diff options
author | joe <joe@jerkface.net> | 2017-08-29 17:37:38 -0400 |
---|---|---|
committer | joe <joe@jerkface.net> | 2017-08-29 17:37:38 -0400 |
commit | 9d16ca2529a184309cbd50bd3b6bc228b31c5e91 (patch) | |
tree | d4a5b9aba7cbd2123db4e67208cbcb53783245df | |
parent | 5472805a6a8fb3c3d64cbeff5bda1d78a898c602 (diff) |
partitionTransport utility.
-rw-r--r-- | src/Network/QueryResponse.hs | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/Network/QueryResponse.hs b/src/Network/QueryResponse.hs index 11fe7c32..1346174f 100644 --- a/src/Network/QueryResponse.hs +++ b/src/Network/QueryResponse.hs | |||
@@ -69,6 +69,36 @@ layerTransport parse encode tr = | |||
69 | sendMessage tr addr msg | 69 | sendMessage tr addr msg |
70 | } | 70 | } |
71 | 71 | ||
72 | -- | Paritions a 'Transport' into two higher-level transports. Note: An 'MVar' | ||
73 | -- is used to share the same underlying socket, so be sure to fork a thread for | ||
74 | -- both returned 'Transport's to avoid hanging. | ||
75 | partitionTransport :: ((b,a) -> Either (x,xaddr) (y,yaddr)) | ||
76 | -> ((x,xaddr) -> (b,a)) | ||
77 | -> ((y,yaddr) -> (b,a)) | ||
78 | -> Transport err a b | ||
79 | -> IO (Transport err xaddr x, Transport err yaddr y) | ||
80 | partitionTransport parse encodex encodey tr = do | ||
81 | mvar <- newEmptyMVar | ||
82 | let xtr = tr { awaitMessage = \kont -> fix $ \again -> do | ||
83 | awaitMessage tr $ \m -> case m of | ||
84 | Just (Right msg) -> either (kont . Just . Right) | ||
85 | (\y -> putMVar mvar y >> again) | ||
86 | $ parse msg | ||
87 | Just (Left e) -> kont $ Just (Left e) | ||
88 | Nothing -> kont Nothing | ||
89 | , sendMessage = \addr' msg' -> do | ||
90 | let (msg,addr) = encodex (msg',addr') | ||
91 | sendMessage tr addr msg | ||
92 | } | ||
93 | ytr = Transport | ||
94 | { awaitMessage = \kont -> takeMVar mvar >>= kont . Just . Right | ||
95 | , sendMessage = \addr' msg' -> do | ||
96 | let (msg,addr) = encodey (msg',addr') | ||
97 | sendMessage tr addr msg | ||
98 | , closeTransport = return () | ||
99 | } | ||
100 | return (xtr, ytr) | ||
101 | |||
72 | addHandler :: (addr -> x -> IO (Maybe (x -> x))) -> Transport err addr x -> Transport err addr x | 102 | addHandler :: (addr -> x -> IO (Maybe (x -> x))) -> Transport err addr x -> Transport err addr x |
73 | addHandler f tr = tr | 103 | addHandler f tr = tr |
74 | { awaitMessage = \kont -> fix $ \eat -> awaitMessage tr $ \m -> do | 104 | { awaitMessage = \kont -> fix $ \eat -> awaitMessage tr $ \m -> do |