@@ -35,16 +35,16 @@ module Streamly.Internal.Network.Inet.TCP
35 -- * TCP clients
35 -- * TCP clients
36 -- | IP Address based operations.
36 -- | IP Address based operations.
38− , withServerAddrM
38+ , withConnectionM
40 -- ** Unfolds
40 -- ** Unfolds
41− , withServerAddr
41+ , usingConnection
44 -- ** Streams
44 -- ** Streams
45 , withConnection
45 , withConnection
46 -- *** Source
46 -- *** Source
47− , toStream
47+ , toBytes
48 -- , readUtf8
48 -- , readUtf8
49 -- , readLines
49 -- , readLines
50 -- , readFrames
50 -- , readFrames
@@ -63,11 +63,14 @@ module Streamly.Internal.Network.Inet.TCP
63 -- , writeUtf8
63 -- , writeUtf8
64 -- , writeUtf8ByLines
64 -- , writeUtf8ByLines
65 -- , writeByFrames
65 -- , writeByFrames
66− -- , writeRequestsOf
66+ , writeWithBufferOf
68+ , fromBytesWithBufferOf
68 -- -- * Array Write
70 -- -- * Array Write
69 -- , writeArray
71 -- , writeArray
70 , writeChunks
72 , writeChunks
72 -- ** Sink Servers
75 -- ** Sink Servers
@@ -109,7 +112,9 @@ import Streamly.Streams.Serial (SerialT)
109import Streamly.Internal.Memory.Array.Types (Array(..), defaultChunkSize, writeNUnsafe)
112import Streamly.Internal.Memory.Array.Types (Array(..), defaultChunkSize, writeNUnsafe)
110import Streamly.Streams.StreamK.Type (IsStream)
113import Streamly.Streams.StreamK.Type (IsStream)
115+import qualified Control.Monad.Catch as MC
112import qualified Network.Socket as Net
116import qualified Network.Socket as Net
113import qualified Streamly.Internal.Data.Unfold as UF
118import qualified Streamly.Internal.Data.Unfold as UF
114import qualified Streamly.Internal.Memory.Array as A
119import qualified Streamly.Internal.Memory.Array as A
115import qualified Streamly.Internal.Memory.ArrayStream as AS
120import qualified Streamly.Internal.Memory.ArrayStream as AS
@@ -225,16 +230,16 @@ connect addr port = do
225 return sock
230 return sock
227-- | Connect to a remote host using IP address and port and run the supplied
232-- | Connect to a remote host using IP address and port and run the supplied
228−-- action on the resulting socket. 'withServerAddrM' makes sure that the
233+-- action on the resulting socket. 'withConnectionM' makes sure that the
229-- socket is closed on normal termination or in case of an exception. If
234-- socket is closed on normal termination or in case of an exception. If
230-- closing the socket raises an exception, then this exception will be raised
235-- closing the socket raises an exception, then this exception will be raised
231−-- by 'withServerAddrM'.
236+-- by 'withConnectionM'.
233-- /Internal/
238-- /Internal/
234−{-# INLINABLE withServerAddrM #-}
239+{-# INLINABLE withConnectionM #-}
235−withServerAddrM :: (MonadMask m, MonadIO m)
240+withConnectionM :: (MonadMask m, MonadIO m)
236 => (Word8, Word8, Word8, Word8) -> PortNumber -> (Socket -> m ()) -> m ()
241 => (Word8, Word8, Word8, Word8) -> PortNumber -> (Socket -> m ()) -> m ()
237−withServerAddrM addr port =
242+withConnectionM addr port =
238 bracket (liftIO $ connect addr port) (liftIO . Net.close)
243 bracket (liftIO $ connect addr port) (liftIO . Net.close)
240-------------------------------------------------------------------------------
245-------------------------------------------------------------------------------
@@ -245,14 +250,14 @@ withServerAddrM addr port =
245-- address and port. The resulting unfold opens a socket, uses it using the
250-- address and port. The resulting unfold opens a socket, uses it using the
246-- supplied unfold and then makes sure that the socket is closed on normal
251-- supplied unfold and then makes sure that the socket is closed on normal
247-- termination or in case of an exception. If closing the socket raises an
252-- termination or in case of an exception. If closing the socket raises an
248−-- exception, then this exception will be raised by 'withServerAddr'.
253+-- exception, then this exception will be raised by 'usingConnection'.
250-- /Internal/
255-- /Internal/
251−{-# INLINABLE withServerAddr #-}
256+{-# INLINABLE usingConnection #-}
252−withServerAddr :: (MonadCatch m, MonadIO m)
257+usingConnection :: (MonadCatch m, MonadIO m)
253 => Unfold m Socket a
258 => Unfold m Socket a
254 -> Unfold m ((Word8, Word8, Word8, Word8), PortNumber) a
259 -> Unfold m ((Word8, Word8, Word8, Word8), PortNumber) a
255−withServerAddr =
260+usingConnection =
256 UF.bracket (\(addr, port) -> liftIO $ connect addr port)
261 UF.bracket (\(addr, port) -> liftIO $ connect addr port)
257 (liftIO . Net.close)
262 (liftIO . Net.close)
@@ -284,35 +289,33 @@ withConnection addr port =
284{-# INLINE read #-}
289{-# INLINE read #-}
285read :: (MonadCatch m, MonadIO m)
290read :: (MonadCatch m, MonadIO m)
286 => Unfold m ((Word8, Word8, Word8, Word8), PortNumber) Word8
291 => Unfold m ((Word8, Word8, Word8, Word8), PortNumber) Word8
287−read = UF.concat (withServerAddr ISK.readChunks) A.read
292+read = UF.concat (usingConnection ISK.readChunks) A.read
289-- | Read a stream from the supplied IPv4 host address and port number.
294-- | Read a stream from the supplied IPv4 host address and port number.
291-- @since 0.7.0
296-- @since 0.7.0
292−{-# INLINE toStream #-}
297+{-# INLINE toBytes #-}
293−toStream :: (IsStream t, MonadCatch m, MonadIO m)
298+toBytes :: (IsStream t, MonadCatch m, MonadIO m)
294 => (Word8, Word8, Word8, Word8) -> PortNumber -> t m Word8
299 => (Word8, Word8, Word8, Word8) -> PortNumber -> t m Word8
295−toStream addr port = AS.concat $ withConnection addr port ISK.toChunks
300+toBytes addr port = AS.concat $ withConnection addr port ISK.toChunks
297-------------------------------------------------------------------------------
302-------------------------------------------------------------------------------
298-- Writing
303-- Writing
299-------------------------------------------------------------------------------
304-------------------------------------------------------------------------------
302-- | Write a stream of arrays to the supplied IPv4 host address and port
306-- | Write a stream of arrays to the supplied IPv4 host address and port
303-- number.
307-- number.
305-- @since 0.7.0
309-- @since 0.7.0
306−{-# INLINE writeChunks #-}
310+{-# INLINE fromChunks #-}
307−writeChunks
311+fromChunks
308 :: (MonadCatch m, MonadAsync m)
312 :: (MonadCatch m, MonadAsync m)
309 => (Word8, Word8, Word8, Word8)
313 => (Word8, Word8, Word8, Word8)
310 -> PortNumber
314 -> PortNumber
311 -> SerialT m (Array Word8)
315 -> SerialT m (Array Word8)
313−writeChunks addr port xs =
317+fromChunks addr port xs =
314− S.drain $ withConnection addr port (\sk -> S.yieldM $ SK.writeChunks sk xs)
318+ S.drain $ withConnection addr port (\sk -> S.yieldM $ ISK.fromChunks sk xs)
317-- | Write a stream of arrays to the supplied IPv4 host address and port
320-- | Write a stream of arrays to the supplied IPv4 host address and port
318-- number.
321-- number.
@@ -320,7 +323,7 @@ writeChunks addr port xs =
320-- @since 0.7.0
323-- @since 0.7.0
321{-# INLINE writeChunks #-}
324{-# INLINE writeChunks #-}
322writeChunks
325writeChunks
323− :: (MonadAsync m)
326+ :: (MonadAsync m, MonadCatch m)
324 => (Word8, Word8, Word8, Word8)
327 => (Word8, Word8, Word8, Word8)
325 -> PortNumber
328 -> PortNumber
326 -> Fold m (Array Word8) ()
329 -> Fold m (Array Word8) ()
@@ -328,56 +331,58 @@ writeChunks addr port = Fold step initial extract
329 initial = do
332 initial = do
330 skt <- liftIO (connect addr port)
333 skt <- liftIO (connect addr port)
331− FL.initialize (SK.writeChunks skt)
334+ fld <- FL.initialize (SK.writeChunks skt)
332− step = FL.runStep
335+ `MC.onException` (liftIO $ Net.close skt)
337+ step (fld, skt) x = do
338+ r <- FL.runStep fld x `MC.onException` (liftIO $ Net.close skt)
333− extract (Fold _ initial1 extract1) = initial1 >>= extract1
340+ extract ((Fold _ initial1 extract1), skt) = do
341+ liftIO $ Net.close skt
342+ initial1 >>= extract1
336-- | Like 'write' but provides control over the write buffer. Output will
344-- | Like 'write' but provides control over the write buffer. Output will
337-- be written to the IO device as soon as we collect the specified number of
345-- be written to the IO device as soon as we collect the specified number of
338-- input elements.
346-- input elements.
340-- @since 0.7.0
348-- @since 0.7.0
341−{-# INLINE writeRequestsOf #-}
349+{-# INLINE fromBytesWithBufferOf #-}
342−writeRequestsOf
350+fromBytesWithBufferOf
343 :: (MonadCatch m, MonadAsync m)
351 :: (MonadCatch m, MonadAsync m)
345 -> (Word8, Word8, Word8, Word8)
353 -> (Word8, Word8, Word8, Word8)
346 -> PortNumber
354 -> PortNumber
347 -> SerialT m Word8
355 -> SerialT m Word8
349−writeRequestsOf n addr port m = writeChunks addr port $ AS.arraysOf n m
357+fromBytesWithBufferOf n addr port m = fromChunks addr port $ AS.arraysOf n m
352-- | Like 'write' but provides control over the write buffer. Output will
359-- | Like 'write' but provides control over the write buffer. Output will
353-- be written to the IO device as soon as we collect the specified number of
360-- be written to the IO device as soon as we collect the specified number of
354-- input elements.
361-- input elements.
356-- @since 0.7.0
363-- @since 0.7.0
357−{-# INLINE writeRequestsOf #-}
364+{-# INLINE writeWithBufferOf #-}
358−writeRequestsOf
365+writeWithBufferOf
359− :: (MonadAsync m)
366+ :: (MonadAsync m, MonadCatch m)
361 -> (Word8, Word8, Word8, Word8)
368 -> (Word8, Word8, Word8, Word8)
362 -> PortNumber
369 -> PortNumber
363 -> Fold m Word8 ()
370 -> Fold m Word8 ()
364−writeRequestsOf n addr port =
371+writeWithBufferOf n addr port =
365 FL.lchunksOf n (writeNUnsafe n) (writeChunks addr port)
372 FL.lchunksOf n (writeNUnsafe n) (writeChunks addr port)
368-- | Write a stream to the supplied IPv4 host address and port number.
374-- | Write a stream to the supplied IPv4 host address and port number.
370-- @since 0.7.0
376-- @since 0.7.0
371−{-# INLINE write #-}
377+{-# INLINE fromBytes #-}
372−write :: (MonadCatch m, MonadAsync m)
378+fromBytes :: (MonadCatch m, MonadAsync m)
373 => (Word8, Word8, Word8, Word8) -> PortNumber -> SerialT m Word8 -> m ()
379 => (Word8, Word8, Word8, Word8) -> PortNumber -> SerialT m Word8 -> m ()
374−write = writeRequestsOf defaultChunkSize
380+fromBytes = fromBytesWithBufferOf defaultChunkSize
377-- | Write a stream to the supplied IPv4 host address and port number.
382-- | Write a stream to the supplied IPv4 host address and port number.
379-- @since 0.7.0
384-- @since 0.7.0
380{-# INLINE write #-}
385{-# INLINE write #-}
381−write :: MonadAsync m
386+write :: (MonadAsync m, MonadCatch m)
382 => (Word8, Word8, Word8, Word8) -> PortNumber -> Fold m Word8 ()
387 => (Word8, Word8, Word8, Word8) -> PortNumber -> Fold m Word8 ()
383−write = writeRequestsOf defaultChunkSize
388+write = writeWithBufferOf defaultChunkSize