tag:blogger.com,1999:blog-70672028149379475692008-06-05T22:49:50.952-07:00Liminal ExistenceBlainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comBlogger23125tag:blogger.com,1999:blog-7067202814937947569.post-20250468172982705912008-05-12T08:53:00.000-07:002008-05-12T09:04:49.886-07:00Velocity<p>If you're interested in scalability and performance as it pertains to internet applications, or if you're involved in or looking to build a reliable internet-based system, go to <a href="http://en.oreilly.com/velocity2008/public/content/home">Velocity</a>.</p> <p>I was fortunate enough to attend the O'Reilly <a href="http://lethargy.org/~jesus/archives/106-A-job,-a-mission,-a-career-all-without-a-path-or-a-name..html">Velocity Summit</a> back in January, which was a Foo-Style event designed to provide some context leading into the actual conference in June. If the conference is one tenth as good as the summit, it will be amazing. <a href="http://radar.oreilly.com/jesse/">Jesse</a> is an amazing organizer and a man with a vision.</p> <p>Anyhow, instead of reading my <a href="http://romeda.org/blog/2008/05/scalability.html">off-the-cuff posts</a> about obvious things that are much more fun to talk about while <a href="http://www.futureofwebapps.com/2008/miami/">drinking in Miami</a>, go to Velocity and learn this stuff for real.</p>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-11879480190102020832008-05-11T18:57:00.000-07:002008-05-12T12:27:43.374-07:00Scalability<p><b>Updated:</b> Go read Steve's <a href="http://steve-yegge.blogspot.com/2008/05/dynamic-languages-strike-back.html">Dynamic Languages Strike Back</a>. It's a longer read, but it's much more interesting, and he's much smarter than I am.</p> <p><a href="http://ola-bini.blogspot.com/2008/05/just-add-scaling.html">LOL.</a> &lt;-- this is a link. Read Ola's post, first.</p> <p>For all those who don't get it, <i>languages don't scale, architectures do.</i></p> <p>Now, some languages are <i>faster</i> than others. That means that to complete a given operation, it <i>costs less</i>, everything else being equal. Costing less is a good thing. But developers also cost money, so if you have to spend money on developers' time porting from one language to another then you might not be saving any money at all, and really you're just treading water.</p> <p>Once upon a time, <i>Shell Scripts</i> were used to <a href="http://docs.rinet.ru/UNIXi/ch18.htm">write CGI applications</a>. With the correct architecture, and enough money, you could build <a href="http://google.com">Google</a> with <a href="http://www.tcsh.org/Welcome">tcsh</a>. No, really. It wouldn't be fun, and you'd be dumb, because there are <b>much</b> <i>cheaper</i> ways to do it. But then again, if you stuck with it, perhaps you'd optimize tcsh to be really fast at spawning and serving up web requests. Faster than Java, faster than &lt;insert your favourite language here&gt;. Faster means <i>cheaper</i>, it doesn't mean more <i>scalable</i>.</p> <p>I point to <a href="http://www.tbray.org/ongoing/When/200x/2007/10/30/WF-Results">exhibit A</a>. Perl used to be <a href="http://furryland.org/~mikec/bench/">slow</a>. Now it beats JoCaml with the bestest concurrency (re: &ldquo;Scalability&rdquo;) around. What was Perl built for? Parsing text. Lots of it. All the time. It's fast. Does it mean that you can't build Wide Finder with another language? Absolutely not. Does it mean that you couldn't build Wide Finder to scale out to a trillion documents with gawk? If you answered &ldquo;yes&rdquo;, go back to the start of this post and read again! :-) If you're still answering &ldquo;yes,&rdquo; try reading some more. <a href="http://randomfoo.net/blog/id/4171">Leonard</a>, <a href="http://teddziuba.com/2008/04/im-going-to-scale-my-foot-up-y.html">Ted</a>, <a href="http://www.joestump.net/2008/04/its-not-the-language-stupid.html">Joe</a>, <a href="http://www.amazon.com/Building-Scalable-Web-Sites-applications/dp/0596102356/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1210561240&sr=8-1">Cal</a>, and <a href="http://www.amazon.com/Scalable-Internet-Architectures-Developers-Library/dp/067232699X/ref=pd_sim_b_img_1">Theo</a> are good places to start. <p>If you answered &ldquo;no,&rdquo; congratulations! Pat yourself on the back for knowing what <a href="http://en.wikipedia.org/wiki/Scalability">scalability</a> means. </p>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-69403456789457665942008-03-08T06:59:00.000-08:002008-03-09T08:25:28.581-07:00FoWA Miami Rocked.<p>I've been busy getting [Twitter] ready for SXSW, and have completely failed at email and, well, everything except work, since then. Before I <span style="text-decoration: line-through">actually land</span> get drunk in Austin, I wanted to make a quick post about how great <a href="http://www.futureofwebapps.com/2008/miami/">FoWA Miami</a> was.</p> <p>After giving my workshop, I attended <a href="http://www.joestump.net/">Joe's</a> workshop on scalability, which was an amazingly thorough discussion, and I highly recommend attending anything that Joe does in the future (including the panel that he, Cal, and others are on at SxSW. I didn't catch many of the session talks on Friday, as I spent much of my time talking to attendees, but the "Building a Web App in 45 minutes" panel was a fun experiment, and both <a href="http://iamcal.com/">Cal</a> and <a href="http://tv.winelibrary.com/">Gary</a> were energetic, brilliant, amazing, all that good stuff. If you get a chance to see either of them speak, don't pass it up. Especially Gary, as you're likely to get free wine, even if he makes you eat dirt beforehand.</p> <p>I had some hiccups during the demo / discussion portion of my workshop, but the first part went well, I think, and I'm looking forward to some great applications that incorporate Jabber soon. My talk, "Bringing your web app to the masses" went well, except for the part where Twitter went down in the middle of it, and I got a call from work (which I waited until after the talk to answer).</p> <p>Some heckling ensued, but I was happy to be able to address the audience's questions about Twitter in an open and honest way. The atmosphere that Carsonified has managed to foster at FoWA helped a ton.</p> <p><a href="http://randommel.com/">Mel</a>, <a href="http://ryancarson.com/">Ryan</a>, <a href="http://www.carsonified.com/about-us">Lisa</a>, <a href="http://www.fiveandlime.com/">Keir</a>, and <a href="http://elliotjaystocks.com/blog">Elliot</a> did a fantastic job organizing everything, and <a href="http://tantek.com/">Tantek</a> and <a href="http://brianoberkirch.com/">Brian</a> put together an amazing lineup of speakers and workshops. Seriously inspiring stuff.</p> <p>If they'll have me, I'll definitely be going to any conferences they hold in the future. They've come a long way since the FoWA San Francisco in Fall 2006, and it looks like they'll just keep getting better.</p>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-82549299344016064692008-02-21T10:51:00.000-08:002008-02-21T11:43:53.337-08:00Google Entaglement<p>I've done a <a href="http://resist.ca/">fair</a> bit of <a href="http://oauth.net/">security</a> work, and generally try to care about the <a href="http://citp.princeton.edu/memory/">finer details</a> of privacy and security. However, one of the things that I've learned is that more often than not, no amount of digital security past a certain point is going to help, since usually the <a href="http://en.wikipedia.org/wiki/Green_Scare">threat model</a> isn't an advanced technological attack, it's a social one.</p> <p>Thus far, Google has done a pretty good job of keeping private things private and public things public. I've spoken to people on the Google Reader team, and the main reason they haven't added support for private feeds is their acute concern for privacy.</p> <p>Today Google announced a <a href="http://bits.blogs.nytimes.com/2008/02/21/google-health-begins-its-preseason-at-cleveland-clinic/?ref=technology">limited trial of storing health records</a> online. This seems reasonable and doable in a secure way, but I'm sure they'll get lots of unwarranted flak for the long-awaited project.</p> <p>However, there will and should be some warranted flak. It turns out that they're using your regular Google account to store this information, and will provide access to it using your regular password, no doubt through yet another Google login page. I've heard concerns that <a href="http://oauth.net/">OAuth</a> supports phishing (from Google people), but project infighting and power struggles at Google that result in <a href="http://gmail.com/">tens</a> of <a href="http://blogger.com/">login</a> <a href="https://www.google.com/accounts/ServiceLogin?service=dodgeball&amp;ltmpl=duallogin">pages</a>, all slightly (or dramatically) different, all using the same credentials supports phishing much moreso.</p> <p>I strongly support patients' rights to access their medical information, and Google is probably one of just a handful of organizations that can do the necessary coordination work and stand up to invasive organizations at scale. However, they need to stop thinking of this data as <span style="font-weight: bold;">theirs</span>, because it's not — it's <span style="font-weight: bold;">your</span> data. Using the same password as your <span style="font-style: italic;">email</span> to access your <span style="font-style: italic;">health records</span> is something that should be actively discouraged. If Google wants to present a unified interface, they should expose an API and use OAuth or AuthSub, just like any other third party that would consume the data.</p> <p>Now, I may be over-reacting, but I had an interaction yesterday that suggests to me that I'm not. Someone using GTalk sent a chat request to blaine@twitter.com; this email address has an MX record that resolves to mail.twitter.com, and the corresponding JID resolves to jabber01.twitter.com. However, I have claimed my blaine@twitter.com address on GMail, and associated it with my primary GTalk ID (romeda@gmail.com). When I accepted the chat request, the response came from my GTalk account, romeda@gmail.com.</p> <p>In effect, Google had done something clever, and in so doing broke the Jabber spec, ignored my own self-hosted Jabber server, and<span style="font-style: italic;"> exposed my personal email address</span> without asking my permission.</p> <p>In this case, it wasn't a big deal, I don't care, etc. Others might, though, and I only knew that it was happening because the person on the other end of the chat was tech-savvy enough to realize what had happened. Also, email addresses and connections between them are hardly closely-guarded secrets. The thing I take away from this is that Google is being sloppy. There's a lot going on, and it's hard to keep track of it all. That your health records are being tied to your Google account just reeks of some power struggle where the Google account people want to bolster their product's internal importance (or have managed to do so that they get veto power where they shouldn't have it), and it's simply not a pragmatic choice. There's a reason your health records aren't stored at the DMV, and it's not out of convenience. Just sayin'.</p>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-6322586508180854482008-01-20T23:19:00.000-08:002008-01-20T23:51:45.705-08:00FoWA Miami<p>Just a quick note that I'll be giving a <a href="http://futureofwebapps.com/2008/miami/workshops.php">workshop</a> on building real-time web applications using Jabber at the <a href="http://futureofwebapps.com/2008/miami/">Future of Web Apps</a> in Miami, on February 28th. The conference runs from the 28th to the 1st of March, and should be a lot of fun. </p><p>We've been gradually improving the Jabber stack on Twitter, and we're now sending millions of messages every day, doing things that just don't fit into the polling-based world of Atom feeds. There are a ton of extremely awesome things that can be built, and so far we've just scratched the surface.</p>More to come; if I don't start blogging these things in small pieces, they'll never come.Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-49929832069825000252007-09-01T18:39:00.000-07:002007-09-01T18:51:06.580-07:00Stability<p>Most of the Twitter team's work in the weeks leading up to launching <a href="http://explore.twitter.com/blocks/">Blocks</a> was to ensure that it wouldn't fall over as soon as we released it. It's an extremely punishing application, loading 10 timelines on every occasion that someone looks at it. So far, the servers haven't even noticed.</p> <p>There have been a number of Twitter hiccups in the past few weeks, but they've all been weird, random bugs. Which is not to make excuses, but rather to say that in spite of (very time-consuming) challenges along the way, we've been myopically focused on making the site faster and more reliable. As evidence, here's a graph of page load times, as seen from an external observer:</p> <img src="http://romeda.org/blog/uploaded_images/twitter.com-.rrd-Load-times-for-one-month-780093.png" alt="Twitter Load Times, as monitored by an external observer, over the past month."> <p>We're going to keep building a faster and more reliable Twitter. We're also going to add some awesome new features, and soon. Possibly better than contact search and GMail, even! Finally, we'll have more visualizations from the Stamen folks. <a href="http://lukewarmtapioca.com/">Britt</a> is off to Berlin for <a href="http://www.railsconfeurope.com/">RailsConf</a> mid-September. We'll then have more details about what we're doing to push Rails and Twitter.</p>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-63599570874130471892007-09-01T15:58:00.000-07:002007-09-01T18:28:57.929-07:00These are the people ...<a href="http://en.wikipedia.org/wiki/Folly">Folly</a>: "In architecture, a folly is an extravagant, frivolous or fanciful building, designed more for artistic expression than for practicality." &#8211; via <a href="http://del.icio.us/url/844681fe17e3f7db16043e6028f714e1">Tom Coates</a>, by way of <a href="http://tom-carden.co.uk/">Tom Carden</a>. <p>We just released <a href="http://explore.twitter.com/blocks/">Twitter Blocks</a>, a nice little visualisation done by the good folks at <a href="http://stamen.com/">Stamen Design</a>. It's fun! Go play!</p> <p>Stamen's recent work highlights the playfulness inherent to Twitter. I can't wait to release more of these interfaces, and hope that it inspires similar work. Sam Ruby, Tim Bray and others have recently weighed in with their long bets. I'm willing to put down that playfulness &#8212; of the sort that Stamen, <a href="http://schulzeandwebb.com/">Schulze &amp; Webb</a> and <a href="http://avantgame.com/">Jane McGonigal</a> explore and invent daily &#8212; is so important to who we are as people that the tech world won't be able to ignore it for much longer.</p> <p>Not exactly a risky bet, but too often the tech industry just ignores these things, so there it is, just for kicks.</p>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-53047015167722129132007-06-21T12:44:00.000-07:002007-06-21T14:48:28.363-07:00SELECT * FROM everything, or why databases are awesome.<p>I've just committed a <a href="http://dev.rubyonrails.org/ticket/8713">patch</a> to ActiveRecord that prevents a large number of very, very bad queries from hitting your database. Go update your code, ASAP.</p> <p>We've made some pretty significant progress towards scaling Twitter, and we're now at the point where the majority of requests that hit our site complete in less than 70 ms (mostly API requests), and the really complicated front-end pages that we display complete in less than 160 ms. There are still a lot of hiccups, so the average is higher than that, but we're constantly working on getting it down.</p> <p>One of the consistent problems we've been facing is errant queries. We've been seeing (off and on) queries like:<br/><br/> <tt>SELECT * FROM statuses WHERE user_id = 234223 ORDER BY created_at</tt> <br/><br/> If you know anything about relational databases, this is a <b>very bad thing</b>, especially when you have users that have more than 20,000 statuses.</p> <p>One major downside of having an object-relational mapper is that you don't always control what goes on behind the scenes. In tracking down this problem, first we investigated all our code, and weren't able to find the source of these problems. Switching tactics, we isolated some test cases that replicated the problem and brought out the big guns: <a href="http://www.tbray.org/ongoing/When/200x/2004/06/17/DeDebPrint">print</a>. This pretty quickly brought us to an obscure corner of the ActiveRecord source (three cheers for source code!), where it became apparent that Rails was doing these gigantic loads from the database every time we saved even a single field in a related object. There are a bunch of mitigating circumstances that mean that this bug doesn't get triggered all the time, but it's still really really bad.</p> <p>Thankfully, the patch <strike>will be committed soon</strike> has been committed (32 minutes patch-to-commit!), and no-one will have to deal with, as <a href="http://blog.codahale.com/">Coda</a> put it: "Arg stabby stab stab stabbity fuck stab" anymore. The fact that no-one noticed really speaks to how freaking awesome relational databases (in our case, MySQL) are these days.</p> <p>Perhaps underlying all of this is the simple fact that most of the time, ActiveRecord and Rails in general is pretty solid, and Ruby underneath is a fully sound language with which to build high-volume services. <a href="http://glu.ttono.us/articles/2007/06/21/powerset-to-launch-front-end-on-ruby">Kevin</a> over at PowerSet has more on the topic - they've recently announced that they'll be doing their front-end development in Ruby (up until now, it's just been a glue language internally).</p>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-55632856007417332652007-05-18T03:30:00.000-07:002007-05-18T03:36:24.867-07:00Twitter at RailsConf<p>Sadly, I won't be attending RailsConf in Portland this weekend. I'll be finishing up at XTech, followed by a (well-deserved) week relaxing / adventuring in Morocco. Photos will follow.</p> <p>In the meantime, if you're one of the lucky <strike>few</strike> many attending RailsConf, <a href="http://al3x.net/">Alex</a> and <a href="http://lukewarmtapioca.com/">Britt</a> will be speaking 10:45 AM on Sunday. They may or may not being doing a reprise of my <a href="http://www.slideshare.net/Blaine/scaling-twitter/">Scaling Twitter</a> talk, but I'm sure it will be fantastic in any event.</p> </p>Wish I were there, have fun all!</p>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-49919319937594308222007-05-17T01:58:00.000-07:002007-05-17T04:09:04.305-07:00Social Software for Robots Slides Up<p>I've uploaded the <a href="http://www.slideshare.net/Blaine/social-software-for-robots/">Social Software for Robots</a> slides for the messaging/jabber talk that <a href="http://laughingmeme.org/">Kellan</a> and I gave yesterday at <a href="http://2007.xtech.org">XTech 2007</a>.</p> <p>I think the talk went well, aside from a hiccup getting all the stars aligned to show the visualization that <a href="http://www.tom-carden.co.uk/">Tom</a> helped us put together. For those who missed it, I'm hoping that Kellan or I or both will give reprises at other upcoming conferences. There's a lot of potential here, and things are finally reaching the point where real-time APIs are not only becoming a reality, but a necessity.</p> <p>XTech has been great fun so far, and there are a number of talks that I'm looking forward to today and tomorrow. Huge thanks to Edd and everyone else who's helped put it together.</p>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-34998431186094703602007-04-22T12:49:00.000-07:002007-04-22T13:13:46.088-07:00Slides for Scaling Twitter talk, XTech next up.<p>The slides from the talk are <a href="http://www.slideshare.net/Blaine/scaling-twitter/">available on SlideShare</a>. They don't spell out the talk, so if you have questions, please do ask.</p> <p>I'm really excited about <a href="http://2007.xtech.org/">XTech</a>, coming up in a few weeks (May 15th-18th) in Paris. I'll be speaking with <a href="http://laughingmeme.org/">Kellan</a> about using <a href="http://2007.xtech.org/public/schedule/detail/197">Jabber to build Social Software for Robots</a>. Lots of awesome people and talks there, should be a lot of fun.</p>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-78635820600926302312007-04-13T12:51:00.000-07:002007-04-13T12:54:14.092-07:00Scaling Twitter, The Talk.<p>Simon Willison <a href="http://simonwillison.net/2007/Apr/12/question/">linked</a> to <a href="http://www.radicalbehavior.com/5-question-interview-with-twitter-developer-alex-payne/">an interview with Alex Payne</a>, one of my co-workers on Twitter. This <a href="http://www.loudthinking.com/arc/000608.html">caused</a> <a href="http://lucasjosh.com/blog/2007/04/13/twitter-rails-and-scaling/">a</a> <a href="http://discuss.joelonsoftware.com/default.asp?joel.3.479387">bit</a> <a href="http://www.alexrudloff.com/2007/04/12/twitter-developer-calls-out-ruby-on-rails/ ">of</a> <a href="http://rc3.org/2007/04/twitter_develop.php">a</a> <a href="http://tomayko.com/weblog/2007/04/13/rails-multiple-connections">stir</a>, so <a href="http://www.agenturblog.de/2007-04/ruby-is-slow/">apparently</a> there's some <a href="http://laughingmeme.org/2007/04/12/twitter-ruby-and-scaling/">interest</a> in our experience scaling Twitter, and Rails.</p> <p>We've been extremely happy with Rails, and make use of the multitude of helpers that it offers us - like any application on any stack, though, providing fast response times to a (rapidly) growing number of users is a challenge. The solutions are often tightly coupled to the application and its characteristics, and while scaling the most trafficked Rails site in the world, we've run into situations where existing solutions weren't enough.</p> <p>This process has led us to build a number of tools that help us deal with our load, and just as soon as we find some spare time, we'll be releasing many of them. In the meantime, you can find out first what sorts of challenges we've encountered and solutions we've come up with at my talk at the SDForum <a href="http://www.sdforum.org/SDForum/Templates/CalendarEvent.aspx?CID=2135&mo=4&yr=2007">Silicon Valley Ruby Conference</a> next weekend (April 21-22nd).</p> <p>I'll be focusing on ActiveRecord and database optimization, caching, and of course, Messaging. I'll also touch on some areas where we haven't had great successes (yet), and hopefully someone from the audience will shout out that there's some totally obvious and awesome thing that we haven't thought of, and it'll save us weeks of work (no, I'm serious. Does someone want to take bets?).</p>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-75507552936069917902007-04-01T11:48:00.000-07:002007-04-01T18:39:18.618-07:00MapReduce in 36 lines of RubyThis has been burning a hole in my head since August, after <a href="http://www.joelonsoftware.com/items/2006/08/01.html">Joel's post</a> made it blindingly obvious that Ruby is the perfect language for distributed programming. I have some code that properly implements partitioning, etc, but never got around to finishing it sufficiently for a proper release. Here's the core idea; if anyone wants the partitioning code, ping me at romeda@gmail.com. mapreduce_enumerable.rb: <pre><code> require 'rubygems' require 'ringy_dingy' require 'ruby2ruby' module Enumerable def dmap(&block) self.each_with_index do |element,idx| ring_server.write([:dmap, Process.pid, block.to_ruby, element, idx]) end results = [] while results.size < self.size result, idx = ring_server.take([:dmap, Process.pid, nil, nil]).last(2) results[idx] = result end results end def ring_server return @ring_server if @ring_server ringy_dingy = RingyDingy.new nil @ring_server = ringy_dingy.ring_server end end </code></pre> mapreduce_runner.rb: <pre><code> require 'rubygems' require 'ruby2ruby' require 'ringy_dingy' ringy_dingy = RingyDingy.new nil ring_server = ringy_dingy.ring_server loop do pid, block, element, idx = ring_server.take([:dmap, nil, nil, nil, nil]).last(4) begin result = eval(block).call(element) rescue Object => err result = err end puts "Got #{result} from #{element} for #{pid}." ring_server.write([:dmap, pid, result, idx]) end </code></pre> From the shell: <pre> $ sudo gem install RingyDingy $ sudo gem install ruby2ruby $ ring_server & $ ruby mapreduce_runner & $ ruby mapreduce_runner & </pre> From irb: <pre><code> > require 'mapreduce_enumerable' > (1..100).to_a.dmap { |v| v * 2 } </code></pre>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-34438466227923355402006-12-22T13:32:00.001-08:002006-12-22T13:32:00.210-08:00Google Code Love<div style="float: right; margin-left: 10px; margin-bottom: 10px;"> <a href="http://www.flickr.com/photos/lattice/330350557/" title="photo sharing"><img src="http://farm1.static.flickr.com/129/330350557_1eac167eaa_m.jpg" alt="" style="border: solid 2px #000000;" /></a> <br /> <span style="font-size: 0.9em; margin-top: 0px;"> <a href="http://www.flickr.com/photos/lattice/330350557/">Google Code Love</a> <br /> Originally uploaded by <a href="http://www.flickr.com/people/lattice/">liminalists</a>. </span></div><p>My <a href="http://code.google.com/p/xmpp4r-simple/">Jabber::Simple</a> project, extracted from <a href="http://twitter.com/">Twitter</a>'s Jabber/IM support, got some love today from Google Code (thanks, <a href="http://vedana.net/">eric</a>!)</p><br clear="all" />Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-45686692282613900452006-12-21T16:06:00.000-08:002006-12-21T17:02:28.968-08:00The Year in Cities, 2006.<p>Here's the list of cities I stayed in during the course of 2006. Memes away. I've only included cities in which I spent at least one day and one night. I've preemptively added a few spots I'll be visiting over Christmas, too.</p> <p> San Francisco, CA<br/> Fresno (FresYES!), CA<br/> Tahoe, CA/NV<br/> Seattle, WA<br/> Vancouver, BC<br/> White Rock, BC<br/> Victoria, BC<br/> Whistler, BC<br/> Reykjavik, Iceland<br/> Ólafsvík, Iceland<br/> Belfast, Northern Ireland<br/> Aberystwyth, Wales<br/> Norwich, East Anglia<br/> London, England<br/> Lewes (Brighton & Hove), East Sussex<br/> Barcelona, Spain<br/> Portland, OR<br/> Grande Prairie, AB<br/> Santa Cruz, CA<br/> Mojave Desert & Las Vegas, CA & NV<br/> Zion National Monument, UT<br/> Tucson, AZ<br/> [Near] Calistoga, CA<br/> Chilliwack, BC </p> <p>All in all, pretty good, though I'm hoping for maybe somewhere more less-European for 2007. We'll see.</p>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-13697902226748251212006-12-20T13:12:00.000-08:002006-12-20T13:34:39.362-08:00The Weather, by Twitter.<p>A few weeks ago, <a href="http://laughingmeme.org/">Kellan</a> and I whipped up what is tentatively known as "WeatherBot". It's a simple tool to provide weather updates to <a href="http://twitter.com/">Twitter</a> users. Every morning at 7:00 AM and 3:45 PM (local time, that's 07h00 and 15h45 for those of you across the pond), our fleet of WeatherBots will send a weather update to Twitter.</p> <p>If you follow these bots, you'll receive those updates wherever you normally get your Twitters; IM, Phone, RSS, or just on the web. So far, we have bots for the following cities (links are to the bots' twitter profiles, for easy friending action): <a href="http://twitter.com/wxboston">Boston</a>, <a href="http://twitter.com/wxbrighton">Brighton</a>, <a href="http://twitter.com/wxchicago">Chicago</a>, <a href="http://twitter.com/wxhelsinki">Helsinki</a>, <a href="http://twitter.com/wxlondon">London</a>, <a href="http://twitter.com/wxla">Los Angeles</a>, <a href="http://twitter.com/wxnyc">New York</a>, <a href="http://twitter.com/wxparis">Paris</a>, <a href="http://twitter.com/wxpdx">Portland</a>, <a href="http://twitter.com/wxsf">San Francisco</a>, <a href="http://twitter.com/wxseattle">Seattle</a>, <a href="http://twitter.com/wxsingapore">Singapore</a>, and <a href="http://twitter.com/wxyvr">Vancouver</a>. If you'd like to see another city, just ask and we'll provide.</p> <p>The source code is available over on Google Code as <a href="http://code.google.com/p/twitter-weather/">Twitter Weather</a>. Kellan and I will be providing follow-up posts (and hopefully talks!) about how we built this, and updates on future improvements, so watch this space, and if you're not already on Twitter, sign up already! We're building an awesome space, and want you to have as much fun as we are.</p>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-24488598839940362112006-12-08T11:55:00.000-08:002006-12-08T15:45:38.134-08:00On Twitter<p>Kathy Sierra has a great post, talking about <a href="http://headrush.typepad.com/creating_passionate_users/2006/12/httpwww37signal.html">Continuous Partial Attention and Twitter</a>. Before you read my response, go read Kellan's excellent <a href="http://laughingmeme.org/articles/2006/12/08/twitter-curve">post</a> on the matter.</p> <p>Twitter is really nothing new, it's just new to the web (and IM/SMS). IRC has been around for ages, and functions in much the same way. Campfire, 37signals' group chat application is a similar application, but more task-focused. So to say that 2006 is the year of the singularity is probably too much of an exaggeration.</p> <p>I held off on using Twitter for a long time, even though I work at Obvious, because it was too much of an attention drain for me. I have a 5 year old <a href="http://www.nokiausa.com/phones/8390">Nokia cell phone</a>, and the SMS experience is one of mind-numbing pain when you receive 15 or 20 SMSes per day (not to mention expensive!). IM, on the other hand, is seamless. Like Kellan, I have verging-on-sub-conscious Growl notifications for IM, and as such I spend less than a second processing each incoming Twitter message.</p> <p>A phone call, on the other hand, can easily eat half an hour for me, because I don't "do" the phone very often. I find it intimidating, because most of the time the interactions involve long hold times, anti-human menus, horrible bureaucracy, etc. Email is more distracting than IM or Twitter, and so on. Calling friends and family is also a major time commitment, especially if we haven't talked in a while.</p> <p>I'm more than willing to put up with certain levels of interruption in order to have that sense that I "know" what's going on around me. I have friends who live far away, and whom I don't speak to on the phone, email, or see regularly. Twitter perfectly fills the gap, and allows us to keep each-other "in the loop", bringing us closer overall.</p> <p>Sure, I could close myself off, and just work all day - but I feel like all these emerging (emergent?) "ambient" communication technologies actually help to make me happier, and feel less alone in our highly abstract and disconnected world. Having "community" is extremely important; far more so than our productivity. Maybe it's just sad that we allow ourselves to live in this paradoxically disconnected online world, "cyberspace" as it were. I like to think of it as just another progression of human adaptation. To say that people are lonelier or happier, more or less fulfilled, busier, or more productive than they were 10, 50, 100, or 500 years ago is a falsehood. We're different, and we're all just trying to <a href="http://www.danah.org/papers/AAAS2006.html">make the best of where we find ourselves</a>.</p>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-85472670243921333302006-11-09T12:14:00.000-08:002006-11-12T11:27:15.721-08:00Announcing Jabber::SimpleJabber::Simple [<a href="http://code.google.com/p/xmpp4r-simple/">src</a>, <a href="http://xmpp4r-simple.rubyforge.org/">doc</a>] is a simple (duh!) Ruby library that aims to make the implementation of basic Jabber functionality trivial. It is an extraction of the Jabber support that was added to <a href="http://twitter.com/">Twitter</a>, and is released under the GPL by <a href="http://obvious.com/">Obvious</a>. A line of code is worth a thousand words, so here is the complete code for sending a simple message to a Jabber user: <pre><code> jabber = Jabber::Simple.new('rex@friendosaurus.com', 'password') jabber.deliver("bront@friendosaurus.com", "Hey! I'm thinking of going Vegetarian - Any suggestions?") </code></pre> Getting incoming messages is just as easy: <pre><code> jabber.received_messages do |msg| puts "#{msg.body}" if msg.type == :chat end </code></pre> You can also set your status, and get information about your friends' statuses: <pre><code> jabber.status(:away, "Eating at the Tree Cafe. I need a ladder.") jabber.presence_updates do |update| friend = update[0] presence = update[2] puts "#{friend.jid} is #{presence.status}" end </code></pre> <h3>Installation</h3> <pre><code> sudo gem install xmpp4r-simple </pre></code> or download the package from <a href="http://rubyforge.org/projects/xmpp4r-simple/">RubyForge</a>. Source code is also <a href="http://code.google.com/p/xmpp4r-simple/">available</a>, licensed under the GPLv2. <h3>Yet Another Jabber Library?</h3> There are a number of existing Jabber libraries for Ruby (<a href="http://jabber4r.rubyforge.org/">jabber4r</a>, <a href="http://home.gna.org/xmpp4r/">xmpp4r</a>, and <a href="http://netxmpp-ruby.jabberstudio.org/">Net::XMPP</a>), so why Jabber::Simple? First off, Jabber::Simple does not aim to replicate any core XMPP protocol functionality present in these libraries &#8212; in fact, Jabber::Simple depends on <a href="http://home.gna.org/xmpp4r/">xmpp4r</a> and the <code>Jabber::Simple#client</code> and <code>Jabber::Simple#roster</code> methods expose all of xmpp4r's awesome functionality. When I started building in Jabber support for <a href="http://twitter.com/">Twitter</a> I'd used <a href="http://adiumx.com/">various</a> <a href="http://apple.com/ichat/">Jabber</a> <a href="http://google.com/talk/">clients</a>, and even set up a simple Jabber server. Writing my own client, however, was a bit more complex. It turns out that the seamless experience of "adding a friend" and chatting with them is (unsurprisingly) comprised of a series of disjoint steps, and fraught with the peril of threads, XML streams, and arcane magic. The available libraries handle these tasks and many more admirably, but lack in elegance. My hope is that Jabber::Simple provides a sufficiently <a href="http://obvious.com/">obvious</a> interface with which to develop tools that use the Jabber protocol. <h3>But Wait! There's More!</h3> Now, you might shy away from writing that really cool chat-bot you've been meaning to write, saying "Wow, this is great, but setting up a Jabber server is a pain." --- but fear not! Go over to <a href="http://google.com/talk/">Google Talk</a> and sign up for an account. Once you're done, use your Google Talk username and password, and start Jabbering. No really, it's that simple. <pre><code> jabber = Jabber::Simple.new("you@gmail.com", "password") </code></pre>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-64226986839833767572006-11-06T23:21:00.000-08:002006-11-06T23:36:03.760-08:00assert_beforeI'm working on a Ruby Jabber client library to hide the numerous machinations and relatively steep learning curve that xmpp4r requires. It's nearly done, and I'm writing tests (it's an extraction from <a href="http://twitter.com/">Twitter</a>'s Jabber support). A problem I was running into was the latency involved with Jabber requests; sending a message is almost instantaneous, but always requires at least a one second sleep before the assertion, sometimes much more (roster updates can be time consuming). I started sprinkling five to ten second sleeps throughout my code, but all of a sudden my tests were taking upwards of a minute to run, and there are only five tests! Here's a snippet that should help with all your variable-latency tests: <pre><code> def assert_before(seconds, &block) error = nil begin Timeout::timeout(seconds) { begin yield rescue => e error = e sleep 0.5 retry end } rescue Timeout::Error raise error end end </code></pre> use it in your tests like so: <pre><code> def test_something_time_consuming_should_succeed_in_at_least_10_seconds assert_before 10.seconds do assert true, time_consuming_task() end end </code></pre> and as soon as your tests pass, the block will exit and continue on, completing your tests as quickly as possible.Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-37837498258199584332006-11-06T20:26:00.000-08:002006-11-06T20:32:18.448-08:00Borat, We Like.I still haven't seen it, but here's what the Guardian <a href="http://film.guardian.co.uk/News_Story/Guardian/0,,1941196,00.html?gusrc=rss&feed=12">has to say</a>: <blockquote>While there had been much early enthusiasm for the film following festival screenings, there were fears that the appetite for a bumbling anti-Semitic, pro-incest fake Kazakh who engages in an extended bout of vigorous nude wrestling with his producer might not be mainstream enough to translate to the box office.</blockquote> Huh? How could there <em>not</em> be enough of an appetite for that?!Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-27883608622328223942006-11-03T22:45:00.000-08:002006-11-03T22:49:18.825-08:00The KnifeAfter seeing this video, I'm totally bummed about missing The Knife. Ray's been talking about it for weeks, but unfortunately they don't do many shows and tickets were selling for (at least) $200. Anyhow, for your viewing enjoyment: <object width="425" height="350"><param name="movie" value="http://www.youtube.com/v/617ANIA5Rqs"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/617ANIA5Rqs" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></object>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-29594750583560786992006-11-03T21:40:00.000-08:002006-11-03T22:50:30.017-08:00.irbrc<code>irb</code> is a wonderful tool; with a few tweaks and additions, though, it becomes essential. I spent too long getting by with just readline support, but today, <em>finally</em>, I added a few of the extensions that I've seen floating around on various ruby blogs. Now my tab completion and history run in overdrive, and the number of extra terminal windows I keep open has been reduced greatly. A quick summary of the features present: <ul> <li>Full <a href="http://tiswww.case.edu/%7Echet/readline/rluserman.html#SEC4">readline</a> support and tab completion</li> <li>Copy-friendly prompt</li> <li>Auto-indentation</li> <li>Persistent history</li> <li><code>Object#local_methods</code>, to view methods unique to an object</li> <li>Colourized output (via wirble)</li> <li>Method finder. e.g., <code>"hello".what?(5) #=> [:length, :size]</code> </li> <li>Colourized inline ri support (either <code>Object#ri(*methods)</code> or <code>ri Object</code>, works best with Ruby 1.8.5's much improved <code>ri</code></code></code></li> <li>Output spooling, via <code>more</code>, <code>less</code> or <code>most</code>. e.g., <code>less { puts really_long_string }</code></li> <li>Simple regular expression helper (<code>/an/.show_match("banana")</code>)</li> <li>Textmate and Vi launching</li> </ul> You can get my .irbrc here: <a href="http://dotfiles.org/%7Elattice/.irbrc">~lattice/.irbc</a>.Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.comtag:blogger.com,1999:blog-7067202814937947569.post-64278714848139499152006-11-03T12:58:00.000-08:002006-11-03T14:36:36.344-08:00MacPorts, a PSAWhen upgrading your ports on OS X, do not use the following command: <pre><code> port upgrade all </pre></code> It doesn't do what you expect. Unless, of course, you want <code>TeXmacs</code> and <code>SimGear</code>. And five hundred of their closest friends. Do this, instead: <pre><code> port upgrade outdated </pre></code>Blainehttp://www.blogger.com/profile/12260514541117400711noreply@blogger.com