3. Why not Node.js
• We never heard of Node.js at the time (2009)
and were experienced in Ruby
• Lots of server-side computations / statistics /
map-reduce (blocking the node event-loop)
• Typical dashboard (view on a database)
• Not that many concurrent users
• No need for open connections
Yes, I would use Ruby again
Saturday, March 31, 12
4. Pivot: Penny auctions
• Swoopo and Bigdeal (real goods)
• Newcope a platform for pay-per-bid
auction games for virtual goods
Saturday, March 31, 12
5. Flash game platform
http://newcope-heyzap.heroku.com/home
Saturday, March 31, 12
6. • The Broth: BarnBuddy
• Facebook app
• Similar to Farmville
• Over 1 million active users per month
Saturday, March 31, 12
7. Challenge
• Build iframe / facebook app solution
• Have the auctions as realtime as possible
• Long polling (later websockets) vs pulling
• Lots of users with open connections
• Scalable
Saturday, March 31, 12
8. Languages considered
• Ruby (Eventmachine, no Goliath yet)
• JRuby
• Scala (Twitter had just moved from ruby)
• Erlang
• Javascript Node.js
Saturday, March 31, 12
10. Node.js experiences
• Functional programming
• Javascript for both client and server
• Very good performance (30k users the first day)
• Node v0.1.25 and no packet manager (npm)
• MySQL with DBSlayer (later Mongodb)
• Nginx to serve static files
• Easy to setup/deploy on EC2 (upstart deamon)
• Everything async (annoying to test)
• Fun!
Yes, I would use Node.js again
Saturday, March 31, 12
11. Auction.prototype.startTimer = function() {
var self = this;
if (this.timer) clearTimeout(this.timer);
this.emit("start");
this.timer = setTimeout(function() {
self.emit("end");
}, self.timeLeft() * 1000);
}
Auction.prototype.bid = function(user) {
var self = this;
return function (callback, errback) {
if (user.bid_count > 0 && self.status() === "running") {
user.bid_count -= 1;
dbUser.updateUser(user.id, {'bid_count': user.bid_count})(function(result){
if (self.timeLeft() < self.bidTimeDelta) {
self.setTime(me.bidTimeDelta);
};
self.price += self.bidPriceDelta;
var bid = { user: user, ts: new Date() }
self.bids.push(bid);
self.bidCount++;
callback(self);
}, function(error) {
user.bid_count += 1;
errback("Could not update new bid count");
})
} else {
errback("Bid could not be placed");
}
};
}
Saturday, March 31, 12
12. // continuation style
var bid = function(user) {
return function (callback, errback) {
if (!user) return errback("No user")
callback(user)
}
}
bid(user)(function(result){
console.log(result)
}, function(error) {
console.log(error)
})
Saturday, March 31, 12
13. // promise style
var bid = function(user) {
var promise = new Promise()
if (!user) {
promise.emitError("No user")
} else {
promise.emitSuccess(user)
}
return promise
}
var promise = bid(user)
promise.addErrback(function(error){
console.log(error)
})
promise.addCallback(function(result) {
console.log(result)
})
Saturday, March 31, 12
14. • // callback style
var bid = function(user, callback) {
if (!user) return callback("No user")
callback(null, user);
}
bid(user, function(err, result){
if (err) console.log(err)
console.log(result)
})
Saturday, March 31, 12
15. • Bottlenose is the smartest social media
dashboard.
• Helping you manage the information overload
on streams like twitter and Facebook
• Bottlenose analyzes and filters messages using
NLP and clustering techniques
• Beta launched December 2011
http://bottlenose.com
Saturday, March 31, 12
17. Why Node.js?
• It began (2009) with NLP in javascript, run
it both on the client and the server
• Fat client and lean server
• Realtime stream updates
• Lots of users (with open connections)
• Alternatives?
Yes, I would use Node.js again
Saturday, March 31, 12
18. Summary:
When to use Node?
• When you are building more of an app than a
website and require lots of open connections to
the server
• When you want your users to get data in
realtime (chat, streams)
• When you have to serve lots of requests that do
not take too many cpu cycles (blocking the loop)
• When you like to work with Javascript all the way
Saturday, March 31, 12