Howdy!

Welcome to my blog where I write about software development, cycling, and other random nonsense. This is not the only place I write, you can find more words I typed on the Buoyant Data blog, Scribd tech blog, and GitHub.

Upgraded to Drupal 6.0

I'm certain that this doesn't interest anybody in the slightest, but I just upgraded the entire site to Drupal 6.0.

Unfortunately some modules like jstools, or the Adsense module haven't been ported over yet so I've just gone ahead and disabled them for now until everything gets back to normal in the land of Drupal.

I've been very pleased with Drupal as a CMS, and am really look forward to them tightening up Drupal 6 further on in the release cycle, but right now everything is looking promising enough to jump ship from Drupal 5.xx.
Read more →

Facebook's Bleeding Edge

For the past couple weeks I've been living dangerously, as some people know I live in the Tenderloin District, but that's not what I mean when I say "living dangerously." In my constant quest to squeeze as much performance out of Top Friends as possible, I've been evaluating the latest and greatest stuff that Facebook has to offer developers. In addition to the usual adding of features, tuning virality, and general application upkeep, I've been exploring mixes of FBML, FBJS, Mock AJAX, preload FQL, and batched queries all as a means to improve how fast Top Friends is for our users. I've been saying for months that it's exceptionally important to keep up with all of Facebook's changes, for better or for worse, and sometimes they throw out gems like preload FQL that will help shape new and interesting ways you can utilize Facebook's data inside your application.

The Feature
The first obvious thing that I wanted to apply preload FQL to, was a new feature we've pushed out called "Top Friends News" which aggregates "what's going on" with your Top Friends.


It was very important to incorporate data from Facebook as well as our own data into the feature to make sure the page was as rich and interesting to the user as possible. Unfortunately, executing queries to fetch birthdays, recently uploaded photos, statuses, etc, are prohibitively expensive if you just run them as standard FQL queries. Even as preload FQL queries they are relatively expensive when hitting a cold cache. To ensure the page was as fast as possible using preload FQL we ran a lot of tests with various iterations of the queries and tuned everything as much as possible. I could yak endlessly on all the cool stuff we've done in this specific case to squeeze every last drop of performance out of the News page, but I'll cite the numbers and get to the nitty-gritty right away. Before we released the feature I tried the page with no preload FQL queries, and the necessary Facebook data was procured through painfully slow standard FQL queries. Executing these queries on the page made the "Top Friends News" page the slowest page Slide served up to Facebook, clocking in at about 2.5-3.0s. Simply unacceptable. After a long day of tuning and implementing all the queries to run as preloaded FQL queries, the "Top Friends News" page became the fastest page Slide serves up to Facebook at around 0.5s a pop.

Although preload FQL is technically still a "beta feature" according to the wiki, we've implemented it in an application that has millions of users daily; in my opinion preload FQL is "Google-beta" quality (which means, it's solid) as opposed to "Microsoft-beta" quality (which means, it sucks).

Using preload FQL
If you grab the latest PHP client library from Facebook, support for preload FQL is already baked in via the admin.setAppProperties API call. Actually calling the API call is relatively painless, it's something to do pre-push instead of "live" like normal FQL queries. Once you set your application's preload FQL rules, the results are simply posted to the FBML page matching the "pattern" you specified when you set the FQL rules to begin with (read the wiki page for more), when the results are POSTed however, they'll be formatted in JSON, similar to a regular FQL query if you specify ResponseType.JSON. This does mean however you should be using FBML for your application page to take advantage of preload FQL, it's possible to use iframe pages and preload FQL through a clever mix of memcached and <fb:iframe/>, but I won't go into that here.

Performance Concerns
While moving to preload FQL means you lessen the chance that Facebook times out while trying to load your FBML page, if you structure your queries incorrectly you merely shuffle the lag-time for the user, you won't eliminate it. After working with some Facebook engineers on profiling the performance of preload FQL, they've added another parameter that will be posted into your FBML page that you can use to guage the time it took your preload FQL queries to execute. If you start logging fb_sig_time alongside fb_sig_preload_fql_timestamp you can measure the difference between when Facebook started to process your preload FQL rules (fb_sig_preload_fql_timestamp), and when Facebook called your server for the page (fb_sig_time).

Mixing and matching FBJS, FBML and preload FQL rules in your pages can allow you to create blistering-fast pages that are as rich as possible for your users, while allowing you do to more with less (server-wise) than you could ever do before. Add in a bit of the Data Store API and you'll have pages that rival Facebook's own in terms of speed at prices that rival Amazon's S3 in terms of overall cost. In general Facebook is an engineering organization with lots of smart people working for them, and most of those smart people (that I've met anyways) are working to make the Facebook Platform even better than it is now, meaning the time you put into exploring new parts of the platform will most definitely have been worth it after you start to use some of Facebook's more "bleeding edge" features that are designed to make your life easier, not harder.

2008 is going to be an interesting year.
Read more →

Speaking at Graphing Social Patterns

Coming up in the first week of March you'll be able to find me doing one of my three favorite things (right behind, writing code and sleeping), I'll be talking, in front of people, about Facebook, Bebo and "social applications." If you are one of the four people that have gone on record has having actually subscribed to my RSS feed, you might know that I spoke at something called "Graphing Social" in the past, but this time I'm speaking at "Graphing Social Patterns West" which will be occurring in parallel to O'Reilly's "ETech (Emerging Technology) Conference)" in San Diego March 3rd and 4th.

I'll be talking briefly, in front of people, on tuesday March 4th about during a joint session on "Social App Development 101: Elements of Style," where I'll be discussing some of keystone pieces of building an application that "pops" on Facebook and Bebo, and designing for portability, etc. My session is going to be brief, so I will most likely be employing my crouching-ninja-presentation technique, where the slides rotate every quarter-second at such a fast pace that the content becomes melded into my audiences' subconscious. It's been rumored to cause brain hemorrhaging, but that's nothing but an urban legend, I promise.

In general the entire event should be lots of fun; I'm looking forward to schmoozing with the speakers lined up for the event, as well the time-honored tradition at O'Reilly conferences, playing a good old game of "Find Tim and tickle him until he pees himself."

Overall the combination of GSP West and ETech looks like it's going to make for an interesting couple of days in San Diego, go ahead and register now to make sure you can get in.
Read more →

More Tips for Beginning Facebook Developers

I don't feel quite as awesome as I did last summer when I tell people that I "develop facebook applications." Despite personally being really happy with my applications, I get the feeling that users now perceive facebook apps as spammy, poorly designed, and pointless. Sure, there are some applications that are knowingly like this (and they are probably making some quick cash), but to many new developers they just don't know any better.

The points in Tyler's post, as well as the ones below, will help new developers start on the right track and then we can all feel awesome again to be a facebook application developer. I am staying away from saying "don't spam" because that is a topic in need of it's own post.

Just because you haven't seen it doesn't mean it isn't there. Do a little research on existing applications with the same idea before you start development. This will help you decide whether you should pick up their best features and improve on them, or just scrap your idea altogether. There is definitely room for similar applications, but don't build a product if you can't make it better.

She may be hot, but she has no brain. Looks are great, but make sure you have a well built application to support your idea. Users love to uninstall when they see error messages.

Keep improving and adding features to your applications based on user requests, they really know best. I may be crazy, but I like to read and respond to nearly every (positive) comment and suggestion on Free Gifts boards.

Tyler pointed out that the one year mark is approaching, and the amount of progress the developer community has made is really amazing. Over the next few months there are a few things I really hope to see: inter-application collaboration, more functional user interfaces, and a decline of "one timer" apps (quizzes, etc).
Read more →

Trying out AdSense

In a vain effort to try to monetize all of the incredibly witty things that I do and say on this ridiculous excuse for a blog, I've started experimenting with Google AdSense mixed in with some of the content on the site. They don't insert themselves into the RSS feeds (as far as I know) and they only show up for anonymous users to the site so I'm willing to bet that the majority of where my traffic actually goes won't be affected.

Unfortunately, since Slide has infected me with this weird disease where I obsessively watch numbers, I'll most likely be obsessively watching a large number of zeroes in the coming weeks. That said, you could totally screw with me by clicking around on a lot of the advertisements...seriously, that would totally irritate me...you should try it.
Read more →

Tips for beginning Facebook developers.

I am starting to see more and more novice developers on the Facebook forums as well as the IRC channel asking fewer and fewer "development" questions and more and more "product" questions. I find this incredibly interesting because it means one of two things: either everybody has figured out how to use the Facebook platform or an increasing number of people are putting the proverbial cart before the horse when it comes to developing Facebook applications.

Call me cynical about the first option, but I find it highly unlikely that everybody figured out how to use the Facebook Platform; despite its low entry barrier many people are over-thinking it or simply trying to develop a Facebook application before they figure out how to build a web application in general.

The second option is far more likely, Facebook applications have reached such a level of ubiquity that "everybody and their mother" wants to write a Facebook application these days. Right now at a small consulting firm in Omaha, Nebraska some middle manager is asking his lead developer if the firm can reinvigorate their collaborative synergies and utilize the social graph to further meet their clients needs.

Facebook is the new Windows, and the Facebook Platform is the new Visual Basic and I feel as if there is a burden on "us" (the existing "top developers" on the platform) to start to cultivate a community that will encourage stylish, functional and ultimately useful applications on the Facebook platform, to ensure that there will never be a "Facebook 98" or a "Facebook ME".

Here's a couple of the best tips I can offer, and maybe Zach (developer of Free Gifts) can help expand.

      Learn by example: Currently Slide has many of the largest applications on the platform, and we've worked extremely hard tuning and tweaking our apps and understanding our userbase. When thinking about developing your application, it certainly won't hurt to check out some of the existing apps that have succeeded on the platform. Stand on the shoulders of others who have spent far more time researching and testing what works and what doesn't work on the platform than you'll be able to spend.
      Learn the vocabulary: Make sure you read up on what FBML, FQL, FBJS all are.
      Understand the difference between the Profile and a Page on Facebook.
      Check out some demos: There are a few demo applications that you can dig through to better understand the basics of what makes a Facebook application.
      Just code already: By far the most common mistake I've seen thus far is over-thinking things, the majority of your questions will be answered by simply trying stuff out on the platform. This isn't high school calculus, you are allowed to guess-and-check. I am willing to help developers who obviously need it, but if you can't be buggered to try something out, I can't be buggered to point you in the right direction on where you went wrong.



    With the first year anniversary of the original F8 event right around the corner in May, I feel we as a community of developers have made tremendous progress in establishing ourselves, but now I feel it's time for some introspection and self-improvement as a community.
Read more →

On funding my startup

This has been a whirlwind year for startups across the bay area and my startup, TY-Combinator really is no different. Barely a month into 2008, Slide, Inc announced it had received funding, the recent news about the bid from Microsoft to purchase Yahoo! for just above the GDP of Croatia and now great news for the TY-Combinator.

I'm pleased to announce that the TY-Combinator has received an unsolicited bid from Microsoft that values TY-Combinator shares at over 400% under market value. Microsoft is willing to offer TY-Combinator a half-eaten sammich in exchange for 85% of TY-Combinator outstanding shares. This is an exciting time to work for TY-Combinator, with the prospective addition of the capital Microsoft is willing to offer we will be able to finance new projects to expand our global reach over 1000%, up from our reported reach in the 2007 fiscal year of 1.


Microsoft's bid for a stake in TY-Combinator
Read more →

Are Free Gifts Still Gifts?

Facebook has been pretty nice to Free Gifts in the past, despite originally being a blatant rip-off of the real Gifts application. Prior to today, I have only received one complaint from Facebook regarding Free Gifts practices. They asked me to remove a gift that looked similar to one of their gifts. I was okay with that even though mine was a lemon and theirs was a lime; maybe it was tough for the color blind audience to decipher? Today, I received my second complaint from them, which stated:

Your Facebook application, Free Gifts, is currently in violation of the Platform Application Guidelines section I.3 (see http://developers.facebook.com/guidelines.php). Specifically, please note that the Terms prohibit applications from acting in a manner that is misleading, deceptive, or fraudulent.

The application's link under the profile picture uses the same wording as Facebook's Gift application (please see attached). Please change this to reflect your application's name to differentiate Facebook's Gift application and "Free Gifts" application, as it is currently misleading users to think that this refers to the associated Facebook features.


I will admit it is relatively the same wording, but they failed to explain how using "Send xxxx a Gift" is deceptive or misleading to users. First of all, Facebook provides a tool tip when you hover over a profile action which says "Provided by the xxxxxx Application," which immediately makes a distinction between Gifts and Free Gifts. Second, as far as I know, users are still sending a gift when they use Free Gifts. Third, I have been using this text for longer than I can remember now with no complaints. With over 50 million gifts sent, I have never had a user say they were "trying to use the real gift" application.

I did comply somewhat by making all future profile actions say "free gift" instead of "gift," but there is no easy way for me to fix the 8 million profiles already containing the text. As of now they have failed to respond to my question of how exactly I was deceiving users, but I am really interested in hearing their reasoning.
Read more →

SIGSEGV in my brane.

I'm not proud of it, but I do read TechCrunch every now and again, if for only the occasional gem that comes across that causes me to hate buzzwords and everybody that uses them.

In the second paragraph of this article almost caused an entire system shutdown in my central-buzzword-processing unit (CBU):

"Both Imeem and Anywhere.FM saw a lot of synergy in the deal."


I couldn't read any further into the article after reading that, whenever anybody uses the word "synergy" seriously I have a tendency to tune out completely and think the absolute worst of them until they offer me chocolates, caffeine or other goodies.
Read more →

Courtesy of Adonomics


We've been working pretty hard for the past month (well, for the past 8 months too) but I'm particularly proud of the work that my co-conspirator and I have been putting in on Top Friends (we're that green line that creeps up from behind on FunWall and Super Wall).

One of the most helpful "tools" that's been available to me has been Slide's competitive spirit. In addition to the 2,000+ developers on the Facebook platform we have some pretty healthy competition going on inside Slide as well. Between Top Friends, SuperPoke and FunWall there is plenty of trash-talking and "friendly competition" (read: if it weren't an HR violation, I'd of already resolved to dirty tactics). In doing so we've cultivated an environment where some of the most often heard phrases are: "Is Facebook down again?!" and "OH SCHNAP!"

Another key factor to our team's enjoyable demeanor has been (in my opinion) our liberal use of the "rubber chicken" as part of a sort of group hazing. In essence, when you have glaring mistakes that somehow get pushed to the live site, you will come into the office the next day with rubber chickens adorning your monitor. This group acknowledgement of when we "fuck up" encourages more of a social-pressure to write good code instead of relying on policy, etc to ensure code quality, especially on the rapid release schedules we adhere to. Rubber chickens are the truly quintessential gift at Slide, it is always feels better to give than to receive.

As we near the end of the first month in 2008, I wish Facebook and Bebo continued success with there platform(s); not because I love FQL and FBML oh so much, but because I work for Slide, on the Facebook team, where competition and rubber chickens reign supreme in the land of embedded videos, sortable friends and flying sheep.

(Now seriously, Slide is hiring)
Read more →

Your "voice interface" is fucking stupid.

Recently the bank that financed my car switched their phone payment systems over from their more traditional "press a number to do stuff" to a "talk to a computer and try to do stuff" interface, and my reluctance to pay my car payments has increased tenfold.

Before they switched the phone interface, I almost had the correct sequence of numbers to press entirely memorized to where I could press 3-5 numbers in sequence and be done with my "payment session" in under two minutes. Meaning in a matter of two minutes, I could initiate a transaction from my checking account, to send almost $300 to Chase, in two minutes. I hated losing the money, but I loved the efficiency.

Recently however, they've "pulled a Vista" and replaced a wonderfully functional system that "got the job done" with a bloated, slow and buggy system that infuriates me everytime I need to talk to the computerized woman at the other end of the line. A rapid mashing of touch-tone keys on my phone has been replaced with:

PaymentBot: Welcome to Chase Auto Finance!

*pause*

PaymentBot: If you would like to make a payment, say "make a payment." If you would like to check your payoff balance, say "payoff balance." If you would like to blow a goat, say "baaaaaaaa."

Tyler-Unit: make a payment

PaymentBot: It looks like you want to make a payment, if this is correct say "yes."

Tyler-Unit: yes (at this point I'm usually irritated that I've past the two minute mark)

PaymentBot: First I need to find your account, please say your account number or your social security number, or enter them into the phone

Tyler-Unit: *mashes on keys*

PaymentBot: The number you entered was 1-2-3--4-5--5-6-5-4, if this is correct, say "yes."

Tyler-Unit: YES

PaymentBot: I'm sorry, I didn't catch that, if the number you entered: 1-2-3--4-5--5-6-5-4 is correct, say "yes."

Tyler-Unit: YES

PaymentBot: Okay, if you would like to make a payment over the phone, say "phone." If you would like to make a payment via mail, say "mail."

I could continue, but I won't .

Just to get to the point where I finally need to enter my payment details (because Chase couldn't update their system to, god-forbid, remember the same information I've been mashing into a keypad for the past two years) takes close to five to eight minutes.

Between the various financial institutions that I need to deal with every month I get to fight with terrible websites, miserable phone interfaces and idiot-customer service representatives, it almost makes me regret being fiscally responsible (our government isn't, why should I have to?). I'm hoping there's a special portion of hell reserved for whichever numbnuts in middle-management at Chase decided "OMG! Voice interfaces are TOTALLY kewl!!!!!"

Are there means of consolidating smaller (think below $10,000) loans from one bank to another? While it's pretty obvious that Chase can effectively handle its finances, they certainly can't handle "user-experience", if your customers' only interaction with you as a company is over the phone, or over snail-mail, it's usually in your best interest to make sure those "interfaces" to your customers are top-notch.

I hate voice interfaces.
Read more →

Perforce Backups, Revisited.

A very long time ago I wrote about my backup script for archiving my entire Perforce repository. I can finally write the obvious follow-up to the post, as I've finally had to use my backups.

In my scenario, the last backup I took was in February of 2007, almost an entire year ago (my development slowed around that time). During my transit from San Antonio to San Francisco the "server" my Perforce repository ran off, also known as orange (seen on the bottom here), a "headless laptop", had its disk completely fail. Up until recently however I haven't had a replacement for "orange" but now that I have pineapple sitting in a colocation facility, I have a new candidate for a Perforce server.

Luckily I had made a habit of burning my backups to DVDs every two weeks, since two weeks of nightly backups would fill up an entire 4.7GB DVD (I still have no idea how my own source repository grew to 120MB or so). After rsync'ing the latest backup tarballs, it was completely up to Perforce to reliably restore them.

Perforce's documentation is very good, so I suggest going over the backup and recovery procedures if you find yourself needing to recover from backups.

Within about 15 minutes I had restored the Perforce database files as well as the actual source code itself and begun to sync a new Perforce client up with the new server (thanks to my p4tunnel script).

I can't talk enough about how much I really like Perforce as a version-control-system and am nothing short of elated to finally have my repository back online, it only goes to show how backups are crucial for anything you might ever want later, in my case backups albeit old backups, were still better than no backups.
Read more →

SXSWi and Me

I spoke with Tammy (our PR mastermind) about whether or not Slide was going to let me out of my cage to go to South by Southwest Interactive this coming March and it seems like they might actually let me! (I'm just as surprised as you are)

Unfortunately things with Facebook were at such a ridiculous pace when SXSWi was accepting panel submissions, that I never got a chance to submit my panel idea: "Slide is awesome, now let's talk about how great Slide is." This leaves me in a slightly awkward position, I cannot remember the last conference or event that I went to where I wasn't speaking or talking or dancing with a baboon in front of a live studio audience. Even at the last SXSWi I was there for about 36 hours and most of that time was spent setting up and then helping run BarCamp Austin2. Ideally I'd like to get on stage with some of the guys from Twitter, Facebook, Bebo, Google and maybe even Myspace to discuss the more open social web that we seem to be moving towards and a bit about how awesome Slide is. It's probably nothing more than a pipe-dream however, since the panels seem to be quite locked down at the moment.

Of course, if nobody will have me, then I might be relegated to slumming up and down 6th street in Austin hanging out with the usual drunkards that I know in Austin (you know who you are) and getting into trouble. Mmm, trouble.

Regardless, if you're going to be in Austin for SXSWi let me know, I've got a stack of swanky new business cards I want to get rid of :)
Read more →

What a heaping pile of FAIL.

I had mentioned previously that iChatAgent in Leopard leaks, I'm going to take that statement back. iChatAgent in Leopard hemorrhages memory, and I think I know why now.

While I was napping, there was a network hiccup causing iChat to get disconnected, when the network connectivity returned, it first tried to sign on a couple of Jabber accounts, both of which use self-signed SSL certificates. Being the lovely old chap that iChat is it prompted the user (napping at the time) to accept the self-signed certificate. While the dialog box was up, iChat sat waiting around before it signed on the other accounts and spun and spun and spun.

iChat spun and spun and spun until all the available disk space for virtual memory was used up by every process that had to swap out to make space for iChatAgent's demands on real memory, and then by iChatAgent itself swapping out.



God fucking damnit.
Read more →

Comparing IronPython and CPython

First a little background to help explain some of the terms, etc. "Python" is a language, similar to how "Java" is a language; unlike Java wherein the language is also relatively synonymous with the actual implementation of that language, Python has multiple implementations. If you've run python(1) from the command line, you're most likely running the CPython implementation of the Python language, in effect, Python implemented in C. Other implementations of Python exist, like Jython (implemented on top of the Java virtual machine), PyPy (Python implemented in Python), and IronPython (Python implemented on top of the .NET CLR).

I was talking with some of the guys from the #mono channel on GIMPNet about IronPython versus CPython as far as performance is concerned and I decided that I would refine my testing (using pybench) for more similar versions of the respective implementations, in as controlled of an environment as possible.

I ran pybench.py on a "quiet" (i.e. not-busy) machine sitting in a remote datacenter not too far from Novell, the machine is a Pentium III (i386) based machine running openSUSE 10.3. Since IronPython reports it's "implementation version" as Python 2.4.0, I decided to build and run CPython 2.4 against it. IronPython is running on top of the recently released Mono 1.2.6 which I also built from source (I got IronPython from the IPCE package in YaST however). pybench reported the various implementation details for both as such:

CPython

Implementation: 2.4.4
Executable: /home/tyler/basket/bin/python
Version: 2.4.4
Compiler: GCC 4.2.1 (SUSE Linux)
Bits: 32bit
Build: Dec 18 2007 23:00:48 (#1)
Unicode: UCS2


IronPython

Implementation: 2.4.0
Executable: /usr/lib/IPCE/ipy.exe
Version: 2.4.0
Compiler: .NET 2.0.50727.42
Bits: 32bit
Build: (#)
Unicode: UCS2


IronPython did alright, but it got pretty thrashed on a lot of the benchmarks. Unfortunately it's hard to tell whether it's Mono getting beaten up, or whether it's IronPython itself that's losing the battle here, running similar tests on the .NET 2.0 CLR would be beneficial but not something I am curious enough to boot a Windows virtual machine for. Regardless, here are the results, I've highlighed the rows where IronPython performs better than CPython.



































































Test Minimum Run-time Average Run-time

CPython IronPython Diff CPython IronPython Diff
BuiltinFunctionCalls:448ms357ms+25.4%450ms405ms+11.0%
BuiltinMethodLookup:530ms1329ms-60.1%536ms1390ms-61.4%
CompareFloats:380ms129ms+194.3%381ms132ms+187.7%
CompareFloatsIntegers:377ms93ms+306.1%378ms97ms+291.2%
CompareIntegers:436ms160ms+172.5%437ms161ms+170.6%
CompareInternedStrings:425ms443ms-4.1%426ms445ms-4.3%
CompareLongs:360ms292ms+23.3%361ms293ms+23.0%
CompareStrings:423ms330ms+28.0%423ms337ms+25.6%
CompareUnicode:377ms243ms+54.7%377ms245ms+54.2%
ConcatStrings:726ms9452ms-92.3%823ms10071ms-91.8%
ConcatUnicode:711ms5687ms-87.5%756ms6039ms-87.5%
CreateInstances:508ms761ms-33.2%518ms815ms-36.4%
CreateNewInstances:451ms3475ms-87.0%458ms3581ms-87.2%
CreateStringsWithConcat:473ms2650ms-82.1%475ms2833ms-83.2%
CreateUnicodeWithConcat:482ms1008ms-52.1%508ms1092ms-53.4%
DictCreation:405ms2944ms-86.2%407ms3057ms-86.7%
DictWithFloatKeys:552ms934ms-40.9%553ms944ms-41.5%
DictWithIntegerKeys:423ms1118ms-62.2%426ms1137ms-62.5%
DictWithStringKeys:413ms1186ms-65.1%414ms1317ms-68.6%
ForLoops:412ms189ms+118.5%413ms217ms+90.7%
IfThenElse:372ms128ms+191.8%374ms141ms+165.8%
ListSlicing:311ms4033ms-92.3%315ms4230ms-92.6%
NestedForLoops:488ms349ms+39.7%489ms382ms+28.1%
NormalClassAttribute:430ms1080ms-60.2%432ms1104ms-60.9%
NormalInstanceAttribute:401ms427ms-6.1%404ms442ms-8.7%
PythonFunctionCalls:393ms302ms+30.1%402ms352ms+14.3%
PythonMethodCalls:478ms643ms-25.7%536ms673ms-20.3%
Recursion:547ms158ms+245.9%659ms159ms+313.6%
SecondImport:476ms1383ms-65.6%481ms1432ms-66.4%
SecondPackageImport:501ms1425ms-64.8%503ms1482ms-66.1%
SecondSubmoduleImport:589ms1916ms-69.3%592ms1990ms-70.2%
SimpleComplexArithmetic:475ms729ms-34.9%476ms758ms-37.3%
SimpleDictManipulation:424ms1009ms-58.0%427ms1020ms-58.2%
SimpleFloatArithmetic:416ms455ms-8.7%422ms480ms-12.0%
SimpleIntFloatArithmetic:345ms161ms+113.8%346ms162ms+112.9%
SimpleIntegerArithmetic:345ms161ms+114.7%345ms161ms+113.9%
SimpleListManipulation:346ms497ms-30.4%350ms501ms-30.1%
SimpleLongArithmetic:402ms1120ms-64.1%403ms1130ms-64.3%
SmallLists:417ms1693ms-75.4%421ms1717ms-75.5%
SmallTuples:450ms3839ms-88.3%453ms3915ms-88.4%
SpecialClassAttribute:431ms1104ms-60.9%432ms1133ms-61.8%
SpecialInstanceAttribute:608ms423ms+43.8%610ms437ms+39.5%
StringMappings:443ms2255ms-80.3%448ms2311ms-80.6%
StringPredicates:503ms1058ms-52.5%504ms1066ms-52.7%
StringSlicing:527ms2880ms-81.7%562ms3008ms-81.3%
TryExcept:418ms21ms+1905.2%418ms39ms+985.6%
TryRaiseExcept:587ms6670ms-91.2%591ms6733ms-91.2%
TupleSlicing:390ms1817ms-78.5%397ms1863ms-78.7%
UnicodeMappings:362ms1323ms-72.7%365ms1347ms-72.9%
UnicodePredicates:438ms860ms-49.0%439ms912ms-51.8%
UnicodeProperties:400ms0msn/a401ms0msn/a
UnicodeSlicing:624ms2491ms-75.0%666ms2638ms-74.7%



The results are disappointing but not all that surprising, especially with regards to string manipulation. I attempted to run the same pybench.py tool on top of Jython but Jython doesn't appear to support the "platform" module, so I don't have a really good baseline for "managed/virtual machine-based Python implementations" right now. However, given the lack of evidence otherwise, I'll just go ahead and assume IronPython blew the doors off of Jython :). In general though this isn't the be-all end-all benchmark for IronPython, especially on Mono, but it does give a nice hint of where some improvements could be made both in the Mono runtime and IronPython. I'll have to run the benchmarks again with the newer versions of both implementations of Python to see where they're improving or degrading but by all means don't let this deter you from checking out IronPython! I'll be writing up a few code samples over the next couple weeks that I hope will be helpful to those "unenlightened" among us; dynamic languages on the CLR, what has the world come to.
Read more →

My new startup

I was talking to Dennis about quitting Palantir and coming to work for my startup which has no funding, and no time, but lots of brilliant ideas, when I realized I don't have a name for the startup yet.

So effectively immediately my I'm naming my startup TY-Combinator and wouldn't you know it! We're currently accepting angel funding, demon funding, and picnic baskets filled with those little sandwiches cut into triangles.

Also effectively immediately, I'm still going to work at Slide.
Read more →

Mono and FastCGI. An awkward relationship.

I've spent the week tweaking and adjusting my lighttpd configuration to where it cooperates better with Mono's FastCGI server, and I finally feel confident enough with the configuration to share.

Around thursday morning or so (maybe it was wednesday) the site was spewing so many 500 errors that somebody who I'm not sure I know where I know them from, emailed me saying "dude, site's broke." After checking the error logs, I found a lot of errors that were all like this:
fcgi-server re-enabled:  0 /tmp/fastcgi-mono-server

backend is overloaded; we'll disable it for 2 seconds and
send the request to another backend instead: reconnects: 0 load: 130

fcgi-server re-enabled: 0 /tmp/fastcgi-mono-server
backend is overloaded; we'll disable it for 2 seconds and
send the request to another backend instead: reconnects: 0 load: 130


After diagnosing the problem and kicking the server again, I decided that a couple of tips on the wiki page for Mono's FastCGI & Lighttpd had done me in, the first being about the FastCGI handler's max-procs configuration variable:
"max-procs" specifies the maximum number of servers to spawn. Because ASP.NET stores session specific objects, I am unsure of how applications would react if switching from one server to another, or if Lighttpd bonds a single server to a client. As such, I highly recommend keeping this value as "1" to avoid any conflicts.
Fortunately Urlenco.de doesn't really need any session information, so I did what Emeril and Apache admins are both familiar with doing, I kicked it up a notch (to about 10). After kicking the server one more time, this time with "max-procs" > 10 I watched the load on my little 1U server spike up to 30. While every terminal I had became so sluggish I could barely interact with the machine, I managed to open up "top(1)" and see what processses were royally screwing my machine. Turns out it was 10 instances of Mono, all trying to digest an ASP.NET site at once, all competing for the meager resources available. It seems that the Mono FastCGI server will process and compile your entire ASP.NET web application as soon as the FastCGI server is bootstrapped and accepting requests. Fortunately pushing new code to the site gets updated on the next HTTP request, so the number of times you'll have to kick (i.e. restart) the Lighttpd server should be minimal and you won't have to incur the huge performance penalty that often (I've since changed max-procs to 4).

I also went against some of the other advice on the wiki page
To overcome these problems, the recommended method for processing files is to send all requests directly to the FastCGI Mono Server.
By effectively passing every single request off to the Mono FastCGI Server you can avoid exposing some internal ASP.NET resources that should be interpreted and not sent over the wire, this seems to be poor practice as far as Lighttpd and FastCGI are concerned. Lighttpd is a very good, high performance HTTP server and should be allowed to do it's job, whereas FastCGI servers merely serve as a means for executing server-side pages, returning markup, etc. To avoid passing every single request off to the FastCGI server, I merely setup the FastCGI handler for .aspx pages and then mapped other ASP.NET extensions to that handler as was appropriate:
fastcgi.map-extensions = (

".asmx" => ".aspx",
".ashx" => ".aspx",
".asax" => ".aspx",
".ascx" => ".aspx",
".soap" => ".aspx",
".rem" => ".aspx",
".axd" => ".aspx",
".cs" => ".aspx",
".config" => ".aspx",
".dll" => ".aspx"
)


The base configuration for one of my virtual hosts (Urlenco.de) turned out something like this:
$HTTP["host"] == "urlenco.de" {

fastcgi.server = (
".aspx" => ((
"socket" => "/tmp/fastcgi-mono-server",
"bin-path" => "/usr/local/bin/fastcgi-mono-server2",
"bin-environment" => (
"MONO_FCGI_APPLICATIONS" => "/:/serv/www/domains/urlenco.de/htdocs",
"MONO_FCGI_LOGLEVELS" => "Standard", #All", #Debug",
"MONO_FCGI_LOGFILE" => "/var/log/lighttpd/mono.log",
),
"max-procs" => 4,
"check-local" => "disable"
))
)
}


Specifying the "application path" is somewhat of a pain, as now I more or less need a separate FastCGI configuration, which means they'll also need separate FastCGI servers, so another virtual host in the configuration (pineapple.monkeypox.org) has the following setup:
$HTTP["host"] == "pineapple.monkeypox.org" {

fastcgi.server = (
".aspx" => ((
"socket" => "/tmp/fastcgi-mono-server-pineapple",
"bin-path" => "/usr/local/bin/fastcgi-mono-server2",
"bin-environment" => (
"MONO_FCGI_APPLICATIONS" => "/:/serv/www/domains/pineapple.monkeypox.org/htdocs",
"MONO_FCGI_LOGLEVELS" => "Standard", #All", #Debug",
"MONO_FCGI_LOGFILE" => "/var/log/lighttpd/mono.log",
),
"max-procs" => 1,
"check-local" => "disable"
))
)
}


Since the virtual host pineapple.monkeypox.org barely runs any ASP.NET code at all, I decided to only give it one Mono FastCGI process. Also of note is that the "socket" is different from the other FastCGI handler, if you try to use the same socket, the first Mono FastCGI process will take it over and both FastCGI handlers will return the same code, returned from the first handler.

Feel free to bug me with any questions, this is my first foray into using Lighttpd and I'm already pleased as punch with it (compared to Apache) but there are certainly some caveats and bits of black magic involved with Mono, FastCGI and Lighttpd. That said, it still feels less sticky than running Apache 2 and mod_mono (not that they're not great and all). Hopefully web traffic will increase and give me a good test-bed for figuring out "the right stuff" to scale Mono on Lighttpd.


Scary thought isn't it? :)
Read more →

"Fun" way to crash Leopard #159

Earlier this week I noticed that the Facebook home page would not stop loading, in the sense that the entire page would load and render, but one resource would continue to load. As I popped open Safari's Activity Monitor I found that the "one resource" was a server-generated image that was effectively streaming to my browser window, since the server would not stop sending data for the file.

Curious as to what the image was, I downloaded it via Safari, which downloads to the "Downloads" folder which has a convenient "stack" icon in the dock. If you're not familiar with "stacks" in Leopard, they essentially are a nifty way to navigate to folders straight from the dock, and also offer an iconic preview of the most-used/latest item in the folder.

Unknowingly, this image that I had downloaded was completely corrupted, but I had just downloaded it to the "Downloads" folder, and the Dock started to try to render a preview in the Dock of the corrupted image. Doing so set off a looping chain-reaction that was a wonderful sight to see, and ended up in a hard-restart of the machine as I couldn't get control of it. First the Dock crashed, following the Dock, Finder restarted and then Spaces crashed entirely. Sitting looking at a Dock that kept restarting and crashing and Spaces that had completely abandoned 5 other "spaces" full of windows, and an unresponsive Finder I made like a Windows ME user and rebooted my machine.

After the machine started up again I got to the Downloads folder and deleted the image before the cycle could start again and managed to restore the machine to a usable state again.

According to Apple, Mac OS X Version 10.5.1 is a full-fledged release, but it still feels like a release candidate depending on the day of the week, the amount of sunshine outside, or any one of a large number of arbitrary variables.
Read more →