Skip to content

Instantly share code, notes, and snippets.

@CrowdHailer
Last active March 23, 2021 10:43
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save CrowdHailer/4ce96fe94d8be80b83d371e90612f279 to your computer and use it in GitHub Desktop.
Save CrowdHailer/4ce96fe94d8be80b83d371e90612f279 to your computer and use it in GitHub Desktop.
Implementing actors in JavaScript.
// Turns out this was not too difficult.
// By using the event loop as a global mail box ordering is even guaranteed for messages between only two actors.
// TODO would like to try and put one actor in a web worker to get some real parallism
// TODO would like to handle errors and have the concept of a deceased actor while a reference to an actor still exists. Probably involves creating an actor system like in Scala. Eurgh.
var actor = {
send: function(message) {
var self = this;
console.log("sending to:", self);
setTimeout(function(){
self.receive(message);
}, 0);
},
state: 0,
receive: function(message){
this.state += message;
console.log(this.state);
}
};
// console.log("hello");
// actor.send(1);
// actor.send(1);
// actor.send(1);
function End(){}
var end = new End();
function Actor(handler, state){
this.handler = handler;
this.state = state;
}
Actor.prototype.end = function(){
return new End();
};
Actor.prototype.send = function(message){
var self = this;
setTimeout(function(){
self.receive(message);
});
return self;
};
Actor.prototype.receive = function(message){
reply = this.handler(this.state, message);
// Could just end by throwing errors instead
if (reply instanceof End) {
console.log("ending");
this.handler = function(){};
} else {
this.state = reply;
}
};
function add(a, b){
console.log(a);
return a === 3 ? new End() : a + b;
}
var a = new Actor(add, 0);
a.send(1).send(1).send(1).send(1).send(1).send(1);
var shout = new Actor(function(state, message){
console.log(message);
});
var forward = new Actor(function(target, message){
target.send(message);
return target;
}, shout);
// forward.send("first");
// shout.send("second");
var ponger = new Actor(function(state, message){
message.from.send(message.payload);
});
var pinger = new Actor(function(state, message){
if (message.ping) {
state.send({from: this, payload: message.payload});
} else {
console.log(message);
}
}, ponger);
pinger.send({ping: true, payload: "huzzah"});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment