packages feed

chan (empty) → 0.0.0

raw patch · 6 files changed

+228/−0 lines, 6 filesdep +asyncdep +basedep +chansetup-changed

Dependencies added: async, base, chan

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Author name here (c) 2017++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Author name here nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,1 @@+# chan
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ chan.cabal view
@@ -0,0 +1,36 @@+name:                chan+version:             0.0.0+synopsis:            Some extra kit for Chans+-- description:+homepage:            https://github.com/athanclark/chan#readme+license:             BSD3+license-file:        LICENSE+author:              Athan Clark+maintainer:          athan.clark@gmail.com+copyright:           2017 Athan Clark+category:            Web+build-type:          Simple+extra-source-files:  README.md+cabal-version:       >=1.10++library+  hs-source-dirs:      src+  exposed-modules:     Control.Concurrent.Chan.Extra+  build-depends:       base >= 4.7 && < 5+                     , async+                     -- , since+  default-language:    Haskell2010++test-suite chan-test+  type:                exitcode-stdio-1.0+  hs-source-dirs:      test+  main-is:             Spec.hs+  build-depends:       base+                     , chan+                     , async+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/athanclark/chan
+ src/Control/Concurrent/Chan/Extra.hs view
@@ -0,0 +1,106 @@+module Control.Concurrent.Chan.Extra where++import Data.IORef (newIORef, readIORef, writeIORef)+-- import Data.Time.Since (timeSince, newTimeSince)+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.Async (Async, async, cancel, wait)++++type DiffNanosec = Int++-- type TotalNanosec = Int+++-- debounceDynamic :: (NominalDiffTime -> NominalDiffTime) -> Chan a -> IO (Chan a, Async ())+-- debounceDynamic toWait outputChan = do+--   sinceRef <- newTimeSince+--   totalWaited <- newIORef 0+--   presentedChan <- newChan+--   writingThread <- newEmptyMVar++--   let invokeWrite x = do+--         putStrLn "Being run.."++--         waited <- readIORef totalWaited+--         let toWaitFurther = toWait waited+--         writeIORef totalWaited (waited + toWaitFurther)++--         -- FIXME must use clocktime - overlayed invocations have+--         -- no concept of time spent, only have knoweldge of invocations+--         -- made++--         threadDelay toWaitFurther+--         putStrLn "waited done"+--         writeChan outputChan x++--   writer <- async $ forever $ do+--     x <- readChan presentedChan++--     newWriter <- async (invokeWrite x)++--     mInvoker <- tryTakeMVar writingThread+--     case mInvoker of+--       Nothing -> pure ()+--       Just i -> cancel i+--     print "killed"+--     putMVar writingThread newWriter++--   pure (presentedChan, writer)++debounceStatic :: DiffNanosec -> Chan a -> IO (Chan a, Async ())+debounceStatic toWaitFurther outputChan = do+  presentedChan <- newChan+  writingThread <- newEmptyMVar++  let invokeWrite x = do+        threadDelay toWaitFurther+        writeChan outputChan x++  writer <- async $ forever $ do+    x <- readChan presentedChan++    newWriter <- async (invokeWrite x)++    mInvoker <- tryTakeMVar writingThread+    case mInvoker of+      Nothing -> pure ()+      Just i -> cancel i+    putMVar writingThread newWriter++  pure (presentedChan, writer)++++intersperseStatic :: DiffNanosec -> IO a -> Chan a -> IO (Chan a, Async (), Async ())+intersperseStatic timeBetween xM outputChan = do+  presentedChan <- newChan+  writingThread <- newEmptyMVar++  let invokeWritePing = do+        threadDelay timeBetween+        x <- xM+        writeChan outputChan x++  writer <- async $ forever $ do+    mInvoker <- tryTakeMVar writingThread+    case mInvoker of+      Nothing -> pure ()+      Just i -> wait i+    newWriter <- async invokeWritePing+    putMVar writingThread newWriter++  listener <- async $ forever $ do+    y <- readChan presentedChan++    mInvoker <- tryTakeMVar writingThread+    case mInvoker of+      Nothing -> pure ()+      Just i -> cancel i++    writeChan outputChan y++  pure (presentedChan, writer, listener)
+ test/Spec.hs view
@@ -0,0 +1,53 @@+import Control.Monad (forever)+import Control.Concurrent (threadDelay)+import Control.Concurrent.Chan (newChan, writeChan, readChan)+import Control.Concurrent.Chan.Extra (debounceStatic, intersperseStatic)+import Control.Concurrent.Async (async)+import Control.Concurrent.MVar (newEmptyMVar, putMVar, takeMVar)++main :: IO ()+main = do++  outgoing <- newChan+  (incoming, _) <- debounceStatic 1000000 outgoing++  lock <- newEmptyMVar++  _ <- async $ forever $ do+    x <- readChan outgoing+    print x+    putMVar lock ()++  putStrLn "writing 1..."+  writeChan incoming 1++  _ <- takeMVar lock++  putStrLn "writing 2..."+  writeChan incoming 1+  writeChan incoming 2++  _ <- takeMVar lock++++  outgoing <- newChan+  (incoming, _, _) <- intersperseStatic 1000000 (pure 0) outgoing++  lock <- newEmptyMVar++  _ <- async $ forever $ do+    x <- readChan outgoing+    print x+    putMVar lock ()++  threadDelay 3000000++  putStrLn "Writing 1..."+  writeChan incoming 1+  _ <- takeMVar lock+  putStrLn "writing 2..."+  writeChan incoming 2+  _ <- takeMVar lock++  pure ()