NoFlo 0.8 is out now

After several months of work, NoFlo 0.8 is finally out as a stable release. This release is important in that it brings the Process API for NoFlo components to general availability, paving way for the 1.x series.

Process API

We introduced Process API in the 0.7 series last summer, but at that stage it wasn’t deemed good enough for production use. There were issues with features like bracket forwarding, as well as API convenience questions that we’ve since tackled. With NoFlo 0.8 onwards, Process API is the recommended way to write all components.

Here are some of the major features coming to Process API with 0.8:

  • hasData and getData methods for dealing with data packets in the inports
  • hasStream and getStream methods for dealing with complete streams of IPs in the inports
  • Calling output.done is now required to signal when component is done processing
  • Automatic bracket forwarding from and to multiple ports as defined in forwardBrackets configuration
  • Support for receiving packets from addressable ports using the [portname, idx] syntax

More information on how to use the API for writing NoFlo components can be found from the Process API guide I wrote back in January.

Big thanks yet again to Vladimir Sibirov for his work pushing Process API to production!

WirePattern

Before Process API, WirePattern was the preferred convenience method used for writing NoFlo components. It made it easy to synchronize data from multiple inports, and to manage lifecycle of asynchronous components. Process API was largely designed to address the learnings we’ve had from the years using WirePattern in production, both the conveniences and the pitfalls.

Since vast majority of current open source NoFlo components use WirePattern, it wasn’t feasible to simply go and deprecate the API. Instead, what we did in the 0.8 cycle was port WirePattern to actually run on top of Process API.

So, when you update to NoFlo 0.8, all WirePattern components will automatically switch to using Process API internally. This means that existing components and graphs should stay working as they always did, except now fully compatible with features like scope isolation, bracket forwarding, and the new network lifecycle.

In 0.8 series we still also ship the original WirePattern implementation, which can be enabled in two ways:

  • Passing a legacy: true as an option to the WirePattern function. This will cause that component to use the legacy WirePattern iimplementation
  • Setting NOFLO_WIREPATTERN_LEGACY environment variable to force all WirePattern components to use legacy mode

There should be no reason to use the legacy mode. If you find a backwards compatibility issue forcing you to do so in your projects, please file an issue.

Component and network lifecycle

Another area of focus for 0.8 was the network lifecycle. The legacy component API in NoFlo had no way for components to tell when they’re done processing data, and hence the network wasn’t able to determine accurately when it was finished.

With Process API we give components much better way to handle this — when you’re done processing, call output.done(). Until then the component is expected to be doing work. When all components have deactivated, the network is considered finished:

NoFlo program lifecycle

To support the lifecycle better, we also made both component and network star-up and shutdown asynchronous with callbacks. This ensures every node in a NoFlo network can do everything it needs to initialize or clean up at the right stage of the flow.

The network methods are:

  • network.start(callback) to start the network. This starts all components and sends the Initial Information Packets
  • network.stop(callback) to stop the network. This calls all components to shut down, closes connections between them, and clears any in-flight inport buffers

If your component needs to do anything special at start-up or shutdown, the new methods it can provide are:

  • component.setUp(callback) called when network starts. Component can do self-initialization but should not send anything at this stage
  • component.tearDown(callback) called when network stops. Stateful components can clean their state at this point, and generators should stop generating (remove event listeners, shut down socket connections, etc)

The tearDown method replaces the old shutdown method. While shutdown method still gets called, all components should migrate to the async-capable tearDown in this release cycle.

Deprecated features

The 0.8 series adds deprecation warnings to features that will be removed from the eventual NoFlo 1.x release. You can find a full list from the ChangeLog, but here are some notable ones:

  • Synchronous WirePattern usage (switch to async: true or port to Process API)
  • noflo.AsyncComponent and noflo.helpers.MapComponent (should be ported to Process API)
  • noflo.InPort legacy packet methods process, receive and contains
  • Legacy noflo.Port and noflo.ArrayPort implementations. Use the modern noflo.InPort and noflo.OutPort instead
  • component.error and component.fail methods. Use WirePattern or Process API error callback instead

By default using a deprecated feature only logs a warning. If you want to make these fatal, set the NOFLO_FATAL_DEPRECATED environment variable. This can be useful for Continuous Integration.

Getting 0.8

NoFlo 0.8.x releases can be found from NPM.

  • For Node.js projects, the noflo-nodejs command-line runner has been updated to 0.8
  • For browser projects, noflo-browser-app scaffolding has been updated to 0.8

As I write this, the hosted browser runtime is still on 0.7. We will hopefully get it updated shortly.


Read more Flow-Based Programming posts.