summaryrefslogtreecommitdiff
path: root/xmppServer.hs
diff options
context:
space:
mode:
authorjoe <joe@jerkface.net>2014-02-13 17:57:23 -0500
committerjoe <joe@jerkface.net>2014-02-13 17:57:23 -0500
commite8358efbdee377fe98e6d50c518d2a9072a3ce6e (patch)
tree33d27316700cb672115afe0bae37ad8eb59bc43e /xmppServer.hs
parente3ff0df9fbdf28dfa5659a8392d89fa66c38a8df (diff)
ConnectWithEndlessRetry
Diffstat (limited to 'xmppServer.hs')
-rw-r--r--xmppServer.hs102
1 files changed, 30 insertions, 72 deletions
diff --git a/xmppServer.hs b/xmppServer.hs
index 4fbb775b..987e7dbc 100644
--- a/xmppServer.hs
+++ b/xmppServer.hs
@@ -27,14 +27,12 @@ import Data.Maybe (catMaybes,fromJust)
27import Data.Monoid ( (<>) ) 27import Data.Monoid ( (<>) )
28import Data.Text (Text) 28import Data.Text (Text)
29import qualified Data.Text as Text (pack) 29import qualified Data.Text as Text (pack)
30import qualified Data.Map as Map
31 30
32import qualified Control.Concurrent.STM.UpdateStream as Slotted 31import qualified Control.Concurrent.STM.UpdateStream as Slotted
33import ControlMaybe 32import ControlMaybe
34import Nesting 33import Nesting
35import EventUtil 34import EventUtil
36import Server 35import Server
37import Data.Time.Clock (UTCTime,getCurrentTime)
38 36
39addrToText :: SockAddr -> Text 37addrToText :: SockAddr -> Text
40addrToText (addr@(SockAddrInet _ _)) = Text.pack $ stripColon (show addr) 38addrToText (addr@(SockAddrInet _ _)) = Text.pack $ stripColon (show addr)
@@ -288,66 +286,49 @@ forkConnection k pingflag src snk stanzas = do
288 wlog $ "end reader fork: " ++ show k 286 wlog $ "end reader fork: " ++ show k
289 return output 287 return output
290 288
289data ConnectionKey
290 = PeerKey { callBackAddress :: SockAddr }
291 | ClientKey { localAddress :: SockAddr }
292 deriving (Show, Ord, Eq)
293
294{-
295data Peer = Peer
296 { peerWanted :: TVar Bool -- ^ False when this peer is on a you-call-me basis
297 , peerState :: TVar PeerState
298 }
299data PeerState
300 = PeerPendingConnect UTCTime
301 | PeerPendingAccept UTCTime
302 | PeerConnected (TChan Stanza)
303-}
304
305peerKey (sock,addr) = do
306 peer <-
307 sIsConnected sock >>= \c ->
308 if c then getPeerName sock -- addr is normally socketName
309 else return addr -- Weird hack: addr is would-be peer name
310 return $ PeerKey (peer `withPort` fromIntegral peerport)
311
312clientKey (sock,addr) = return $ ClientKey addr
313
291monitor sv params = do 314monitor sv params = do
292 chan <- return $ serverEvent sv 315 chan <- return $ serverEvent sv
293 stanzas <- atomically newTChan 316 stanzas <- atomically newTChan
294 peersVar <- atomically $ newTVar Map.empty
295 let doConnect utc k = do
296 peers <- readTVar peersVar
297 let mb = Map.lookup k peers
298 maybe (do false <- newTVar False
299 pending <- newTVar (PeerPendingConnect utc)
300 let v = Peer { peerWanted = false
301 , peerState = pending }
302 writeTVar (peersVar) $ Map.insert k v peers)
303 (\peer ->
304 writeTVar (peerState peer)
305 $ PeerPendingConnect utc)
306 mb
307 fix $ \loop -> do 317 fix $ \loop -> do
308 action <- atomically $ foldr1 orElse 318 action <- atomically $ foldr1 orElse
309 [ readTChan chan >>= \(k,e) -> return $ do 319 [ readTChan chan >>= \(k,e) -> return $ do
310 case e of 320 case e of
311 Connection pingflag conread conwrite -> do 321 Connection pingflag conread conwrite -> do
312 wlog $ tomsg k "Connection" 322 wlog $ tomsg k "Connection"
313 let (xsrc,xsnk) = xmlStream conread conwrite 323 let (xsrc,xsnk) = xmlStream conread conwrite
314 outs <- forkConnection k pingflag xsrc xsnk stanzas 324 forkConnection k pingflag xsrc xsnk stanzas
315 atomically $ do 325 return ()
316 peers <- readTVar peersVar
317 let mb = Map.lookup k peers
318 maybe (do false <- newTVar True -- False -- TODO: should be False
319 connected <- newTVar (PeerConnected outs)
320 let v = Peer { peerWanted = false
321 , peerState = connected }
322 writeTVar (peersVar) $ Map.insert k v peers)
323 (\peer -> do
324 writeTVar (peerWanted peer) True -- TODO REMOVE
325 writeTVar (peerState peer)
326 $ PeerConnected outs)
327 mb
328 return ()
329 ConnectFailure addr -> do 326 ConnectFailure addr -> do
330 wlog $ tomsg k "ConnectFailure" 327 wlog $ tomsg k "ConnectFailure"
331 action <- atomically $ do
332 peers <- readTVar peersVar
333 let mb = Map.lookup k peers
334 maybe (return $ return ())
335 (\peer -> do
336 wanted <- readTVar (peerWanted peer)
337 if wanted then return $ do
338 utc <- getCurrentTime
339 control sv (Connect addr params)
340 wlog $ tomsg k "Retry"
341 atomically $ doConnect utc k
342 else return $ return ())
343 mb
344 action
345 EOF -> wlog $ tomsg k "EOF" 328 EOF -> wlog $ tomsg k "EOF"
346 HalfConnection In -> do 329 HalfConnection In -> do
347 wlog $ tomsg k "ReadOnly" 330 wlog $ tomsg k "ReadOnly"
348 utc <- getCurrentTime
349 control sv (Connect (callBackAddress k) params) 331 control sv (Connect (callBackAddress k) params)
350 atomically $ doConnect utc k
351 HalfConnection Out -> wlog $ tomsg k "WriteOnly" 332 HalfConnection Out -> wlog $ tomsg k "WriteOnly"
352 RequiresPing -> wlog $ tomsg k "RequiresPing" 333 RequiresPing -> wlog $ tomsg k "RequiresPing"
353 _ -> return () 334 _ -> return ()
@@ -363,29 +344,6 @@ monitor sv params = do
363 where 344 where
364 _ = str :: String 345 _ = str :: String
365 346
366data ConnectionKey
367 = PeerKey { callBackAddress :: SockAddr }
368 | ClientKey { localAddress :: SockAddr }
369 deriving (Show, Ord, Eq)
370
371data Peer = Peer
372 { peerWanted :: TVar Bool -- ^ False when this peer is on a you-call-me basis
373 , peerState :: TVar PeerState
374 }
375data PeerState
376 = PeerPendingConnect UTCTime
377 | PeerPendingAccept UTCTime
378 | PeerConnected (TChan Stanza)
379
380peerKey (sock,addr) = do
381 peer <-
382 sIsConnected sock >>= \c ->
383 if c then getPeerName sock -- addr is normally socketName
384 else return addr -- Weird hack: addr is would-be peer name
385 return $ PeerKey (peer `withPort` fromIntegral peerport)
386
387clientKey (sock,addr) = return $ ClientKey addr
388
389 347
390peerport = 5269 348peerport = 5269
391clientport = 5222 349clientport = 5222
@@ -404,7 +362,7 @@ main = runResourceT $ do
404 (Just testaddr0) 362 (Just testaddr0)
405 (Just "5269") 363 (Just "5269")
406 putStrLn $ "Connecting to "++show testaddr 364 putStrLn $ "Connecting to "++show testaddr
407 control sv (Connect testaddr peer_params) 365 control sv (ConnectWithEndlessRetry testaddr peer_params 2000)
408 forkIO $ monitor sv peer_params 366 forkIO $ monitor sv peer_params
409 control sv (Listen peerport peer_params) 367 control sv (Listen peerport peer_params)
410 -- control sv (Listen clientport client_params) 368 -- control sv (Listen clientport client_params)