Skip to content

v0.22.0

Choose a tag to compare

@Guest0x0 Guest0x0 released this 16 Sep 03:56
· 30 commits to main since this release
  • [breaking] catch can no longer capture cancellation.

    In this release, moonbitlang/async changes how cancellation is signaled for cancelled code. Previously cancellation signal is represented using an ordinary suberror. In this release, cancellation signal is represented using special compiler primitive. The cancellation signal still propagate likes error and triggers defer/errdefer like an error. However, try .. catch can no longer capture the cancellation signal.

    The correct way to adapt this change depend on existing code shape:

    • code using defer/errdefer need no change at all
    • code using catch for cleanup purpose, migrate to defer/errdefer. There should be a compiler warning for catch handler that looks like defer/errdefer. Notice that defer/errdefer can contain raise or async code now
    • other kinds of catch handler usually should not capture cancellation anyway. For example user should not wrap cancellation signal into another error in general, because that will confuse various structural concurrency combinators. If the catch handler previously skip cancellation signal manually via is_cancellation_error, simply remove that special case. If the catch handler has no special cancellation handling previously, upgrading to this version may fix buggy behavior on cancellation automatically
    • when special handling of cancellation is indeed desired, use @async.handle_cancellation
  • [breaking] @async.is_cancellation_error now always return false and is deprecated, because cancellation signal is no longer a special error. For catch handlers using with special @async.is_cancellation_error branch, either delete the branch directly (if the branch is used to prevent cancellation from getting handled like other errors) or use @async.handle_cancellation instead.

  • [breaking] @async.TaskGroup::add_defer now requires the deferred block to be nocancel

  • [breaking] add noraise mask to various API, such as @async.sleep. These functions were previously considered raise because they are cancellable, and cancellation signal was previously an error. In this version, cancellation is now separated from normal error, so async API that never raise an error themselves, merely cancellable can now receive a more precise type with noraise mark.

    This change should be invisible for most users. However code that use affected function as higher order function directly may receive a type error.

  • adapt nocancel mark in various API. The latest version of MoonBit now provides a new nocancel mark on function signature. The nocancel mark is added to @async.protect_from_cancel and several other inherently non-cancellable API. When using moonbitlang/async, nocancel always mean "not cancellable". Code that capture cancellation signal are still cancellable, and indeed the signature of @async.capture_cancellation does not contain nocancel

  • deprecate @async.with_cancellation_handler, in favor of a new API @async.handle_cancellation. @async.handle_cancellation runs a cancellable async callback, and return None if the callback is cancelled while running. Notice that @async.handle_cancellation only captures a single cancellation signal, it does not revert cancellation altogether. Current task remain in cancelled state, and subsequent unprotected async operation still get cancelled immediately

  • @fs.remove and @fs.rmdir are made non-cancellable, because they are often used in cleanup operations

  • introduce @async.platform for runtime OS detection. This is especially useful for Wasm backend, because a single Wasm binary can be run on different operating systems, so the actual OS can only be known at runtime. Currently supported operating systems include Linux, MacOS and Windows

  • bug fix & adapt latest compiler version