summaryrefslogtreecommitdiff
path: root/src/Network/BitTorrent
diff options
context:
space:
mode:
Diffstat (limited to 'src/Network/BitTorrent')
-rw-r--r--src/Network/BitTorrent/Exchange.hs47
1 files changed, 43 insertions, 4 deletions
diff --git a/src/Network/BitTorrent/Exchange.hs b/src/Network/BitTorrent/Exchange.hs
index b0a94853..3f3346d2 100644
--- a/src/Network/BitTorrent/Exchange.hs
+++ b/src/Network/BitTorrent/Exchange.hs
@@ -60,6 +60,7 @@ module Network.BitTorrent.Exchange
60 , awaitEvent 60 , awaitEvent
61 , yieldEvent 61 , yieldEvent
62 , handleEvent 62 , handleEvent
63 , exchange
63 64
64 -- * Exceptions 65 -- * Exceptions
65 , disconnect 66 , disconnect
@@ -85,16 +86,14 @@ import Data.Conduit.Network
85import Data.Serialize as S 86import Data.Serialize as S
86import Text.PrettyPrint as PP hiding (($$)) 87import Text.PrettyPrint as PP hiding (($$))
87 88
88
89import Network 89import Network
90 90
91 91import Data.Bitfield as BF
92import Network.BitTorrent.Internal 92import Network.BitTorrent.Internal
93import Network.BitTorrent.Extension 93import Network.BitTorrent.Extension
94import Network.BitTorrent.Peer 94import Network.BitTorrent.Peer
95import Network.BitTorrent.Exchange.Protocol 95import Network.BitTorrent.Exchange.Protocol
96import Data.Bitfield as BF 96import System.Torrent.Storage
97
98 97
99{----------------------------------------------------------------------- 98{-----------------------------------------------------------------------
100 Peer wire 99 Peer wire
@@ -464,3 +463,43 @@ yieldEvent e = {-# SCC yieldEvent #-} go e
464 463
465handleEvent :: (Event -> P2P Event) -> P2P () 464handleEvent :: (Event -> P2P Event) -> P2P ()
466handleEvent action = awaitEvent >>= action >>= yieldEvent 465handleEvent action = awaitEvent >>= action >>= yieldEvent
466
467-- Event translation table looks like:
468--
469-- Available -> Want
470-- Want -> Fragment
471-- Fragment -> Available
472--
473-- If we join the chain we get the event loop:
474--
475-- Available -> Want -> Fragment --\
476-- /|\ |
477-- \---------------------------/
478--
479
480
481-- | Default P2P action.
482exchange :: Storage -> P2P ()
483exchange storage = {-# SCC exchange #-} (awaitEvent >>= handler)
484 where
485 handler (Available bf) = do
486 liftIO (print (completeness bf))
487 ixs <- selBlk (findMin bf) storage
488 mapM_ (yieldEvent . Want) ixs -- TODO yield vectored
489
490 handler (Want bix) = do
491 blk <- liftIO $ getBlk bix storage
492 yieldEvent (Fragment blk)
493
494 handler (Fragment blk @ Block {..}) = do
495 liftIO $ print (ppBlock blk)
496 done <- liftIO $ putBlk blk storage
497 when done $ do
498 yieldEvent $ Available $ singleton blkPiece (succ blkPiece)
499
500 -- WARN this is not reliable: if peer do not return all piece
501 -- block we could slow don't until some other event occured
502 offer <- peerOffer
503 if BF.null offer
504 then return ()
505 else handler (Available offer)