@@ -35,16 +35,16 @@ module Streamly.Internal.Network.Inet.TCP
3535 -- * TCP clients
3636 -- | IP Address based operations.
3737 , connect
38− , withServerAddrM
38+ , withConnectionM
3939
4040 -- ** Unfolds
41− , withServerAddr
41+ , usingConnection
4242 , read
4343
4444 -- ** Streams
4545 , withConnection
4646 -- *** Source
47− , toStream
47+ , toBytes
4848 -- , readUtf8
4949 -- , readLines
5050 -- , readFrames
@@ -63,11 +63,14 @@ module Streamly.Internal.Network.Inet.TCP
6363 -- , writeUtf8
6464 -- , writeUtf8ByLines
6565 -- , writeByFrames
66− -- , writeRequestsOf
66+ , writeWithBufferOf
67+ , fromBytes
68+ , fromBytesWithBufferOf
6769
6870 -- -- * Array Write
6971 -- , writeArray
7072 , writeChunks
73+ , fromChunks
7174 {-
7275 -- ** Sink Servers
7376
@@ -109,7 +112,9 @@ import Streamly.Streams.Serial (SerialT)
109112import Streamly.Internal.Memory.Array.Types (Array(..), defaultChunkSize, writeNUnsafe)
110113import Streamly.Streams.StreamK.Type (IsStream)
111114
115+import qualified Control.Monad.Catch as MC
112116import qualified Network.Socket as Net
117+
113118import qualified Streamly.Internal.Data.Unfold as UF
114119import qualified Streamly.Internal.Memory.Array as A
115120import qualified Streamly.Internal.Memory.ArrayStream as AS
@@ -225,16 +230,16 @@ connect addr port = do
225230 return sock
226231
227232-- | 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
229234-- socket is closed on normal termination or in case of an exception. If
230235-- closing the socket raises an exception, then this exception will be raised
231−-- by 'withServerAddrM'.
236+-- by 'withConnectionM'.
232237--
233238-- /Internal/
234−{-# INLINABLE withServerAddrM #-}
235−withServerAddrM :: (MonadMask m, MonadIO m)
239+{-# INLINABLE withConnectionM #-}
240+withConnectionM :: (MonadMask m, MonadIO m)
236241 => (Word8, Word8, Word8, Word8) -> PortNumber -> (Socket -> m ()) -> m ()
237−withServerAddrM addr port =
242+withConnectionM addr port =
238243 bracket (liftIO $ connect addr port) (liftIO . Net.close)
239244
240245-------------------------------------------------------------------------------
@@ -245,14 +250,14 @@ withServerAddrM addr port =
245250-- address and port. The resulting unfold opens a socket, uses it using the
246251-- supplied unfold and then makes sure that the socket is closed on normal
247252-- 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'.
249254--
250255-- /Internal/
251−{-# INLINABLE withServerAddr #-}
252−withServerAddr :: (MonadCatch m, MonadIO m)
256+{-# INLINABLE usingConnection #-}
257+usingConnection :: (MonadCatch m, MonadIO m)
253258 => Unfold m Socket a
254259 -> Unfold m ((Word8, Word8, Word8, Word8), PortNumber) a
255−withServerAddr =
260+usingConnection =
256261 UF.bracket (\(addr, port) -> liftIO $ connect addr port)
257262 (liftIO . Net.close)
258263
@@ -284,35 +289,33 @@ withConnection addr port =
284289{-# INLINE read #-}
285290read :: (MonadCatch m, MonadIO m)
286291 => 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
288293
289294-- | Read a stream from the supplied IPv4 host address and port number.
290295--
291296-- @since 0.7.0
292−{-# INLINE toStream #-}
293−toStream :: (IsStream t, MonadCatch m, MonadIO m)
297+{-# INLINE toBytes #-}
298+toBytes :: (IsStream t, MonadCatch m, MonadIO m)
294299 => (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
296301
297302-------------------------------------------------------------------------------
298303-- Writing
299304-------------------------------------------------------------------------------
300305
301−{-
302306-- | Write a stream of arrays to the supplied IPv4 host address and port
303307-- number.
304308--
305309-- @since 0.7.0
306−{-# INLINE writeChunks #-}
307−writeChunks
310+{-# INLINE fromChunks #-}
311+fromChunks
308312 :: (MonadCatch m, MonadAsync m)
309313 => (Word8, Word8, Word8, Word8)
310314 -> PortNumber
311315 -> SerialT m (Array Word8)
312316 -> m ()
313−writeChunks addr port xs =
314− S.drain $ withConnection addr port (\sk -> S.yieldM $ SK.writeChunks sk xs)
315−-}
317+fromChunks addr port xs =
318+ S.drain $ withConnection addr port (\sk -> S.yieldM $ ISK.fromChunks sk xs)
316319
317320-- | Write a stream of arrays to the supplied IPv4 host address and port
318321-- number.
@@ -320,7 +323,7 @@ writeChunks addr port xs =
320323-- @since 0.7.0
321324{-# INLINE writeChunks #-}
322325writeChunks
323− :: (MonadAsync m)
326+ :: (MonadAsync m, MonadCatch m)
324327 => (Word8, Word8, Word8, Word8)
325328 -> PortNumber
326329 -> Fold m (Array Word8) ()
@@ -328,56 +331,58 @@ writeChunks addr port = Fold step initial extract
328331 where
329332 initial = do
330333 skt <- liftIO (connect addr port)
331− FL.initialize (SK.writeChunks skt)
332− step = FL.runStep
333− extract (Fold _ initial1 extract1) = initial1 >>= extract1
334+ fld <- FL.initialize (SK.writeChunks skt)
335+ `MC.onException` (liftIO $ Net.close skt)
336+ return (fld, skt)
337+ step (fld, skt) x = do
338+ r <- FL.runStep fld x `MC.onException` (liftIO $ Net.close skt)
339+ return (r, skt)
340+ extract ((Fold _ initial1 extract1), skt) = do
341+ liftIO $ Net.close skt
342+ initial1 >>= extract1
334343
335−{-
336344-- | Like 'write' but provides control over the write buffer. Output will
337345-- be written to the IO device as soon as we collect the specified number of
338346-- input elements.
339347--
340348-- @since 0.7.0
341−{-# INLINE writeRequestsOf #-}
342−writeRequestsOf
349+{-# INLINE fromBytesWithBufferOf #-}
350+fromBytesWithBufferOf
343351 :: (MonadCatch m, MonadAsync m)
344352 => Int
345353 -> (Word8, Word8, Word8, Word8)
346354 -> PortNumber
347355 -> SerialT m Word8
348356 -> m ()
349−writeRequestsOf n addr port m = writeChunks addr port $ AS.arraysOf n m
350−-}
357+fromBytesWithBufferOf n addr port m = fromChunks addr port $ AS.arraysOf n m
351358
352359-- | Like 'write' but provides control over the write buffer. Output will
353360-- be written to the IO device as soon as we collect the specified number of
354361-- input elements.
355362--
356363-- @since 0.7.0
357−{-# INLINE writeRequestsOf #-}
358−writeRequestsOf
359− :: (MonadAsync m)
364+{-# INLINE writeWithBufferOf #-}
365+writeWithBufferOf
366+ :: (MonadAsync m, MonadCatch m)
360367 => Int
361368 -> (Word8, Word8, Word8, Word8)
362369 -> PortNumber
363370 -> Fold m Word8 ()
364−writeRequestsOf n addr port =
371+writeWithBufferOf n addr port =
365372 FL.lchunksOf n (writeNUnsafe n) (writeChunks addr port)
366373
367−{-
368374-- | Write a stream to the supplied IPv4 host address and port number.
369375--
370376-- @since 0.7.0
371−{-# INLINE write #-}
372−write :: (MonadCatch m, MonadAsync m)
377+{-# INLINE fromBytes #-}
378+fromBytes :: (MonadCatch m, MonadAsync m)
373379 => (Word8, Word8, Word8, Word8) -> PortNumber -> SerialT m Word8 -> m ()
374−write = writeRequestsOf defaultChunkSize
375−-}
380+fromBytes = fromBytesWithBufferOf defaultChunkSize
376381
377382-- | Write a stream to the supplied IPv4 host address and port number.
378383--
379384-- @since 0.7.0
380385{-# INLINE write #-}
381−write :: MonadAsync m
386+write :: (MonadAsync m, MonadCatch m)
382387 => (Word8, Word8, Word8, Word8) -> PortNumber -> Fold m Word8 ()
383−write = writeRequestsOf defaultChunkSize
388+write = writeWithBufferOf defaultChunkSize