Friday, December 14, 2007

Unadulterated Expurgation!

Alright, so, occasionally I post something funny that happened recently. Yesterday I received a spam company broadcast email from an anonymous customer of mine. You know who you are! :)

Team Anonymous Company,

In each office Anonymous Company employees have inhabited, many attempts have been made to keep our refrigerators clean and sanitary. Keeping clean refrigerators only works if we all participate – yet despite the best team players on the planet, we’ve fallen short of the goal. Common comments run the gamut from, "I’ll never put 'my' lunch in there," to the more lyrical, "There’s a fungus among us!"

As a result of this circumstance, the many must suffer the failings of a few – meaning:

Every Friday afternoon at 4:00 p.m. our Sergeant of Sanitation, will remove and dispose of everything from every refrigerator – as in: any one thing, each thing, the sum of all things, collectively all, the aggregate of all, anything at all, the totality of all within, including or comprehending all things, a comprehensive sweep of any and all things, whatever it is, whatever is left, nothing will be left, the sum total of all things, the Full Monty, the whole enchilada (frozen and unfrozen), the whole shebang. In short, every Friday at 4:00 p.m. all the refrigerators will experience an unadulterated expurgation!

Many thanks in advance for your cooperation and understanding,

The Management

Good thing I don't use the fridge...

Tuesday, December 11, 2007

Introduction to fbasync: an Asynchronous Facebook Library (Part 1)

I'd like to start off by saying asynchronous programming is easy. Building asynchronous frameworks is hard, but using them is easy. Everybody doing programming in AJAX and Flash do it every day without thinking about it. There's no reason us C# .NET programmers can't do the same!

This first article about fbasync is going to show how to use it. Your 12 year old script kiddie nephew could do it, I promise. Then later on in the series we'll dive into how the library is implemented and see if we can forever scare him away from a programming career.

Those who know me well (or have read my blog for a while) know I'm a proponent of asynchronous patterns. Why? Well, there are a lot of reasons. I've mentioned why 1 2 3 4 5 6 times. To sum it up, the two primary reasons for using asynchronous patterns are to gain better vertical scalability (to do more with one piece of hardware) and provide a better user experience. When it's as easy as writing synchronous code, I say why not? Using asynchronous patterns in your code is especially important when it comes to communicating with a web service outside of your network (like Facebook). When you don't know how long your service calls are going to take, you simply can't expect to scale up an application without going asynchronous!

In a previous article entitled Simpler Isn't Always Better I spent a lot of time bashing the event based asynchronous pattern. Well, I take it back (some of it). It turns out in the context of ASP.NET and Winforms, the event based pattern is very nice indeed. While I implemented both the event based and IAsyncResult pattern in fbasync, I'd recommend most people use the event based interface. This is what we'll be looking at today.

What you've been waiting for

Ok, enough blabbering! The fbasync library is available on CodePlex. You can download the bits right now and follow along at home. The library comes with a simple example that allows you to browse the photo albums uploaded by you and your friends. In this sample we get all the albums and related cover photos of the requested user, and the list of friends for the authenticated user on the server through asynchronous requests. Let's get it setup and take a deeper look!

  1. Make sure you have Visual Studio 2008 installed. It's required.
  2. Download and extract the zip file somewhere interesting.
  3. Open the fbasync.sln file.

Now that you have the web site loaded just make sure your web server is setup to run on port 30912 and the virtual path is "/" (in your project properties). This is the way the sample application is configured in Facebook. If you have your own application (API Key/Secret) you want to test this with, edit the web.config.

Project Setup

With this setup, you'll be able to run the fbasync.web application, add it through Facebook, and experiment with it in the Facebook iframe.

Setting up your page

Getting your Facebook application setup and working is outside the scope of this article. Check out the Facebook Developer site for introduction information. Once you decide you want a Facebook canvas page with an iframe application, return here. :)

It's quite easy to get your page connected to Facebook. Simply inherit from the fbasync.webcomponents.FacebookPage. Once we hit the 1.0 release of the library, you'll also be able to drag a component onto an existing page without messing with your inheritance hierarchy. For now, here's how it looks.

Once you've got your page setup, using the library is simple. The base page takes care of making sure the request is authenticated and gets a Facebook session based on the authentication token provided to your application. Before we go any further, make sure you set the Async directive on your page so fbasync can do things asynchronously. How async pages work was explained well by Fritz Onion in an Extreme ASP.NET article last year.

Now that you have setup the page to process requests asynchronously, fbasync can best do its magic. Override the OnFacebookSessionCreated method in your page, or add a handler for the FacebookSessionCreated event. This will be raised when fbasync has acquired a session from Facebook, using either the authentication token provided in the Facebook iframe or after a redirect through the Facebook login page. The Facebook authentication process is covered in depth in the Facebook Developer Authentication Overview. The good news is, you probably don't need to know! Fbasync will handle the most common situation for you.

Now that you've got a Facebook session, it's time to do something interesting. Let's take a look at the code in our AlbumBrowse page.

There are two interesting bits in this code (they're in giant red boxes – hard to miss). First, we setup event handlers for the *Completed events we are interested in. Second, we call the *Async methods. Notice in this example we're doing three simultaneous asynchronous requests. That's important. These requests will happen simultaneously. That, is the power of asynchronous code in action. Imagine each call takes 250ms to complete. With three calls, that's nearly 750ms of time just waiting around for Facebook. Using the asynchronous pages we end up waiting only as long as it takes for the longest running call to complete!

At this point astute readers will point out that I am in fact lying. In the default configuration of .NET, you will only ever make two simultaneous calls to a given remote IP. This is built-in to the WebRequest class. Lucky for us, we can change it in the web.config like so!

<add address="*" maxconnection="100" />

With this configuration entry in place we can now make up to 100 simultaneous outgoing requests to the same IP address. Much better. Even if you're not using fbasync, you should make a similar change.

Back to the example. Making asynchronous requests is interesting, but requests don't usually do us much good without dealing with the results. The list of friends on the left side of the application is generated using a ListView control and some simple codebehind. I'm going to leave the HTML markup out of it, as its dirt simple. Have a look at the code if interested. Here's the codebehind that renders the user list.

Surprised? There are no red highlights. There's nothing very interesting here. If you haven't seen many lambda functions or LINQ before, the OrderBy and Single methods might look funny, but the code here is pretty darn simple. We remove our event handler (not doing this is prone to memory leaks so I always do it). Then we bind the ListView to the Result on the event argument. And finally we put the friends name who's albums we are viewing in the placeholder. Yup, that's it. No thread locking, no monitor, no mutex, no volatiles, no interlocks, none of that scary threading stuff at all.

Let's review what happened. Our page loaded. The fbasync library got a session from Facebook (or pulled one out of the cache/session – more on this in a future post). Our GetUsersAsync method was kicked off (among others). It finished, in a background thread, and raised the GetUsersCompleted event back in the context of our ASP.NET request. We took the results and bound them to a list view. No muss, no fuss. No threading required. My grandmother could do it – well, if she knew ASP.NET.

This is getting too long already. I'm starting to feel like I'm writing a Scott Guthrie article. Coming soon: we'll wrap up the rest of the example code, and move onto how the *Async methods are implemented. I'd love to get some more contributors on this project. So, if you're interested, give me a buzz or head on over to CodePlex and get crackin! Feedback is welcome and encouraged.

Thursday, December 6, 2007

Geeks With Kids

I was just IMing with a good geek friend of mine. This is what happens when you give paranoid geeks kids (names removed for obvious reasons).

(5:08:06 PM) Geek Friend: i'm outta here, i gotta go home,
looks like the kids are fighting
(5:08:15 PM) Geek Friend: no adult supervision
(5:08:20 PM) Me: haha
(5:08:26 PM) Me: you watching them on camera?
(5:08:27 PM) Geek Friend: i'm so glad my parents didn't have
video cameras all over my house when i was their age
(5:08:30 PM) Me: hahahha
(5:08:34 PM) Geek Friend: watching, listening
(5:08:39 PM) Me: and they know?
(5:08:42 PM) Geek Friend: going to go ground two of them
(5:08:44 PM) Geek Friend: yeah, they know
(5:08:47 PM) Me: wow
(5:08:56 PM) Me: and they still act up
(5:08:56 PM) Me: crazy
(5:09:04 PM) Geek Friend: kid0 was straight up punching kid1
just now
(5:09:08 PM) Geek Friend: elbowed him in the face
(5:09:17 PM) Geek Friend: tried to gouge his eyes with her
(5:09:17 PM) Me: nice
(5:09:19 PM) Geek Friend: crazy fight
(5:09:25 PM) Geek Friend: never seen them do anything like
that before
(5:09:30 PM) Me: well get goin!
(5:09:33 PM) Me: before one of them dies
(5:09:38 PM) Geek Friend: i called them
(5:09:42 PM) Me: ah
(5:09:43 PM) Geek Friend: they're sitting in the corners
of the room
(5:09:46 PM) Me: lol
(5:09:47 PM) Geek Friend: and can't move
(5:10:05 PM) Geek Friend: i turned on the alarm, i told
them if they move, the alarm will go off and the police
will come
(5:10:21 PM) Geek Friend: (not true though) just a really
loud noise until i shut it off
(5:10:49 PM) Geek Friend: later

Wednesday, December 5, 2007

Async Facebook Library Teaser

I've been trolling the Facebook Developer Forums recently and talking with other developers. I've also been reading a lot and trying to get a feel for what people might want out of the asynchronous Facebook library I've been (slowly) building. In particular, I've been participating in this thread about Facebook scalability issues. I thought I would share my most recent post as a bit of a teaser as what's to come. Here it is, reproduced:

tomten wrote:

...but it was way overkill for what I've done. ...

This is one myth I want to squash. Async stuff isn't hard. I promise. smile Let's take your page loading example, and make it asynchronous. I put in code comments for a "facebook is hammered" timing. Let's say every call takes you 250ms. That means that page will spend roughly one second waiting for facebook.

Page_Load {
GetSession(); // Call to Facebook 250ms
// Make calls to Facebook
GetFriends(); // Call to Facebook 250ms
UpdateProfile(); // Call to Facebook 250ms
SendNotification(); // Call to Facebook 250ms

Now, let's make this Async. It would become (roughly -- there is also a "Completed" event handler you'd setup for the items you cared about):

Page_Load {

Page_PreRenderCompelete {

This time, with the async calls in the server, we spend 0 time waiting for facebook. Just like in client side AJAX, we get a callback when the calls were complete! And, instead of a full second for our page to finish processing, it only takes 250ms, as all the facebook calls happen simultaneously (yeah I know this is a faulty assumption, but it is usually pretty close).

In addition to the shorter page lifecycle (250ms instead of 1 second) we are not tying up a processing thread (of which there is a small finite number). During that time we are waiting for facebook to finish our API calls, the engine happily processes more requests on the thread that originally kicked off processing of our page.

A shorter lifecycle is important, not only for throughput, but also for memory consumption and garbage collection efficiency. Because the objects do not live for as long, they will be garbage collected more quickly and your application will spend less time doing garbage collection.

Ok, so that's a bit of a spoiler, but, I hope it helps.

Hopefully some time this week I'll clean up the library enough that I think it's worthy to be posted publicly. I spent last night refactoring a bit and removing a lot of "who wrote this crap" code. :)

As a bit of an aside, I was excited to see the team working on the "almsot official" Microsoft .NET library for Facebook released an asynchronous version of the FacebookService. I thought maybe I wouldn't have to write one myself. However, after looking at the code, I was very disappointed by the fake asynchronous support that's in the Facebook Developer Toolkit. It made me shed a tear. I really wish they'd put a disclaimer up: "This AsyncFacebookService is not really asynchronous I/O. It will only make things worse by tying up an additional threadpool thread waiting for the delegate to the synchronous method to return.".

About the Author

Wow, you made it to the bottom! That means we're destined to be life long friends. Follow Me on Twitter.

I am an entrepreneur and hacker. I'm a Cofounder at RealCrowd. Most recently I was CTO at Hive7, a social gaming startup that sold to Playdom and then Disney. These are my stories.

You can find far too much information about me on linkedin: No, I'm not interested in an amazing Paradox DBA role in the Antarctic with an excellent culture!