Skip to content

Releases: moonbitlang/async

v0.15.0

19 Dec 03:03

Choose a tag to compare

  • [breaking] Support closing @async.Queue via .close(). Detailed behavior:

    • any blocked put or get operation will fail immediately after calling .close()
    • calling put or try_put on a closed queue will fail immediately
    • calling get or try_get on a closed queue can still retrieve buffered elements in the queue. If the queue is closed and empty, get and try_get will fail immediately.
      • .close(clear=true) (clear=false by default) result in a hard close. Buffered elements in the queue will be discarded, and subsequent get & try_get operations always fail immediately

    By default, the error @aqueue.QueueAlreadyClosed will be raised for the above scenarios. However, the error can be customized via the error optional argument of .close().

    This change is breaking because try_get and try_put may now raise error.

  • add @async.lazy_init for creating lazily initialized async values. The result of lazily initialized async values can be retrieved by .wait(). The async initialization process will start automatically on the first .wait() request, and the result, once computed, will be cached. If all waiters are cancelled before the initialization completes, the initialization process will be cancelled automatically.

  • bug fix: @async.now() did not work in JavaScript backend previously

  • adapt to latest MoonBit release (v0.6.35)

v0.14.3

10 Dec 06:32

Choose a tag to compare

  • add .ping() method to @websocket.Conn for actively sending PING message and wait for corresponding PONG reply
  • remove some deprecated API: @fs.File::{seek,curr_pos}, @pipe.{stdin,stdout,stderr}
  • fix bug concerning behavior of current task calling @async.TaskGroup::return_immediately

v0.14.2

02 Dec 07:14

Choose a tag to compare

  • add WebSocket support via moonbitlang/async/websocket
  • fix API name typo: @http.{Client.ServerConnection}.entre_passthrough_mode => enter_passthrough_mode
  • all .close() methods are idempotent: things can be closed multiple times, only the first .close() takes effect
  • HTTP: no longer use chunked encoding when the body is empty. This improves compatibility with some restrictive client/server
  • adapt to MoonBit v0.6.33

v0.14.1

26 Nov 04:05

Choose a tag to compare

  • add @http.ServerConnection::client_addr(), which returns the address of client in a HTTP server connection
  • fix @http.Server::run_forever crashing when client sends multiple Content-Length: 0 requests
  • mark some internal API with #internal

v0.14.0

24 Nov 09:18

Choose a tag to compare

  • [breaking] allow different behaviors for @async.Queue::put. On queue creation, a kind argument can be provided, with four options:

    • Unbounded: this is the previous behavior. The queue has unbounded size, and put never block or fail. If kind is omitted in @async.Queue::new, this is also the default behavior, for compatibility sake. But a warning will be reported if kind is omitted.
    • Blocking(n): the queue's size must not exceed n. If the queue is full, put will block until the queue has enough space. Multiple blocked writers are processed in a FIFO manner
    • DiscardOldest(n): the queue's size must not exceed n. If the queue is full, put will discard the oldest element. put never block or fail for this kind of queue
    • DiscardLatest(n): the queue's size must not exceed n. If the queue is full, put will discard the newest element (i.e. the argument of put). put never block or fail for this kind of queue

    this change is breaking because put is now async. Note that for all kinds of queues except Blocking, put never actually suspend. A new API try_put is also introduced, which can be used in non-async context. try_put will return true iff the queue is not full and the new element is added. Note that try_put will not discard elements for DiscardOldest or DiscardLatest queues.

  • Refined API for HTTP server. A new type, @http.Server is introduced, with various APIs. The previous @http.run_server is deprecated in favor of @http.Server::new(..).run_forever(..). Compared to @http.run_server:

    • separating server creation and running allows binding the server to a random port for testing
    • the callback of @http.Server::run_forever handles a single request instead of connection. It accepts three parameters: the request header, a &@io.Reader for request body, and a @http.ServerConnection for writing response. This way the API is cleaner, and the user no longer need to manually loop for requests over the connection.
  • various HTTP client related API now accepts an extra proxy? : @http.Client parameter. If present, proxy should be another HTTP client in a clean state (i.e. no in the middle of a request). A CONNECT request will be sent to the proxy client to establish a opaque tunnel, and subsequent traffic will go through this tunnel

  • the port argument of @http.get etc., in favor of specifying the port in the URI, in the standard way. @http.Client::connect is deprecated in favor of a new API @http.Client::new. Except name difference, @http.Client::new no longer accept the protocol and port parameter, and instead require them to be specified in the URI

  • add @async.is_cancellation_error to detect if an error is the internal error used to represent cancellation. Note that @async.is_cancellation_error is not 100% accurate: if some cancellation handling code fail, the error may be replaced to something else. For accurate detection of cancellation, use @async.is_being_cancelled instead

v0.13.3

21 Nov 03:42

Choose a tag to compare

  • add experimental JavaScript backend support. Features include:
    • all IO-independent abstractions are available, including task group, timeout, async queue, semaphore etc.
    • a new package, moonbitlang/async/js_async, provides integration with JavaScript promise:
      • wait for JavaScript promise, with automatic cancellation support using AbortController
      • export async MoonBit function as JavaScript promise, again with native cancellation support via AbortSignal
  • add @async.is_being_cancelled for detecting whether current task is being cancelled. This is useful for avoiding dead loop for some code patterns, such as writing catch-all error handler inside loop body
  • ignore SIGPIPE, so that writing to a closed pipe result in a normal error instead of crashing the program
  • some other bugfix

v0.13.2

14 Nov 09:54

Choose a tag to compare

  • add @io.Reader::read_some, which read a new chunk of data from the reader as soon as new data arrives. This is useful for iterating over a reader stream chunk-by-chunk
  • add reuse_addr option for TCP/HTTP server. This is useful for testing and quick hacking, but should not be used in production
  • bugfix

v0.13.1

13 Nov 03:48

Choose a tag to compare

  • add .addr() method for @socket.{Tcp,TcpServer,UdpClient,UdpServer}, which return the local address of socket

v0.13.0

12 Nov 02:12

Choose a tag to compare

  • [breaking] @io.Reader is now always buffered. End users can take benefit from this via the new read_until API, which consumes input stream until a separator is reached. For end users this change should be non-breaking, but custom implementations of @io.Reader will be broken (this is not encouraged, though). The type @io.BufferedReader is no longer useful and is deprecated.
  • add new package moonbitlang/async/cond_var for condition variable. The type @cond_var.Cond can also be accessed via @async.CondVar. It supports a .wait operation, as well as .signal operation for waking up a single waker, and .broadcast for waking up all waiters. See the API doc for more details
  • introduce @io.pipe() and two new types @io.PipeRead & @io.PipeWrite, which implements fully user-space, un-buffered pipe. This is useful for testing and converting writer based function to reader. @pipe.pipe() is still useful for some complex process output collection task, but it may be deprecated in the future once we get replacement for that kind of tasks (e.g. merging output of multiple process)
  • add @http.{get,put,post}_stream, which are streaming version of @http.{get,put,post} and allows lazily read/write response/request body. These API return a @http.Client for lazy IO, which must be manually closed. Though more verbose, this allows precise control of connection lifetime.

v0.12.0

07 Nov 09:01

Choose a tag to compare

  • [breaking] @fs.opendir is now async
  • add @fs.symlink for creating symbolic link and @fs.chmod for changing file permission
  • add @fs.read_at and @fs.write_at for reading/writing file at specific position, without modifying or depending on the global file pointer state. Seeking based API are deprecated in favor of read_at/write_at
  • bug fix:
    • fix incorrect behavior of @io.BufferedReader::find{_opt} when target pattern span across multiple chunks of data
    • fix @process.collect_output hanging on large stderr
    • some MacOS systems do not have fdatasync, so we avoid calling it on MacOS and use fsync instead
    • fix a race condition that may crash the runtime