Crowds Machine, Day 1

I’ve been working on Crowds Machine for a while, starting this an idea long ago and running it for my personal use for about three years now, but only recently I took some time to make it publicly usable – the first users I don’t personally know showed up only in the last 24 hours, following its mention in Waxy.org Links.

Here’s what this first public day looks like in traffic:

Keeping in mind it’s Christmas, and the site was down for a while till I fixed up the server, I’m pretty happy with that. But the real surprise is here:

There were less than 10 crowds in the system, so this means 1 in every 4 new visitors created a crowd. That’s pretty incredible. Maybe the holiday timing helped here. Maybe allowing users to log in with their Google accounts. Having to process 12,274 feeds a day might prove a bit of a challenge though…

I always assumed there’s a high entry barrier for CM users since they have to load in quite a few feeds to make it useful. Visitors so far seem to have no issues with that, most just importing their feeds list via OPML. Obviously these are not the typical Web users, but that’s ok. Crowds Machine isn’t meant to be mainstream – that’s the whole point of it.

HelloWorldChat In Stanford Peace Dot Directory

HelloWorld Chat is a project I’ve been working on with my friend and designer extraordinaire Aviva. Basically it’s a “chat online with a stranger” site like Omegle & co, but we try to match between users from different countries (based on their IP address). Once we reach a certain level of traffic, we could start adding more sophisticated matching rules and connect between users of specific nations, based on current world events and so on.

We haven’t done much in way of publicizing the site, so it was great to be accepted into Stanford’s Peace Dot directory. Peace Dot only adds one organization per day to the directory, and we’re excited to finally get in :) They even do a little welcome video for each site, here’s Standord’s BJ Fogg welcoming us:

Thanks, Peace Dot!

Technically, HelloWorld is a simple Google App Engine based chat, written in Python. The focus was less on the chat code and more on making the application easy to customize and adapt for various sites. The look can be completely changed by editing two HTML files, and being App Engine based makes deployment extremely simple and cheap.

Sites built on top of HelloWorld might be used to foster dialog between sides in a conflict, aid in reconciliation phases, or help people going through their own struggle with a disease or addiction talk with others in the same situation. The anonymity allows users to speak frankly where it may often be difficult or dangerous to do so, and hopefully some may later move on to talk via Skype or Email – our goal is to be the easily accessed and risk free gateway to a dialog.

While forums and multi-user chats have important roles, a one to one conversation has a unique value of its own. Talking one to one makes slogans and cliches a lot harder to hide behind. It is a lesson I learned myself in the summer of 2006, when I happened into an IM conversation with a Lebanese person while both our parents’ towns were under fire by the other side. That experience was the inspiration for HelloWorld, I hope this tool would allow many more such conversations to take place.

The Long Poll: AJAX Push(like) Chat with Comet

Recently I’ve been working on an AJAX based chat application (in development..). The obvious way to do it is send an XMLHttpRequest every few seconds to check for new messages. Unless it’s a particularly animated conversation most requests won’t return any new content, so I added a simple Conditional-GET like system based on the chat’s text size. Here’s the client side implementation:

function refresh_chat() {
	$.ajax({
	  	url: "/chat",
	   	data: "format=xhr&chat_id={{chat_id}}&cur_len=" + chat_content.length,
		  complete: function(xhr){					
				if (xhr.status == 200) render_chat(xhr.responseText);
				setTimeout("refresh_chat()", 5000)
		  }
	 });	
}

And the server code that handles it:

cur_len = self.request.get("cur_len", 0)
if len(chat.content) == int(cur_len):
	self.error(304) # return 304 Not Modified
else:
	self.response.out.write(chat.content) # return new content

That’s basically the standard approach. Pretty simple, works ok (could be optimized a bit, for example return only the actual new content etc). It’s not exactly an elegant design, though. Trying to use HTTP, designed as a Pull protocol, for an application that requires Push results creates this system of frequent server requests with empty responses, kind of like the “Are we there yet?” conversations with kids on long road trips.

Jack Moffitt’s JSConf talk introduced me to the concept of Long Polling, aka Comet or (with a lot added) BOSH, as a way to simulate HTTP Push. Rather than have the client sending a lot of short, frequent requests and the server responding to each as fast as possible, long polling turns it around: the server holds the requests as long as it can, returning a response only when it has new data or a timeout limit was hit. So, instead of sending request every 3 seconds, for example, you can send one every 30 seconds.

Client side code remains almost the same:

function refresh_chat() {
	$.ajax({
	  	url: "/chat",
	   	data: "format=xhr&chat_id={{chat_id}}&cur_len=" + chat_content.length,
		  complete: function(xhr){					
				if (xhr.status == 200) render_chat(xhr.responseText);
				setTimeout("refresh_chat()", 1000);
		  }
	 });
}

But on the server side, there’s a bit of new logic to keep checking for new content while the server holds the response:

cur_len = self.request.get("cur_len", 0)
end_by = int(time.time()) + 30

while int(time.time()) < end_by:
	if len(chat.content) != int(cur_len):
		return self.response.out.write(chat.content) # return new content
 	
	time.sleep(1)

self.error(304) # return 304 Not Modified

If you have any experience building web applications, you’ve spent a lot of effort making sure servers respond quickly to requests. Delaying the response is counter-intuitive, which in itself makes Comet useful to know, if only for its new perspective. However, this also makes production use a bit complicated, since most web server stacks are optimized for maximum requests/second rather than long concurrent requests. Content-rich sites often use separate servers for big media content for this reason, and Comet also has its own server (er “HTTP-based event routing bus”) in Cometd.

FeedVolley: Messages From Iran

I just put up a quick hack I made with FeedVolley (more about FV here), that aggregates Twitter (and other media) feeds coming from inside Iran: Messages From Iran

I don’t know about news value, but it’s pretty cool to be able to refresh that page now and then and get a snapshot of the current mood and happenings, in these possibly historic times there.

It was also cool to find another use for FeedVolley, which I neglected a bit recently ;) I added some page caching on top of the existing feed caching, to allow it to handle some traffic (Slicehost’s 256MB slices seem to start sending swap alerts as soon as traffic rises above negligible). The sources are basically the ones listed here, with a few additional ones I’m trying to find. In fact, if you really want to keep a close watch on what’s going on, you may want to watch the FriendFeed stream – the FeedVolley page is really just an HTML skin to make the feed look a little nicer (hopefully).

(Favorite tweet so far: “@jonobacon IRC is blocked. Tell our regards to Ubuntu Global Jam from Iran. I’m twitting the #iranElection story from a Kubuntu machine :)“. Makes me think of starting to use Twitter again..)

41411 Rmmbr: Text Your Inbox

rmmbr is a service I built for myself and recently opened for general use. I wanted a way to send myself notes about things I need to do, items I want to research etc. If just write this on a scrap of paper I usually seem to forget about it, so using Textmarks‘ web-SMS gateway (which is pretty nice btw – reliable and easy to interface with) I wrote a little web app that lets me text these notes to my inbox.

The examples on rmmbr’s home page are pretty much how I use it – I come across some term I want to research or am reminded of something I need to do and send an text message like rmmbr <whatever> to 41411. When I get back home an email is waiting in my Gmail inbox with the text sent, a Google search link for it, and if it’s an address or a date Gmail might also attach its “map this” or “add to calendar” links as well.

To start using it, you need to let rmmbr connect your phone # with your email address by texting rmmbr signup <your@email> to 41411. You’ll get a confirmation email and can start sending yourself messages. Just remember to always start the message with “rmmbr” – it still gets me sometimes..

I don’t know how useful it would be for anyone with an iPhone or a Blackberry, but if you’re like me and prefer to keep your cellphones small, cheap and low maintenance, you might find this a useful solution for your text-to-inbox needs. Enjoy :)

[Update: formerly rmbr, the app/sms code is now rmmbr, to prevent confusion with rmbr.com – which is a different product, not related to rmmbr in any way]