Giter VIP home page Giter VIP logo

purescript-avar's Introduction

AVar

CI Release Pursuit Maintainer: garyb

Low-level interface for asynchronous variables.

Installation

Install avar with Spago:

spago install avar

Quick start

The quick start hasn't been written yet (contributions are welcome!). The quick start covers a common, minimal use case for the library, whereas longer examples and tutorials are kept in the docs directory.

Documentation

avar documentation is stored in a few places:

  1. Module documentation is published on Pursuit.
  2. Usage examples can be found in the test suite.

If you get stuck, there are several ways to get help:

Contributing

You can contribute to avar in several ways:

  1. If you encounter a problem or have a question, please open an issue. We'll do our best to work with you to resolve or answer it.

  2. If you would like to contribute code, tests, or documentation, please read the contributor guide. It's a short, helpful introduction to contributing to this library, including development instructions.

  3. If you have written a library, tutorial, guide, or other resource based on this package, please share it on the PureScript Discourse! Writing libraries and learning resources are a great way to help this library succeed.

purescript-avar's People

Contributors

garyb avatar jordanmartinez avatar kl0tl avatar natefaubion avatar rgrover avatar thomashoneyman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

purescript-avar's Issues

`takeVar` does not block

Hey, I am trying to understand how the avar semantics have changed from v3.
I expected this test to hang forever, but it just returns:

main :: Eff _ Unit
main = run' (defaultConfig { timeout = Nothing }) [consoleReporter] do
  describe "avars" do
    it "should block" do
      x <- makeEmptyVar
      takeVar x

The same occurs also for:

main :: Eff _ Unit
main = void $ launchAff do
  x <- makeEmptyVar
  takeVar x

Is that the intended behavior?

Windowing operations

Something like this was requested in #7, and I think it could be supported fairly easily, and would likely simplify implementations of purescript-concurrent-queues since all the queue machinery exists in AVar anyway.

data Operation
  = Ignore -- Do nothing with the queue
  | Fail Error -- Propagate an exception to the callback
  | Halt Error -- Kill the internal queue and propagate the exception
  | PushHead -- Push callback onto the head
  | PushTail -- Push callback onto the tail
  | DropHead Error -- Drop the head, and push onto the tail
  | DropTail Error -- Drop the tail, and push onto the head
  | SwapHead Error -- Replace the head
  | SwapTail Error -- Replace the tail

windowPut :: forall a b. (Int -> Operation) -> a -> AVar a -> AVarCallback Unit -> Effect (Effect Unit)

This would have variations for windowTake, tryWindowPut. tryWindowTake isn't necessary. It would be straightforward to implement queue strategies on top, which could be bundled up as newtypes in a separate library.

putMax :: forall a. Int -> Error -> a -> AVar a -> AVarCallback Unit -> Effect (Effect Unit)
putMax max err = windowPut go
  where
  go n
    | n < max = PushTail
    | otherwise = Fail err

putSliding :: forall a. Int -> Error -> a -> AVar a -> AVarCallback Unit -> Effect (EFfect Unit)
putSliding max err = windowPut go
  where
  go n
    | n < max = PushTail
    | otherwise = DropHead err

/cc @felixSchl @kritzcreek

Limiting size of internal queue

I am porting pipes-concurrency to purescript and am looking for a suitable way to implement the buffering of values.

I need to implement:

data Buffer a
  = Unbounded   -- this is what AVar currently does
  | Bounded Int -- ?
  | Latest a    -- ?
  | Newest Int  -- ?

Do you think this project is the right candidate to implement Newest Int and Bounded Int on top of?

Can't find variable: EMPTY

I'm not sure if this issue should go into purescript-aff or this repo, but when I use purescript-aff#4.0.0 and use the makeVar function, the Control.Monad.Eff.AVar module is missing the EMPTY variable in the compiled JavaScript. I think these steps can reproduce the issue. Here's a sample module...

module Test.Main where

import Prelude

import Control.Monad.Aff (message, runAff_)
import Control.Monad.Aff.AVar (makeEmptyVar, makeVar)
import Control.Monad.Eff.Console (log)
import Control.Monad.Eff.Exception (stack)
import Data.Either (Either(..))

main = runAff_ (case _ of
    Left err -> do
      log $ "ERROR: " <> message err
      log $ show (stack err)
    Right r -> log "OK"
  ) $ do
    a <- makeVar "s"
    pure unit

If you compile using pulp build --main Test.Main --to test.js, the resulting test.js has this compiled Control.Monad.Eff.AVar module.

(function(exports) {
  /* globals exports, setTimeout */
  /* jshint -W097 */
  "use strict";

  // ...

  function drainVar (util, avar) {

    // ...

    if (value === EMPTY && (p = takeHead(ps))) {
      avar.value = value = p.value;
    }
  }
  // ...
})(PS["Control.Monad.Eff.AVar"] = PS["Control.Monad.Eff.AVar"] || {});

However, if I substitute makeEmptyVar for makeVar, then I get this output...

(function(exports) {
  /* globals exports, setTimeout */
  /* jshint -W097 */

  "use strict";

  var EMPTY = {};
  // ...

I'm using compile 0.11.6.

Repo is missing a quick start section

Is your change request related to a problem? Please describe.
As described in the documentation section of the Library Guidelines, Contributors libraries are expected to have in their README a short summary of the library's purpose, installation instructions, a quick start with a minimal usage example, and links to the documentation and contributing guide.

This library currently doesn't have a completed quick start in the README.

Describe the solution you'd like
The library needs a quick start section after the installation instructions. argonaut-codecs is one example of a library with a quick start.

Additional context
See the Governance repository for more information about requirements in the Contributors organization.

Feature Request: replace

replace :: forall a. a -> AVar a -> Effect Unit
replace x v = tryTake v *> tryPut x v $> unit

add Cap like in Bus

I have a module which looks like this:

module Control.Monad.Aff.AVar.RW
  ( module Control.Monad.Eff.AVar
  , AVar
  , Cap
  , AVarR
  , AVarR'
  , AVarW
  , AVarW'
  , AVarRW
  , split
  , makeVar
  , makeEmptyVar
  , status
  , isEmptyVar
  , isFilledVar
  , isKilledVar
  , takeVar
  , tryTakeVar
  , putVar
  , tryPutVar
  , readVar
  , tryReadVar
  , killVar
  ) where

import Prelude

import Control.Monad.Aff.AVar (takeVar, putVar, readVar) as AffAvar
import Control.Monad.Aff.Class (class MonadAff, liftAff)
import Control.Monad.Eff.AVar (AVAR, AVarStatus(..), isEmpty, isFilled, isKilled)
import Control.Monad.Eff.AVar as AVar
import Control.Monad.Eff.Class (class MonadEff, liftEff)
import Control.Monad.Eff.Exception (Error)
import Data.Maybe (Maybe)
import Data.Tuple (Tuple(..))

data Cap

data AVar (r ∷ # Type) a = AVar (AVar.AVar a)
type AVarR = AVarR' ()
type AVarR' r = AVar (readCap | r)
type AVarW = AVarW' ()
type AVarW' r = AVar (writeCap | r)
type AVarRW = AVar (readCap, writeCap)

split  forall a. AVarRW a -> Tuple (AVarR a) (AVarW a)
makeVar  forall m eff a. MonadEff (avar  AVAR | eff) m => a -> m (AVarRW a)
makeEmptyVar  forall m eff a. MonadEff (avar  AVAR | eff) m => m (AVarRW a)
status  forall m eff a r. MonadEff (avar  AVAR | eff) m => AVarR' r a -> m (AVar.AVarStatus a)
isEmptyVar  forall m eff a r. MonadEff (avar  AVAR | eff) m => AVarR' r a -> m Boolean
isFilledVar  forall m eff a r. MonadEff (avar  AVAR | eff) m => AVarR' r a -> m Boolean
isKilledVar  forall m eff a r. MonadEff (avar  AVAR | eff) m => AVarR' r a -> m Boolean
takeVar  forall m eff a. MonadAff (avar  AVAR | eff) m => AVarRW a -> m a
tryTakeVar  forall m eff a. MonadEff (avar  AVAR | eff) m => AVarRW a -> m (Maybe a)
putVar  forall m eff a r. MonadAff (avar  AVAR | eff) m => a -> AVarW' r a -> m Unit
tryPutVar  forall m eff a r. MonadEff (avar  AVAR | eff) m => a -> AVarW' r a -> m Boolean
readVar  forall m eff a r. MonadAff (avar  AVAR | eff) m => AVarR' r a -> m a
tryReadVar  forall m eff a r. MonadEff (avar  AVAR | eff) m => AVarR' r a -> m (Maybe a)
killVar  forall m eff a r. MonadEff (avar  AVAR | eff) m => Error -> AVarW' r a -> m Unit

The Cap is exact same thing as in Bus and i find it very useful. for example if are passing AVar to someone they can do many staff with it but if you instead pass AVarW you know they can only write to it and not read.

if you like I can make similar changes (except Monad{Aff,Eff} i guess) and then in ps-bus we can reuse this Cap.

Potential memory leak in `drainVar` loop

Followup issue mentioned in #8. I've been able to reproduce with only the Eff interface. I changed the take/put loop to force a manual GC every 50000 loops, which keeps it from growing so quickly, but it still grows, and the GC pauses get longer and longer as it has to walk over more and more references. There's definitely an issue here.

/cc @felixSchl

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.