Skip to content

Commit

Permalink
Version 0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
stagas committed May 15, 2012
1 parent 8415784 commit 8243cba
Show file tree
Hide file tree
Showing 26 changed files with 876 additions and 451 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
node_modules
63 changes: 0 additions & 63 deletions examples/akka-tutorial-first.js

This file was deleted.

12 changes: 12 additions & 0 deletions examples/ask.js
@@ -0,0 +1,12 @@
var drama = require('../')
var sys = drama('sys')

var actor = sys.actor({
hello: function () {
this.reply('hello back')
}
}).pick('?hello')

actor.hello(function (reply) {
console.log(reply)
})
32 changes: 32 additions & 0 deletions examples/async-db.js
@@ -0,0 +1,32 @@
var drama = require('../')
var sys = drama('sys')
var atomic = require('atomic')

var db = sys.actor(function () {
var data = {}
var lock = atomic()
return {
get: function (key) {
var reply = this.reply.bind(this)
lock(key, function (done) {
setTimeout(function () {
reply(data[key], key)
done()
}, 500)
})
}
, set: function (key, val) {
lock(key, function (done) {
setTimeout(function () {
data[key] = val
done()
}, 1000)
})
}
}
}).init().pick('?get', 'set')

db.set('foo', 'bar')
db.get('foo', function (val, key) {
console.log('%s: %s', key, val)
})
21 changes: 21 additions & 0 deletions examples/chat-client.js
@@ -0,0 +1,21 @@
var readline = require('readline')
var net = require('net')

var rl = readline.createInterface(process.stdin, process.stdout)
rl.on('close', function () {
console.log('Have a great day!')
process.exit()
})

var client = net.connect(6886, 'localhost')

client.setEncoding('utf8')
client.on('data', function (data) {
process.stdout.write(data)
})

rl.on('line', function (line) {
client.write(line)
rl.setPrompt('>', 2)
rl.prompt()
})
91 changes: 91 additions & 0 deletions examples/chat.js
@@ -0,0 +1,91 @@
var drama = require('../')
var sys = drama('sys')
var $ = sys.actor.bind(sys)

var channels = []

var Client = function (socket) {
var nick

var Enter = function () {
socket.write('\nEnter your nickname: ')
return function (newNick) {
if (newNick && newNick.length > 2) {
nick = newNick
socket.write('Welcome, ' + nick + '!\n')
socket.write('To enter the main room type: /join main\n')
return Lobby
}
else {
socket.write('Not a valid nickname (<2 chars)\n')
return Enter()
}
}
}

var Lobby = {
join: function (name) {
if (!~channels.indexOf(name)) {
$(name, Channel).init(name)
channels.push(name)
}
var channel = 'sys@' + name
this.send('join', nick).to(channel)
return {
msg: function (msg) {
this.send('msg', msg, nick).to(channel)
}
, echo: function (msg) {
socket.write(msg + '\n')
}
, part: function (msg) {
this.send('part', msg || 'Bye.', nick).to(channel)
this.echo('Leaving ' + name)
return Lobby
}
, _: function () {
this.echo("I don't understand: " + this.originalMessage)
}
}
}
, _: function () {
socket.write('You have to join a channel before you can take action.\n')
}
}
return Enter()
}

var Channel = function (name) {
var clients = {}
return {
join: function (nick) {
clients[nick] = this.sender
this.broadcast(nick + ' has joined the room.')
}
, part: function (msg, nick) {
delete clients[nick]
this.broadcast(nick + ' has left the room: ' + msg)
}
, msg: function (msg, nick) {
this.broadcast(nick + ': ' + msg, nick)
}
, broadcast: function (msg, nick) {
for (var k in clients) {
if (k !== nick) clients[k].tell('echo', msg)
}
}
}
}

var net = require('net')
net.createServer(function (socket) {
socket.uid = (Math.random() * 100000).toString(36)
var client = $(socket.uid, Client).init(socket)
socket.setEncoding('utf8')
socket.on('data', function (data) {
if (data[0] === '/') {
client.tell(data.split(' ')[0].substr(1), data.split(' ').slice(1).join(' '))
}
else client.tell('msg', data)
})
}).listen(6886)
75 changes: 75 additions & 0 deletions examples/distributed-db.js
@@ -0,0 +1,75 @@
var drama = require('../')
var sys = drama('sys')
var nextTick = require('nexttick')

var Db = function (isChild) {
var atomic = require('atomic')
var crypto = require('crypto')

function hash (key) {
return crypto.createHash('sha1').update(key).digest('hex')
}

var data = {}
var lock = atomic()
var workers = {}
var w = 0

var Child = {
get: function (key) {
var reply = this.reply.bind(this)
lock(key, function (done) {
setTimeout(function () { // simulate an async db get function
reply(data[key])
done()
}, 50)
})
}
, set: function (key, val) {
lock(key, function (done) {
setTimeout(function () { // simulate an async db set function
data[key] = val
done()
}, 300)
})
}
}

var Router = {
get: function (key) {
var reply = this.reply.bind(this)
workers[hash(key).substr(0, 1)].get(key, function (val) {
reply(val, key)
})
}
, set: function (key, val) {
workers[hash(key).substr(0, 1)].set(key, val)
}
}

var Master = function () {
;'abcdefghijklmnopqrstuvwxyz0123456789'.split('').forEach(function (l) {
var worker = sys.fork('remote-' + l)
.actor('worker-' + l, Db)
.init(true)
.pick('?get', 'set')
workers[l] = worker
})
return Router
}

if (isChild) return Child
else return Master
}

var db = sys.actor('db', Db).init().init().pick('?get', 'set')

var x = 0, y = 0
nextTick.while(function () { return ++y < 100 }, function () {
for (var x = 0; x < 100; x++) {
db.set('foo-' + y, 'bar-' + x)
db.get('foo-' + y, function (val, key) {
console.log('%s: %s', key, val)
})
}
})
87 changes: 87 additions & 0 deletions examples/distributed-pi.js
@@ -0,0 +1,87 @@
/**
* Port of the Akka first tutorial
* Distributed PI calculator
*/

var drama = require('../')
var sys = drama('sys')
var $ = sys.actor.bind(sys)

var PiWorker = function () {
var it = 0
return {
calculatePiFor: function (m) {
var acc = 0.0
for (var i = m.start; i < m.start + m.elements; i++) {
acc += 4.0 * (1 - (i % 2) * 2) / (2 * i + 1)
}
it += m.elements
this.reply(acc)
}
, getPiPiece: function (needed) {
var ctx = this
var self = this.self
var piPiece = 0
var count = needed.pieces.length
if (!count) ctx.reply(0)
else {
needed.pieces.forEach(function (piece) {
self.actor().ask(self, 'calculatePiFor', { start: piece, elements: needed.elements }, function (result) {
piPiece += result
--count || ctx.reply(piPiece)
})
})
}
}
}
}

var piCalculator = sys.actor('pi calculator', function (opts) {
var numOfWorkers = opts.workers
var workers = []
var threads = new Array(opts.threads)
for (var t = 0; t < opts.threads; t++) {
threads[t] = sys.fork('thread-' + t)
for (var w = 0, actor; w < numOfWorkers; w++) {
actor = threads[t].actor('pi-t' + t + '-w' + w, PiWorker) //, function (actor) {
actor.init()
workers.push(actor)
}
}
var totalWorkers = workers.length
var startTime = Date.now()
return {
calculate: function (elements) {
var pi = 0
var nrOfResults = 0
var count = elements
var ctx = this

var c = 0
var w = 0
var needed = {}
for (var i = 0; i < count; i++) {
if (++w >= totalWorkers) w = 0
needed[w] = needed[w] || []
needed[w].push(i * elements)
}

count = totalWorkers
for (var w in needed) {
$().ask(workers[w], 'getPiPiece', {
elements: elements
, pieces: needed[w] }, function (result) {
pi += result
--count || ctx.reply(pi, Date.now() - startTime)
})
}
}
}
})

piCalculator.init({ threads: 3, workers: 2 })
$().ask(piCalculator, 'calculate', 10000, function (pi, time) {
console.log('Pi approximation:', pi)
console.log('Time to finish:', time)
})

0 comments on commit 8243cba

Please sign in to comment.