This project aim to bring Akka framework available for JS applications.
NOTE the current exposed API is minimal, I will be happy to receive Issues asking for further functionalities to be exposed, and more happy to have PR.
Install the module:
npm install akkajs
A simple Ping Pong between two actors looks like:
const akkajs = require("akkajs")
const system = akkajs.ActorSystem.create()
class Pinger extends akkajs.Actor {
constructor() {
super()
this.name = "pinger"
this.receive = this.receive.bind(this)
}
receive(msg) {
console.log("RECEIVED PING")
this.sender().tell("pong")
}
}
const pinger = system.spawn(new Pinger())
class Ponger extends akkajs.Actor {
constructor() {
super()
this.name = "ponger"
this.receive = this.receive.bind(this)
}
receive(msg) {
console.log("RECEIVED PONG")
this.sender().tell("ping")
}
}
const ponger = system.spawn(new Ponger())
pinger.tell("ping", ponger)
An Actor based greeter on Node looks like follows:
const akkajs = require("akkajs")
const readline = require("readline")
const system = akkajs.ActorSystem.create("helloworld")
class Greeter extends akkajs.Actor {
constructor() {
super()
// following guideline in: https://facebook.github.io/react/docs/react-without-es6.html#autobinding
this.receive = this.receive.bind(this)
}
receive(msg) {
console.log("Hello " + msg)
}
}
const greeter = system.spawn(new Greeter())
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
rl.question(
"What is your name? ",
(answer) => {
greeter.tell(answer)
rl.close()
}
)
Akka.Js is pure Javascript and has not got known limitations in running in the major browsers or directly on any JS VM (e.g. Node, Phantom, ...)
Into the github repo there are few examples under the demo
folder.
To run the examples simply clone this project go into the demo
directory and run with:
https://github.com/akka-js/akka.js_bindings.git
cd akka.js_bindings/demo
run <example-name>
Configuration
class enable you to configure your ActorSystem
.
Configuration is based on the HOCON standard ported to JS through ScalaJs thanks to SHOCON
The Configuration
constructor accept an optional String as parameter that enable you to override parameters.
all defaults instantiation:
const config = new akkajs.Configuration()
custom instantiation:
const config = new akkajs.Configuration(`akka {
loglevel = "DEBUG"
stdout-loglevel = "DEBUG"
}`)
the full default configuration can be found here
Methods
Method | Description |
---|---|
config.add(moreconfig) |
To add additional customizations to your configuration (e.g. config.add("akka.log-config-on-start = on") ) |
config.get() |
To obtain the configuration object to construct an ActorSytem |
An ActorSystem
is a container and the environment for your Actors.
The ActorSystem
creator method accept an optional String as name and an optional configuration.
all defaults instantiation:
const system = akkajs.ActorSystem.create()
with custom name:
const system = akkajs.ActorSystem.create("myActorSystem")
with custom name and configuration:
const system = akkajs.ActorSystem.create("myActorSystem", config.get())
Methods
Method | Description |
---|---|
system.terminate() |
Shutdown the ActorSystem |
system.select(actorpath) |
To obtain the reference to an Actor |
system.spawn(actor) |
Will spawn a new instance of the provided Actor and return the reference to it |
An Actor
is is an execution unit that runs concurrently with other actors.
You have to define a class that extends
akkajs.Actor
and use the spawn
method on an instance of it to run your Actor
and obtain the reference to it.
class Example extends akkajs.Actor {
constructor() {
super()
this.receive = this.receive.bind(this)
}
receive(msg) {
// do something when you receive a message
}
}
const actor = system.spawn(new Example())
Actors
talk each other only by message passing and you cannot call directly a method on them.
Given a reference to an Actor
you can invoke the followings:
Methods
Method | Description |
---|---|
actor.path() |
Return a String representing a logical path associated to your actor, it can be used to identify an actor using the select method |
actor.tell(msg) |
Send to the Actor the specified msg |
actor.tell(msg, anotheractor) |
Send to the Actor the specified msg pretending the sender to be anotheractor |
actor.kill() |
Will kill the specified actor |
When defining an Actor class you can override a few definitions
Methods
Method | Description |
---|---|
this.name |
The name of the Actor will be used to construct the path |
this.receive(msg) |
This method gets triggered when dequeuing the mailbox of the actor |
this.preStart() |
Triggered once when the Actor is started (or re-started) |
this.postStop() |
Triggered once when the Actor is stopped |
an example class that override all of these looks like:
class Example extends akkajs.Actor {
constructor() {
super()
this.name = "newname"
this.preStart = this.preStart.bind(this)
this.receive = this.receive.bind(this)
this.postStop = this.postStop.bind(this)
}
preStart() { console.log("starting " + this.name) }
receive(msg) { console.log("received message: " + msg) }
postStop() { console.log("stopping") }
}
// and you can trigger all of them by running:
const actor = system.spawn(new Example())
setTimeout(
() => {
actor.tell("hello world")
actor.kill()
}
)
From within the Actor
itself you have access to a few more functions to call:
Methods
Method | Description |
---|---|
this.path() |
Return the path of the Actor |
this.parent() |
Return the array of the children of this Actor |
this.children() |
Return the array of the children of this Actor |
this.sender() |
Called within the receive method return the reference to the Actor that sent the message - inferring the sender has some limitations consider using explicit sender in the tell method to have it working reliably |
this.self() |
Return the reference to itself |
this.system() |
Return the ActorSystem this Actor belong to |
this.spawn(actor) |
Let spawn an Actor as a child of this one, return it's reference |
this.become(func) |
Change the current receive function to the argument func |
You need to install Sbt to compile this project from sources. Compile with
sbt compile
and you can test examples with your modifications by running first:
sbt deploy
and running desired examples into the demo
directory.