std/async▲toc

Asynchronous primitives

This module is based closely on [1] and aims to have robust and composable asynchronous primitives. In particular, any outstanding asynchronous operation can be canceled (through cancel) within a certain scope which allows for composable primitives like timeout and firstof.

References

[1]Daan Leijen. Structured Asynchrony with Algebraic Effects. Microsoft Research technical report MSR-TR-2017-21, May 2017. pdf 🔎

.

Asynchronous operations have the asyncstd/async/async: HX effect.

A type alias for asynchronous operations that can raise exceptions non-deterministically. This is common for almost all asyncstd/async/async: HX operations since cancel and timeout can cancel operations non-deterministically which raises the Cancel exception and cancels outstanding asynchronous requests.

A channel of values of type a. Values can be asynchronously emitstd/async/emit: forall<a> (ch : channel<a>, value : a) -> asyncx ()ed into a channel, and asynchronously receivestd/async/receive: forall<a> (ch : channel<a>) -> asyncx ad.

Primitive: Execute setup to set up an asynchronous callback with the host platform. Invoke cb as the callback: it takes either an exception or a result value, together with boolean parameter whether the callback is done. The callback cb will eventually emit the result into the given channel ch after applying the transformation f to the result.
Note: once you exit the cancelablestd/async/cancelable: forall<a,e> (action : () -> <async|e> a) -> <async|e> a scope where await-to-channelstd/async/await-to-channel: forall<a,b> (setup : (cb : (try<a>, bool) -> io ()) -> io maybe<() -> io ()>, ch : channel<b>, f : (try<a>) -> b) -> async channel<b> was called, the callback is invoked with a Cancel exception. The channel should always be awaited within the same cancelablestd/async/cancelable: forall<a,e> (action : () -> <async|e> a) -> <async|e> a scope as the await-to-channelstd/async/await-to-channel: forall<a,b> (setup : (cb : (try<a>, bool) -> io ()) -> io maybe<() -> io ()>, ch : channel<b>, f : (try<a>) -> b) -> async channel<b> invokation.

Create a new asynchronous channel.

Emit a value asynchronously into a channel.

Receive (and remove) a value from the channel: returns immediately if a value is available and otherwise waits asynchronously until a value becomes available.

Return immediately if a value is available on the channel and otherwise returns Nothingstd/core/Nothing: forall<a> maybe<a>.

todo: use queue data type for the values and listeners for better complexity.

A promise that carries a value of type a. A promise is initially empty but can be awaited asynchronously until it gets resolvestd/async/resolve: forall<a> (p : promise<a>, value : a) -> asyncx ()d unblocking any await operations. After that a promise stays resolved and any await will return immediately. It is an error to try to resolve a promise more than once.

Await a promise; returns immediately if the promise was already resolved and otherwise waits asynchronously.

Resolve a promise to value. Raises an exception if the promise was already resolved.

Returns immediately if the promise was already resolved and otherwise return Nothingstd/core/Nothing: forall<a> maybe<a>.

abstract wid for timeout handlers.

The outer asyncstd/async/async: HX effect handler. This is automatically applied by the compiler around the main function if it has an asyncstd/async/async: HX effect.

Primitive: Execute setup to set up an asynchronous callback with the host platform. Invoke cb as the callback: it takes either an exception or a result a. Usually setup returns Nothingstd/core/Nothing: forall<a> maybe<a> but you can return a Juststd/core/Just: forall<a> (value : a) -> maybe<a>(cleanup) value where the cleanup functions is invoked on cancellation to dispose of any resources (see the implementation of wait). The callback should be invoked exactly once – when that happens await-exnstd/async/await-exn: forall<a> (setup : (cb : (try<a>) -> io ()) -> io maybe<() -> io ()>) -> async try<a> is resumed with the result.

Convenience function for awaiting a NodeJS style callback where the first argument is a possible exception.

Convenience function for awaiting a NodeJS style callback where the first argument is a possible exception and the second argument the possible result value.

Execute setup to set up an asynchronous callback with the host platform. Invoke cb as the callback: it takes either an exception or a result a. Usually setup returns Nothingstd/core/Nothing: forall<a> maybe<a> but you can return a Juststd/core/Just: forall<a> (value : a) -> maybe<a>(cleanup) value where the cleanup functions is invoked on cancellation to dispose of any resources (see the implementation of wait). The callback should be invoked exactly once – when that happens await is resumed with the result using untrystd/core/untry: forall<a> (ex : try<a>) -> exn a either raise an exception or return the plain result.

Convenience function for awaiting a zero argument callback.

Convenience function for awaiting a single argument callback.

The cancel operations cancels any outstanding asynchronous operation under the innermost cancelablestd/async/cancelable: forall<a,e> (action : () -> <async|e> a) -> <async|e> a handler by returning the Cancel exception. The cancel operation itself returns normally without raising a Cancel exception.

fun cancelable( action : () -> <asyncstd/async/async: HX|e> a ) : <asyncstd/async/async: HX|e> a

Execute action in a cancelable scope. If cancel is called within action, any outstanding asynchronous operations started in the cancelable scope are canceled. (Outstanding operations outside the cancelable scope are not canceled).

Interleave two actions around their asynchronous operations.

Interleave a list of actions around their asynchronous operations.

Interleave two actions around their asynchronous operations and explicitly returning either their result or their exception.

Interleave a list actions around their asynchronous operations and explicitly returning either either their result or their exception.

Wait (asynchronously) for secs seconds as a doublestd/core/double: V. Use yieldstd/async/yield: () -> <exn,async> ()() to yield to other asynchronous operations.

Wait (asynchronously) for optional secs seconds durationstd/time/duration/duration: V (= 0.seconds). Use yieldstd/async/yield: () -> <exn,async> ()() to yield generally to other asynchronous operations.

Yield to other asynchronous operations. Same as wait(0).