diff options
-rw-r--r-- | examples/dhtd.hs | 64 |
1 files changed, 52 insertions, 12 deletions
diff --git a/examples/dhtd.hs b/examples/dhtd.hs index 755a65d7..badea2b1 100644 --- a/examples/dhtd.hs +++ b/examples/dhtd.hs | |||
@@ -98,13 +98,21 @@ showColumns rows = do | |||
98 | marshalForClient :: String -> String | 98 | marshalForClient :: String -> String |
99 | marshalForClient s = show (length s) ++ ":" ++ s | 99 | marshalForClient s = show (length s) ++ ":" ++ s |
100 | 100 | ||
101 | data ClientHandle = ClientHandle Handle (MVar Int) | ||
102 | |||
101 | -- | Writes a message and signals ready for next command. | 103 | -- | Writes a message and signals ready for next command. |
102 | hPutClient :: Handle -> String -> IO () | 104 | hPutClient :: ClientHandle -> String -> IO () |
103 | hPutClient h s = hPutStr h ('.' : marshalForClient s) | 105 | hPutClient (ClientHandle h hstate) s = do |
106 | st <- takeMVar hstate | ||
107 | hPutStr h ('.' : marshalForClient s) | ||
108 | putMVar hstate 1 -- ready for input | ||
104 | 109 | ||
105 | -- | Writes message, but signals there is more to come. | 110 | -- | Writes message, but signals there is more to come. |
106 | hPutClientChunk :: Handle -> String -> IO () | 111 | hPutClientChunk :: ClientHandle -> String -> IO () |
107 | hPutClientChunk h s = hPutStr h (' ' : marshalForClient s) | 112 | hPutClientChunk (ClientHandle h hstate) s = do |
113 | st <- takeMVar hstate | ||
114 | hPutStr h (' ' : marshalForClient s) | ||
115 | putMVar hstate 2 -- ready for more output | ||
108 | 116 | ||
109 | data DHTQuery nid ni = forall addr r tok. | 117 | data DHTQuery nid ni = forall addr r tok. |
110 | ( Ord addr | 118 | ( Ord addr |
@@ -253,7 +261,7 @@ reportResult :: | |||
253 | -> (r -> String) | 261 | -> (r -> String) |
254 | -> (tok -> Maybe String) | 262 | -> (tok -> Maybe String) |
255 | -> (ni -> String) | 263 | -> (ni -> String) |
256 | -> Handle | 264 | -> ClientHandle |
257 | -> Either String ([ni],[r],Maybe tok) | 265 | -> Either String ([ni],[r],Maybe tok) |
258 | -> IO () | 266 | -> IO () |
259 | reportResult meth showR showTok showN h (Left e) = hPutClient h e | 267 | reportResult meth showR showTok showN h (Left e) = hPutClient h e |
@@ -334,7 +342,7 @@ forkSearch method nid DHTQuery{qsearch,qshowTok,qshowR} dhtSearches dhtBuckets | |||
334 | writeTVar kvar $ Just $ searchLoop qsearch nid storeResult st | 342 | writeTVar kvar $ Just $ searchLoop qsearch nid storeResult st |
335 | 343 | ||
336 | reportSearchResults :: (Show t, Ord t1, Ord t, Hashable t) => | 344 | reportSearchResults :: (Show t, Ord t1, Ord t, Hashable t) => |
337 | String -> Handle -> DHTSearch t1 t -> IO () | 345 | String -> ClientHandle -> DHTSearch t1 t -> IO () |
338 | reportSearchResults meth h DHTSearch{searchShowTok,searchState,searchResults} = do | 346 | reportSearchResults meth h DHTSearch{searchShowTok,searchState,searchResults} = do |
339 | (ns,rs) <- atomically $ do | 347 | (ns,rs) <- atomically $ do |
340 | mm <- readTVar $ searchInformant searchState | 348 | mm <- readTVar $ searchInformant searchState |
@@ -361,12 +369,39 @@ data Session = Session | |||
361 | , signalQuit :: MVar () | 369 | , signalQuit :: MVar () |
362 | } | 370 | } |
363 | 371 | ||
364 | clientSession :: Session -> t1 -> t -> Handle -> IO () | 372 | exceptionsToClient :: ClientHandle -> IO () -> IO () |
373 | exceptionsToClient (ClientHandle h hstate) action = | ||
374 | action `catch` \(SomeException e) -> do | ||
375 | st <- takeMVar hstate | ||
376 | when (st /= 1) $ do | ||
377 | hPutStr h ('.': marshalForClient (show e)) | ||
378 | putMVar hstate 1 -- ready for input | ||
379 | |||
380 | hGetClientLine :: ClientHandle -> IO String | ||
381 | hGetClientLine (ClientHandle h hstate) = do | ||
382 | st <- takeMVar hstate | ||
383 | -- st should be 1 | ||
384 | x <- hGetLine h | ||
385 | putMVar hstate 0 -- ready for output | ||
386 | return x | ||
387 | |||
388 | hCloseClient :: ClientHandle -> IO () | ||
389 | hCloseClient (ClientHandle h hstate) = do | ||
390 | st <- takeMVar hstate | ||
391 | hClose h | ||
392 | putMVar hstate 3 -- closed file handle | ||
393 | |||
394 | clientSession0 :: Session -> t1 -> t -> Handle -> IO () | ||
395 | clientSession0 s sock cnum h = do | ||
396 | hstate <- newMVar 1 -- ready for input | ||
397 | clientSession s sock cnum (ClientHandle h hstate) | ||
398 | |||
399 | clientSession :: Session -> t1 -> t -> ClientHandle -> IO () | ||
365 | clientSession s@Session{..} sock cnum h = do | 400 | clientSession s@Session{..} sock cnum h = do |
366 | line <- dropWhile isSpace <$> hGetLine h | 401 | line <- dropWhile isSpace <$> hGetClientLine h |
367 | let (c,args) = second (dropWhile isSpace) $ break isSpace line | 402 | let (c,args) = second (dropWhile isSpace) $ break isSpace line |
368 | cmd0 :: IO () -> IO () | 403 | cmd0 :: IO () -> IO () |
369 | cmd0 action = action >> clientSession s sock cnum h | 404 | cmd0 action = exceptionsToClient h action >> clientSession s sock cnum h |
370 | switchNetwork dest = do hPutClient h ("Network: "++dest) | 405 | switchNetwork dest = do hPutClient h ("Network: "++dest) |
371 | clientSession s{netname=dest} sock cnum h | 406 | clientSession s{netname=dest} sock cnum h |
372 | strp = B.unpack . fst . until snd dropEnd . (,False) . B.dropWhile isSpace . B.pack | 407 | strp = B.unpack . fst . until snd dropEnd . (,False) . B.dropWhile isSpace . B.pack |
@@ -401,6 +436,7 @@ clientSession s@Session{..} sock cnum h = do | |||
401 | , ["toxids"] | 436 | , ["toxids"] |
402 | , ["c"] | 437 | , ["c"] |
403 | , ["help"] | 438 | , ["help"] |
439 | , ["throw"] | ||
404 | ] | 440 | ] |
405 | case (map toLower c,args) of | 441 | case (map toLower c,args) of |
406 | (n, _) | n `elem` Map.keys dhts -> switchNetwork n | 442 | (n, _) | n `elem` Map.keys dhts -> switchNetwork n |
@@ -421,10 +457,14 @@ clientSession s@Session{..} sock cnum h = do | |||
421 | hPutClient h $ "error." | 457 | hPutClient h $ "error." |
422 | 458 | ||
423 | ("stop", _) -> do hPutClient h "Terminating DHT Daemon." | 459 | ("stop", _) -> do hPutClient h "Terminating DHT Daemon." |
424 | hClose h | 460 | hCloseClient h |
425 | putMVar signalQuit () | 461 | putMVar signalQuit () |
426 | 462 | ||
427 | ("quit", _) -> hPutClient h "" >> hClose h | 463 | ("throw", er) -> cmd0 $ do |
464 | throwIO $ userError er | ||
465 | hPutClient h "The impossible happened!" | ||
466 | |||
467 | ("quit", _) -> hPutClient h "" >> hCloseClient h | ||
428 | 468 | ||
429 | ("pid", _) -> cmd0 $ do | 469 | ("pid", _) -> cmd0 $ do |
430 | pid <- getProcessID | 470 | pid <- getProcessID |
@@ -1131,7 +1171,7 @@ main = do | |||
1131 | (toxids,rstr) <- fromMaybe ((,) <$> atomically (newTVar []) <*> newRoster) $ do | 1171 | (toxids,rstr) <- fromMaybe ((,) <$> atomically (newTVar []) <*> newRoster) $ do |
1132 | tox <- mbtox | 1172 | tox <- mbtox |
1133 | return $ return ( userKeys (Tox.toxCryptoKeys tox), Tox.toxRoster tox ) | 1173 | return $ return ( userKeys (Tox.toxCryptoKeys tox), Tox.toxRoster tox ) |
1134 | let session = clientSession $ Session | 1174 | let session = clientSession0 $ Session |
1135 | { netname = concat $ take 1 $ Map.keys dhts -- initial default DHT | 1175 | { netname = concat $ take 1 $ Map.keys dhts -- initial default DHT |
1136 | , dhts = dhts -- all DHTs | 1176 | , dhts = dhts -- all DHTs |
1137 | , signalQuit = signalQuit | 1177 | , signalQuit = signalQuit |