packages feed

chan 0.0.4 → 0.0.4.1

raw patch · 4 files changed

+31/−18 lines, 4 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

README.md view
@@ -1,17 +1,21 @@+ # chan  This is just some extra `Chan` and `TChan` kit that might help the average user. It relies on spawning threads with `async` and either canceling (debouncing) or waiting (throttling) messages. -Unfortunately, the current design is untyped in the sense that the channel which you supply is the+Unfortunately, the current design is slightly untyped in the sense that the channel which you supply is the _output_ channel, and the returned channel is the one you would write to. I'm not sure how this should-be fixed.+be fixed. There's a series of "typed" alternatives to each underlying channel type, that allows users to+restrict them to "read-only", "write-only", or "Writable a => ..." etc.  An example might be the following:  ```haskell import Control.Concurrent.Chan (readChan)-import Control.Concurrent.Chan.Extra (throttleStatic, intersperseStatic)+import Control.Concurrent.Chan.Scope (Scope (..))+import Control.Concurrent.Chan.Typed (ChanRW)+import Control.Concurrent.Chan.Extra (allowReading, throttleStatic, intersperseStatic)   @@ -19,23 +23,26 @@  data SomeMessage   = Ping+  | Foo   -- | ... -throttleLayer :: Chan SomeMessage -> IO (Chan SomeMessage)+throttleLayer :: ChanRW 'Read SomeMessage -> IO (ChanRW 'Write SomeMessage) throttleLayer output = do   (x,_) <- throttleStatic output 1000000 -- nanoseconds, = 1 second   pure x -pingLayer :: Chan SomeMessage -> IO (Chan SomeMessage)+pingLayer :: ChanRW 'Read SomeMessage -> IO (ChanRW 'Write SomeMessage) pingLayer output = do   (x,_,_) <- intersperseStatic output (pure Ping) 1000000   pure x -performWebsocket :: Chan SomeMessage -> IO ()+performWebsocket :: ChanRW 'Read SomeMessage -> IO () performWebsocket output = do-  output' <- pingLayer =<< throttleLayer output-  _ <- async $ forever $ do-    msg <- readChan output'+  sendable <- pingLayer . allowReading =<< throttleLayer output+  emittingThread <- async $ forever $ do+    -- the thread that actually facilitates the sending of messages queued in the chans+    msg <- readChanRW output     send msg -- something like that - it'll include Ping messages for us,              -- and throttle the outgoing messages at the same time.+  writeChanRW sendable Foo ```
chan.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 9429247fea789bb683e6f4ed7fb173854b095d3e98824b896891eb68655e73a8+-- hash: ccb631c185767be2ee9b87d1fdc3c68a599868947989a396f06221b2c06a9b22  name:           chan-version:        0.0.4+version:        0.0.4.1 synopsis:       Some extra kit for Chans description:    Please see the README on Github at <https://github.com/athanclark/chan#readme> category:       Concurrency
src/Control/Concurrent/Chan/Extra.hs view
@@ -16,11 +16,10 @@   ( TChanRW (..), writeTChanRW, readTChanRW, newTChanRW) import Control.Concurrent.Chan.Scope (Scope (..), Writable, Readable) -import Data.IORef (newIORef, readIORef, writeIORef) import Control.Monad (forever) import Control.Concurrent (threadDelay) import Control.Concurrent.MVar (newEmptyMVar, tryTakeMVar, putMVar)-import Control.Concurrent.Chan (Chan, readChan, writeChan, newChan)+import Control.Concurrent.Chan (Chan) import Control.Concurrent.Async (Async, async, cancel, wait) import Control.Concurrent.STM   (atomically, tryTakeTMVar, putTMVar, newEmptyTMVarIO)
test/Spec.hs view
@@ -1,15 +1,15 @@ import Control.Monad (forever) import Control.Concurrent (threadDelay) import Control.Concurrent.Chan (newChan, writeChan, readChan)-import Control.Concurrent.Chan.Extra (debounceStatic, throttleStatic, intersperseStatic)+import Control.Concurrent.Chan.Extra (ChanExtra (debounceStatic, throttleStatic, intersperseStatic)) import Control.Concurrent.Async (async) import Control.Concurrent.MVar (newEmptyMVar, putMVar, takeMVar) import Control.Concurrent.STM (atomically) import Control.Concurrent.STM.TChan (newTChan, writeTChan, readTChan)-import qualified Control.Concurrent.STM.TChan.Extra as TChan import Control.Concurrent.STM.TMVar (newEmptyTMVar, putTMVar, takeTMVar)  +chanDebounceTest :: IO () chanDebounceTest = do   putStrLn "Debounce ---------"   outgoing <- newChan@@ -35,6 +35,7 @@    pure () +chanThrottleTest :: IO () chanThrottleTest = do   putStrLn "Throttle ---------"   outgoing <- newChan@@ -60,6 +61,7 @@    pure () +chanIntersperseTest :: IO () chanIntersperseTest = do   putStrLn "Intersperse ---------"   outgoing <- newChan@@ -84,15 +86,17 @@   pure ()  +chanTests :: IO () chanTests = do   chanDebounceTest   chanThrottleTest   chanIntersperseTest +tchanDebounceTests :: IO () tchanDebounceTests = do   putStrLn "Debounce STM ---------"   outgoing <- atomically newTChan-  (incoming, _) <- TChan.debounceStatic 1000000 outgoing+  (incoming, _) <- debounceStatic 1000000 outgoing    lock <- atomically newEmptyTMVar @@ -114,10 +118,11 @@    pure () +tchanThrottleTests :: IO () tchanThrottleTests = do   putStrLn "Throttle STM ---------"   outgoing <- atomically newTChan-  (incoming, _) <- TChan.throttleStatic 1000000 outgoing+  (incoming, _) <- throttleStatic 1000000 outgoing    lock <- atomically newTChan @@ -140,10 +145,11 @@   pure ()  +tchanIntersperseTests :: IO () tchanIntersperseTests = do   putStrLn "Intersperse STM ---------"   outgoing <- atomically newTChan-  (incoming, _, _) <- TChan.intersperseStatic 1000000 (pure 0) outgoing+  (incoming, _, _) <- intersperseStatic 1000000 (pure 0) outgoing    lock <- atomically newEmptyTMVar @@ -164,6 +170,7 @@   pure ()  +tchanTests :: IO () tchanTests = do   tchanDebounceTests   tchanThrottleTests