Skip to content

0.34.0

Compare
Choose a tag to compare
@SeanTAllen SeanTAllen released this 03 May 13:57

Pony version 0.34.0 is now available. The release features a couple of small breaking changes. We recommend updating at your leisure.

What's new in 0.34.0?

  • Two breaking changes in the process package.
  • A new build system for ponyc.
  • A number of packaging and support tooling changes.
  • A small, but important runtime change.

Please see our installation instructions for how to install 0.34.0 on your operating system of choice. If you run into installation problems, please open an issue or, let us know on the Zulip.

0.34.0 is the first release where the Pony core team is no longer maintaining the Homebrew ponyc formula. If you'd like to take over maintenance, let us know, we'd be happy to help you get started. The current formula expects our old build system which has been replaced (see the first release note item below) and will need to be updated to build with our new cmake system. If you are interested in taking over, drop Sean T Allen a line on our Zulip.

Build PonyC using CMake

A new build system for ponyc based on CMake has been implemented. Requirements and instructions for building from source have changed; please see BUILD.md for updated details.

Make clang our default compiler on Linux, macOS, and FreeBSD

All official Pony pre-built packages, both nightlies and releases are now built with clang instead of gcc. We will make a best effort to not break gcc when we implement changes to ponyc, however, all testing is done with clang.

As a result of this change, the default linker for ponyc has switched from clang to gcc. If you haven't set your CC and CXX environment variables to clang/clang++ or gcc/g++ then you must have clang installed as ponyc will look to use usr/bin/clang as the linker; this is a change from previous releases where /usr/bin/gcc was the default linker.

Update to supported operating systems

We now support Ubuntu 20.04 as our officially supported glibc Linux distribution. Ubuntu 18.04 is no longer supported, however, we continue to make a best effort case to continue to support it.

FreeBSD 12.0 support has been deprecated, the last FreeBSD release 12.1 is our officially supported version.

FreeBSD packages are now available

As of Pony 0.34.0, we are now supplying prebuilt packages for FreeBSD 12.1. There are both release and nightly versions available.

Docker Images for Windows

There are now automatically-built Docker images for Windows that include ponyc:

  • ponylang/ponyc:windows: Includes PonyC nightly builds.
  • ponylang/ponyc:release-windows: Includes the latest PonyC release version.

You can find them on DockerHub with our other ponyc images.

Let ProcessMonitor chdir before exec

The ProcessMonitor class now takes an argument for the desired working directory of its child process, and will change to that directory prior to spawning the child.

Also, for debugging convenience, errors that happen before the child process's standard error is set up will be piped to the notifier's stderr.

The Unsupported ProcessError value has been removed. Matches that include this value will need to be updated; however, see the next item for additional ProcessMonitor-related breaking changes.

Update ProcessMonitor errors to contain error messages

The types in the ProcessError union in the process stdlib package now contain error messages. So instead of matching on the individual types and providing your own error messages, you should call .string() on a single value of type ProcessError to get an error message. For example, some code that implemented ProcessNotify used to look like this:

  fun ref failed(process: ProcessMonitor ref, err: ProcessError) =>
    match err
    | ExecveError => _env.out.print("ProcessError: ExecveError")
    | PipeError => _env.out.print("ProcessError: PipeError")
    | ForkError => _env.out.print("ProcessError: ForkError")
    | WaitpidError => _env.out.print("ProcessError: WaitpidError")
    | WriteError => _env.out.print("ProcessError: WriteError")
    | KillError => _env.out.print("ProcessError: KillError")
    | CapError => _env.out.print("ProcessError: CapError")
    | Unsupported => _env.out.print("ProcessError: Unsupported")
    else _env.out.print("Unknown ProcessError!")
    end

Now it should look like:

  fun ref failed(process: ProcessMonitor ref, err: ProcessError) =>
    _env.out.print(err.string())

If you want to determine the type of error, you can match on the ProcessError.error_type field, e.g.:

  fun ref failed(process: ProcessMonitor ref, err: ProcessError) =>
    match err.error_type
    | ExecveError => // do something
    | PipeError => // do something else
    ...
    end

Schedule the cycle detector with higher priority using the inject queue

PR #2709 introduced the cycle detector being lazily scheduled once a certain amount of CPU ticks (--ponycdinterval) has passed. Scheduler thread 0 would then 'wake up' the the cycle detector by sending it a CHECK_BLOCKED message. The cycle detector would then be appended to the end of scheduler 0's queue. The cycle detector would then only be scheduled if either:

  1. Scheduler 0 is available (i.e. its queue was empty in the previous loop iteration).
  2. Another scheduler thread is available and steals the cycle detector from scheduler 0's queue. However, this would only happen when the cycle detector has 'travelled' to the head of said queue.

This could create pathological behavior where cycle detection is actually deferred to a point in time where the program would be almost quiescent, especially for programs that create lots of actors right at program start, such that the distance for the cycle detector to reach the head of the scheduling queue might be relatively long.

This change treats the cycle detector as a special system actor that is maintained on the schedulers global inject queue. That is, it is always scheduled using its original start up main context (which is not related to any runtime thread), making sure that a CHECK_BLOCK message (and any other message it would receive after being blocked) will cause it to be pushed to the global inject queue. Every scheduler thread that has become available would first try to consume an item from this queue before attempting to get an actors from its local queue.

This should have the following effects on runtime system behavior:

  1. Get the cycle detector to be scheduled closer to --ponycdinterval, making this a theoretical upper bound setting.
  2. Have the cycle detector to be scheduled with higher priority as it can be pop_global'd by any scheduler thread from the inject queue.
  3. Not defer garbage collection of large actor graphs for long running programs right to (or close to) the end of a quiescent system.

[0.34.0] - 2020-05-03

Added

  • Build Docker images for windows builds (PR #3492)
  • Added support for VS Preview (PR #3487)
  • Add nightly FreeBSD 12.1 builds (PR #3502)
  • Add OSSockOpt constants added by Linux 5.1 kernel (PR #3515)
  • Add prebuilt FreeBSD 12.1 builds for releases (PR #3525)

Changed

  • Build PonyC using CMake (PR #3234)
  • Update supported FreeBSD version to 12.1 (PR #3495)
  • Make clang our default compiler on Linux, macOS, and FreeBSD (PR #3506)
  • schedule the cycle detector with higher priority using the inject queue (PR #3507)
  • Update glibc Docker image based to Ubuntu 20 (PR #3522)
  • Change supported Ubuntu version to Ubuntu 20 (PR #3522)
  • Let processmonitor chdir before exec (PR #3530)
  • Removed unused Unsupported error from ProcessMonitor(PR #3530)
  • Update ProcessMonitor errors to contain error messages (PR #3532)