Quickstart

Let's jump right in and get a first distributed application up and running.

Need help?

If you have any issues or just want to give feedback on our quickstart guide, you are welcome to join our Discord chat or write us an e-mail to [email protected] .

Requirements

Prepare

All the files you need for this quickstart guide can be found in a Github repository. Go ahead and clone it:

git clone https://github.com/Actyx/quickstart

Inside the newly created quickstart directory you should now find the following files and directories:

quickstart/
|--- scripts/
|--- sample-webview-app/
|--- sample-docker-app/
|--- misc/

The business logic

ActyxOS is all about distributed apps communicating with one another, so let’s write an app that sends events around and displays events from other apps. The easiest approach is to use the Actyx Pond library and write the app in the Typescript language. The distributable pieces of app logic are called fishes:

import { Pond, Semantics, OnStateChange, Subscription, FishTypeImpl } from '@actyx/pond'
// Each fish keeps some local state it remembers from the events it has seen.
// In this case, we’ll just remember some details of the latest event.
type State = { time: string, name: string, msg: string, } | undefined
const ForgetfulChatFish: FishTypeImpl<State, string, string, State> = FishTypeImpl.of({
// The kind of fish is identified by the meaning of its event stream, the semantics
semantics: Semantics.of('ForgetfulChatFish'),
// When the fish first wakes up, it computes its initial state and declares which
// event streams to listen to. Most fishes subscribe to their own event stream.
initialState: (_name, _sourceId) => ({
state: undefined, // start without information about previous event
subscriptions: [Subscription.of(ForgetfulChatFish)] // all fish of this kind
}),
// Upon each new event, keep some details of that event in the state.
onEvent: (_state, event) => ({
time: new Date(event.timestamp / 1000).toISOString(),
name: event.source.name,
msg: event.payload
}),
// Show the state computed above to the outside world (see Pond.observe below).
onStateChange: OnStateChange.publishPrivateState(),
// Upon each received command message generate a single event.
onCommand: (_state, msg) => [msg],
})

This piece of logic can be run on multiple edge devices, each running an ActyxOS node, and we’ll do so in the following. But before we can do that we need to add some code that takes the type of fish defined above and wakes up one specific instance, identified by its name.

// get started with a Pond
Pond.default().then(pond => {
// figure out the name of the fish we want to wake up
const myName = process.argv[2] || pond.info().sourceId
// wake up fish with the given name and log its published states
pond.observe(ForgetfulChatFish, myName).subscribe(console.log)
// send a 'ping' message every 5 seconds to generate a new event
setInterval(() => pond.feed(ForgetfulChatFish, myName)('ping').subscribe(), 5000)
})

This example shows how to start this fish and have it emit one event every five seconds. Now we want to see this in action, so let’s install the necessary ingredients.

Install the Actyx CLI

Download and install the latest version of the Actyx CLI (ax). You can find builds for several operating systems at https://downloads.actyx.com. You can find detailed installation instructions for the Actyx CLI here.

Once installed you can check that everything works as follows:

ax --version
Having trouble?

Check out the troubleshooting section below or let us know.

Start ActyxOS

Now, start ActyxOS as a Docker container on your local machine. Since ActyxOS is published on DockerHub, you can start it using the following command:

docker run --name actyxos -it --rm -e AX_DEV_MODE=1 -v actyxos_data:/data --privileged -p 4001:4001 -p 4457:4457 -p 4243:4243 -p 4454:4454 actyx/os

ActyxOS will be up and running as soon as you see something like

***********************
**** ActyxOS ready ****
***********************
note

As you can see, you need to provide a persistent volume and set up some port forwarding. For more information about running ActyxOS on Docker, refer to the ActyxOS documentation.

Now that it is running, we need to provide the ActyxOS node with a couple of settings. These allow the node to function correctly. For now, we will just use the sample settings defined in misc/local-sample-node-settings.yml. Run the following command:

ax settings set --local com.actyx.os @misc\local-sample-node-settings.yml localhost

😊 Congrats! Your computer is now running a fully configured ActyxOS node. You can check this by running

ax nodes ls --local localhost

Run the app in Dev Mode

note

In the following we assume that you have cloned the github repository with the sample apps and opened a shell inside that folder.

Docker app

You’ll find the app prepared in the folder sample-docker-app. Inside this folder, run the following to install the dependencies:

npm install

Now you can start the app by running

npm start Dori

This will connect to ActyxOS and then start printing out lines after a few seconds, corresponding to state updates from the ForgetfulChatFish named “Dori”.

WebView app

The WebView app is prepared in the folder sample-webview-app. As for the docker app, first install the dependencies:

npm install

Then start the built-in webserver by running

npm start

The app itself will only start once you open it in your web browser, you should find it at http://localhost:1234 (or check the output of the above command). If you kept the docker app running in your terminal, you should see its messages appear after clicking the “send message” button.

tip

The fish we used here is called ForgetfulChatFish because it only remembers some details from the most recent event it has seen. Why don’t you try your hand at keeping the last ten messages in its state and render that as a list in the UI?

Deploy the app

ActyxOS on Docker

First, we need to build a docker image containing the app. This is done inside the sample-docker-app folder by running

npm run build:image

The resulting image is packaged into an Actyx App using the Actyx CLI:

ax apps package
This can take a couple of minutes

Packaging Docker apps can take quite a bit of time. Please give it a couple of minutes. Unfortunately the Actyx CLI does not provide any feedback during packaging yet (we are working on that).

After a few moments you’ll find an app package in your folder. This can be deployed to the ActyxOS node by running

ax apps deploy --local com.actyx.sample-docker-app-1.0.0-x86_64.tar.gz localhost

You can check the state of this app using

ax apps ls --local localhost

As you will see the app is deployed, but stopped, so let's start it with this command:

ax apps start --local com.actyx.sample-docker-app localhost

If you still have the webview app open running in dev mode in your browser, you should see the ping messages appear in there. The two apps are so far served by the same ActyxOS node.

In order to make this sample fully distributed you can either start another ActyxOS node on a different computer (by repeating the ActyxOS steps above), or you can continue with an Android device as we will do here.

ActyxOS on Android

After installing ActyxOS from the Google Play store, start ActyxOS by clicking on the ActyxOS app in Android.

Having trouble installing?

Now that you have installed ActyxOS on the second device, let's configure the node and then package and deploy one of the sample apps. From the quickstart folder, run the following command:

ax settings set --local com.actyx.os @misc\remote-sample-node-settings.yml <DEVICE_IP>
note

Replace <DEVICE_IP> with the IP of your Android device.

The ActyxOS node on the second device should now be fully functional! 😊

Now go back to the sample-webview-app folder and create the production build for this web app:

npm run build

The resulting files in the dist folder can now be packaged into an Actyx app using

ax apps package

The resulting app is then deployed to the Android device by running

ax apps deploy --local com.actyx.sample-webview-app-1.0.0.tar.gz <DEVICE_IP>

Now that the app is deployed, you can start it either by selecting it from the ActyxOS app on Android or by using the Actyx CLI:

ax apps start --local com.actyx.sample-webview-app <DEVICE_IP>

Congratulations, you have just packaged and deployed an ActyxOS app to a remote ActyxOS node!

You should now see two apps running locally on you computer and the app running on the device communicating with each other without any central server or database.

This brings us to the close of this quickstart guide.

Further reading

Troubleshooting

Where to get help and file issues

If you have any issues or just want to give feedback on our quickstart guide, you are welcome to join our Discord chat or write us an e-mail to [email protected] .