Last active
March 23, 2021 10:43
-
-
Save CrowdHailer/4ce96fe94d8be80b83d371e90612f279 to your computer and use it in GitHub Desktop.
Implementing actors in JavaScript.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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