Skip to main content

Introducing Pond 3.0

· 5 min read
Benjamin Sieffert
Distributed Systems Engineer at Actyx

With the release of Actyx V2, we are also shipping a new major version of the Pond: 3.0 is here.

The major features of this release are:

  • Compatible with shiny new Actyx V2!
  • Also compatible with ActyxOS V1
  • Hugely improved performance in the case of many active Fish, independent of which Actyx version is used

In terms of API changes, we have introduced as little breaking changes as possible. This should make it straight-forward to migrate an existing app to Pond 3.0 and thus be able to run it on Actyx V2!

Read on to learn all you need to know.

New Pond constructor#

Initialization of the Pond is the only thing that will have to be changed in every app. With the new auth scheme introduced in Actyx V2, every client has to authenticate itself with the Actyx API.
For this, the Pond needs your app manifest.

// Simplest way to initialise a Pond nowconst pond = await Pond.default({  appId: 'com.example.my-app',  displayName: 'My Example App',  version: '1.0.0',})

For development, you can use any manifest where the appId starts with com.example – this is the free development mode.

When your application enters production use, you create a proper manifest and get Actyx’ signature:

// Initialisation of the Pond in productionconst pond = await Pond.default({  appId: 'com.my-company.production-app',  displayName: 'MyCompany’s factory application',  version: '1.2.0',  // The signature depends on the manifest, this is just an example  signature: "8Bl3z…C7TREAQ==",})

Read our docs on Auth for more details on how to create and sign manifests.

getNodeConnectivity is gone (for now)#

We are working on a much-improved UX for diagnosing and displaying connectivity with your swarm of Actyx devices.
In the meantime, the function Pond.getNodeConnectivity is no longer available.

Local Snapshots are gone (for now)#

Due to the much improved querying performance of Actyx V2, the Pond is no longer using Local Snapshots. As such, the recently introduced snapshotThreshold parameters have been removed again.

We are working on exciting new features that utilize Local Snapshot technology, perhaps this time in a completely opaque fashion.
Until then, please let us know if your application performance suffers from the removal of Local Snapshots, so we can work with you in taking the tech to the next level!

The Pond is now based on @actyx/sdk#

We have started work on a new TypeScript library, named @actyx/sdk. The SDK will be where future innovation happens for our TypeScript offering. For now, the SDK contains everything that is very much related to Actyx, but not related to Fish – most notably, the recently introduced EventFns are now implemented inside the SDK.

As a Pond user, you will hardly notice this change: The Pond re-exports the complete SDK API surface. You don’t have to import anything from the SDK manually.

If you are building an application that doesn’t need the Pond, you can now just use the SDK. One common example would be an event exporter:

import { Actyx } from '@actyx/sdk'
const actyx = await Actyx.of(myManifest)
// Export events in chunks of at most 2000 elements, at least once every minuteactyx.subscribeChunked(  {},  { maxChunkTimeMs: 60_000, maxChunkSize: 2000 },  writeToMyDB)
info

The SDK is still at major version 0 – expect frequent changes and improvements to the API.

The Pond’s dependency on the SDK is flexible. You can run npm i @actyx/pond in your project to update both Pond and SDK to their latest versions.
If there is no new Pond version, npm will still update the transitive SDK dependency, giving you new functionality (re-exported by the Pond) to work with!

What’s changed in the SDK?

Tags can now automatically extract IDs#

There was some tedium involved with making sure you attached the right "id" to events you tagged.

One common example for this are events that carry both a machine and a production order ID.

const FooTag = Tag<FooEvent>('foo')// Will tag with 'foo' and `foo:${event.fooId}`actyx.emit(FooTag.withId(event.fooId).apply(event))

Forgetting the ID means you have a hard time finding the exact events you need, later.
We’ve now added a simple mechanism for automatically attaching IDs.

// The passed-in function is used to automatically find IDsconst FooTag = Tag<FooEvent>('foo', event => event.fooId)// Will tag with 'foo' and `foo:${event.fooId}`actyx.emit(FooTag.apply(event))
// (this also works in the Pond)pond.emit(FooTag, event)

While we continue working on new concepts for identifying and finding events, we hope this makes using tags a tad easier.

SourceId becomes Stream in Metadata#

The concept of SourceId is deprecated in Actyx V2. The successor concept is event streams.

If you are running Pond 3.0 on an Actyx V2 back end, metadata.stream will contain Stream IDs.
They look like this: LJpRDkcgyOjLruMvk.q1dXZyf9DCwKqyAiYvi7N/KgE-1

If you are running Pond 3.0 on an Actyx V1 back end, metadata.stream will still contain Source IDs, though this is technically incorrect: Source IDs are not Stream IDs! In practice, this makes little difference, since Actyx V1 and Actyx V2 nodes cannot talk to each other.
In the near future, we will offer migration from ActyxOS V1 to Actyx V2, and will in that context explain how to turn all your Source IDs into Stream IDs.

PendingEmission now supplies Metadata of the written events#

The list of returned Metadata is in the same order as the list of events passed into the emit call.

Pond.run meanwhile returns a new type called PendingCommand, which still supplies no Metadata.

EventFns.queryAllKnownChunked is now also cancelable#

As all other querying functions in EventFns, queryAllKnownChunked now also returns a function that can be called in order to cancel the ongoing execution of the query.
So it very naturally converts to an Observable:

const chunks$ = new Observable(o =>  actyx.queryAllKnownChunked({}, 2000, chunk => o.next(chunk), () => o.complete()))