<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>Hi, my name is Ben and I’m the co-founder and CTO of Mobile Commons in New York City.  

This is my professional tumblelog.  Expect to find lots of writing about open source, Ruby, mobile technology, and the like.

If you’re more interested in pictures of urban chickens, beagles, or my wife, you should probably be reading http://benjaminste.in instead.</description><title>Benjamin Ste.in Pro</title><generator>Tumblr (3.0; @benjaminsteinpro)</generator><link>http://pro.benjaminste.in/</link><item><title>Lego Mindstorm Codecs Added to ffmpeg</title><description>&lt;a href="http://git.ffmpeg.org/?p=ffmpeg;a=commit;h=78bf5852b521e41b64e2c30b363ccb3bcc313afe"&gt;Lego Mindstorm Codecs Added to ffmpeg&lt;/a&gt;: &lt;p&gt;Open source is so awesome.  So are nerds.&lt;/p&gt;</description><link>http://pro.benjaminste.in/post/849234035</link><guid>http://pro.benjaminste.in/post/849234035</guid><pubDate>Fri, 23 Jul 2010 07:42:43 -0400</pubDate></item><item><title>Demo of Scary Vulnerability Using Safari Autofill</title><description>&lt;a href="http://ha.ckers.org/weird/safari_autofill.html"&gt;Demo of Scary Vulnerability Using Safari Autofill&lt;/a&gt;: &lt;p&gt;Brilliant + terrifying.&lt;/p&gt;
&lt;p&gt;Visit the above link in Safari.  It’s just a demo of the vulnerability; nothing bad will happen. &lt;/p&gt;</description><link>http://pro.benjaminste.in/post/845558319</link><guid>http://pro.benjaminste.in/post/845558319</guid><pubDate>Thu, 22 Jul 2010 12:00:52 -0400</pubDate></item><item><title>Can I get a w00t w00t‽</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_l5wwzu8byV1qadru1o1_500.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Can I get a w00t w00t‽&lt;/p&gt;</description><link>http://pro.benjaminste.in/post/840918336</link><guid>http://pro.benjaminste.in/post/840918336</guid><pubDate>Wed, 21 Jul 2010 10:45:30 -0400</pubDate></item><item><title>Two fantastic tidbits from Ars on the recent zero-day Window’s exploit that takes advantage of...</title><description>&lt;p&gt;Two fantastic tidbits from Ars on the &lt;a href="http://arstechnica.com/microsoft/news/2010/07/new-windows-shortcut-zero-day-exploit-confirmed.ars"&gt;recent zero-day Window’s exploit&lt;/a&gt; that takes advantage of a flaw in Windows shortcuts.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;The best option for mitigating the flaw is to disable Windows’ ability to show shortcuts’ icons. However, this mitigation comes at some cost; it removes all the icons from the Start menu, for example, which is sure to be detrimental to usability.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;span&gt;Microsoft doesn’t list Windows 2000 or Windows XP Service Pack 2 as vulnerable, but this is because they are no longer supported—they are just as vulnerable as more recent versions, but will not receive a patch.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Sigh.&lt;/p&gt;</description><link>http://pro.benjaminste.in/post/836184937</link><guid>http://pro.benjaminste.in/post/836184937</guid><pubDate>Tue, 20 Jul 2010 08:16:02 -0400</pubDate></item><item><title>hugehuge:

True.
</title><description>&lt;img src="http://30.media.tumblr.com/tumblr_l59sb6gy7r1qz9etso1_400.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;a href="http://hugehuge.tumblr.com/post/787731901/true"&gt;hugehuge&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;True.&lt;/p&gt;
&lt;/blockquote&gt;</description><link>http://pro.benjaminste.in/post/789255893</link><guid>http://pro.benjaminste.in/post/789255893</guid><pubDate>Fri, 09 Jul 2010 08:07:24 -0400</pubDate></item><item><title>No really, Fluid is open source</title><description>&lt;a href="http://fluidapp.com/blog/2010/06/07/no-really-fluid-is-open-source/"&gt;No really, Fluid is open source&lt;/a&gt;: &lt;p&gt;This is awesome.  Todd Ditchendorf open-sourced &lt;a href="http://github.com/itod/fluid"&gt;Fluid.app on GitHub&lt;/a&gt;.  So what are you waiting for?  &lt;/p&gt;</description><link>http://pro.benjaminste.in/post/681628671</link><guid>http://pro.benjaminste.in/post/681628671</guid><pubDate>Wed, 09 Jun 2010 19:29:13 -0400</pubDate></item><item><title>New in Campfire: Drag and drop uploading</title><description>&lt;a href="http://productblog.37signals.com/products/2010/04/new-in-campfire-drag-and-drop-uploading.html"&gt;New in Campfire: Drag and drop uploading&lt;/a&gt;: &lt;p&gt;Yes!&lt;/p&gt;</description><link>http://pro.benjaminste.in/post/524652700</link><guid>http://pro.benjaminste.in/post/524652700</guid><pubDate>Thu, 15 Apr 2010 21:55:43 -0400</pubDate></item><item><title>Pretty interesting post from Percona this week about the cost of...</title><description>&lt;img src="http://29.media.tumblr.com/tumblr_l0m1a8Ygan1qadru1o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Pretty interesting post from Percona this week about the cost of scaling out MySQL.  They compared the &lt;a href="http://www.mysqlperformanceblog.com/2010/04/08/fast-ssd-or-more-memory/"&gt;cost/benefit of increasing memory vs switching to an SSD&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The above graph is a little confusing at first, but take a look at the 6GB point on the x-axis.  By switching to an SSD, you can get a 5x speed boost (TPS).  To do the same thing with RAM, you’d have to add another 10GB.&lt;/p&gt;
&lt;p&gt;Anecdotally we all knew &lt;a href="http://www.marco.org/379922349"&gt;SSDs improve performance&lt;/a&gt;, but it’s great to see someone throw some numbers behind that claim. Of course there are a million YMMV caveats here (data size, read-write ratio, active data vs historical, etc) but it’s always good to have alternative ways to scale out a single host that don’t just involve throwing RAM at it.&lt;/p&gt;</description><link>http://pro.benjaminste.in/post/508158369</link><guid>http://pro.benjaminste.in/post/508158369</guid><pubDate>Fri, 09 Apr 2010 08:56:31 -0400</pubDate></item><item><title>OS X Geek Tip of the Day</title><description>&lt;p&gt;When OS X Disk Utility tells you that your disk has “issues” and you must boot up from a system disk and run Disk Utility again, you can simply boot in single-user mode by holding down command-S during bootup and run `fsck -fy` at the command prompt. It does the same thing.&lt;/p&gt;
&lt;p&gt;Now there’s no need to (a) look for your OS X install disk or (b) wait the 10 minutes for your system to boot off a DVD.&lt;/p&gt;</description><link>http://pro.benjaminste.in/post/480887915</link><guid>http://pro.benjaminste.in/post/480887915</guid><pubDate>Mon, 29 Mar 2010 00:27:18 -0400</pubDate></item><item><title>"Never mind that real businesses track all of their data in SQL databases that scale just fine…..."</title><description>“Never mind that real businesses track all of their data in SQL databases that scale just fine… By replacing MySQL or Postgres with a different, new data store, you have traded a well-enumerated list of limitations and warts for a newer, poorly understood list of limitations and warts, and that is a huge business risk… The sooner your company admits this, the sooner you can get down to some real work.”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;You said it, &lt;a&gt;Ted Dziuba&lt;/a&gt;!&lt;/em&gt;</description><link>http://pro.benjaminste.in/post/480881156</link><guid>http://pro.benjaminste.in/post/480881156</guid><pubDate>Mon, 29 Mar 2010 00:23:56 -0400</pubDate></item><item><title>Did you know that you can specify an IP address in your browser using a base other than base 10?...</title><description>&lt;p&gt;Did you know that you can specify an IP address in your browser using a base other than base 10?  For example, the following are all equivalent representations of 66.102.13.99 (one of Google’s IPs)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a&gt;&lt;a href="http://0x42.0x66.0x0d.0x63"&gt;http://0x42.0x66.0x0d.0x63&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a&gt;http://0x42660d63&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a&gt;http://1113984355&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a&gt;&lt;a href="http://00000102.00000146.00000015.00000143"&gt;http://00000102.00000146.00000015.00000143&lt;/a&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;From a post on &lt;a&gt;Viruslist&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;Now, by itself, this isn’t terribly interesting from a technical perspective; this “feature” of IP specification has been around for quite a while.&lt;/blockquote&gt;
&lt;blockquote&gt;What is interesting is that due to the relative obscurity of using such methods to denote an IP or URL, it is quite feasible that existing security products do not correctly identify the URLs as valid or flag them as malicious when they point to existing known bad websites.&lt;/blockquote&gt;
&lt;p&gt;In other words, known malicious sites may be able to sneak through web filters because the different representations aren’t recognized.&lt;/p&gt;</description><link>http://pro.benjaminste.in/post/470869743</link><guid>http://pro.benjaminste.in/post/470869743</guid><pubDate>Wed, 24 Mar 2010 16:52:18 -0400</pubDate></item><item><title>Counting down the days until a VZW Nexus One or HTC Incredible. </title><description>&lt;img src="http://28.media.tumblr.com/tumblr_kzp68yvroO1qadru1o1_400.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Counting down the days until a VZW Nexus One or HTC Incredible. &lt;/p&gt;</description><link>http://pro.benjaminste.in/post/466100409</link><guid>http://pro.benjaminste.in/post/466100409</guid><pubDate>Mon, 22 Mar 2010 15:02:58 -0400</pubDate></item><item><title>"Too many tables; MySQL can only use 61 tables in a join"</title><description>“Too many tables; MySQL can only use 61 tables in a join”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;AKA You’re Doing it Wrong&lt;/em&gt;</description><link>http://pro.benjaminste.in/post/439880371</link><guid>http://pro.benjaminste.in/post/439880371</guid><pubDate>Wed, 10 Mar 2010 18:43:36 -0500</pubDate></item><item><title>Huge CSV Data Exports in Rails</title><description>&lt;p&gt;I’m a strong believer in data portability for software as a service applications.  As a consumer, I never want to use a service that won’t let me get my data out.  And as a provider, I’d much prefer to compete on features, quality, customer service, etc than on locking in customers.   Additionally,  it takes a lot of hubris to assume that your application can provide all the analysis a customer may want to do with her data.  Letting customers import data into Excel or a similar tool is incredibly valuable.&lt;/p&gt;
&lt;p&gt;At &lt;a href="http://www.mobilecommons.com"&gt;Mobile Commons&lt;/a&gt;, we have a ton of data that customers may want to export.  User profiles, text messages, donations, phone call records, etc.  And customers want to use different query parameters for their export.  For example, pull every constituent in New York that has opted in to a particular advocacy campaign and donated money.&lt;/p&gt;
&lt;p&gt;This basic idiom repeats itself over and over again in our application:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A customer pulls up a page with a customizeable set of search parameters&lt;/li&gt;
&lt;li&gt;An HTML view displays the data with pagination&lt;/li&gt;
&lt;li&gt;A CSV export button enables them to download the data, but obviously without pagination this time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In Rails, this is pretty easy to accomplish with respond_to blocks.  We setup the ActiveRecord finders, then return the appropriate content type:&lt;/p&gt;
&lt;p&gt;For example, consider the following URL: &lt;a href="http://foo.example.com/articles/123/comments?published=true&amp;after=2010-01-01&amp;order=updated_at"&gt;http://foo.example.com/articles/123/comments?published=true&amp;after=2010-01-01&amp;order=updated_at&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;
class CommentsController
  def index
    finder = current_user.articles.find(params[:article_id]).comments
    finder = finder.published if params[:published] = true
    finder = finder.scoped(:conditions=&gt;'created_at &gt; ?', params[:after])
    finder = finder.scoped(:order=&gt;params[:order_by])
    respond_to do |format|
      format.html do
        finder.paginate( params[:page])
      end
      format.csv do
        send_csv finder.all.to_csv
      end
    end
  end
end
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;This works quite well.  The code is DRY and easy to read.  The problem comes when the number of comments grows large.  Let’s say we have 1,000 comments in the database (for example, if we become the first google result for “&lt;a href="http://www.readwriteweb.com/archives/facebook_wants_to_be_your_one_true_login.php"&gt;facebook login&lt;/a&gt;”).  The pagination version still works fine. We show 10 on a page and let the user click through lots of pages. But the CSV version falls flat as we try to pull 1,000 records from the database at once on every request.&lt;/p&gt;
&lt;p&gt;No problem!  This is a perfect opportunity for asychronous processing.  We push a message onto a queue, run the report in the background, and provide a callback URL for the user to pickup the CSV when it’s complete.&lt;/p&gt;
&lt;p&gt;This approach works great, but makes for an interesting architectural decision: where should the finder logic live?  It seemed like the controller was a good place for it, but now we want to access it from another process that knows nothing about MVC.  &lt;i&gt;You probably don’t realize how much business logic is implicitly encoded in your routes until you try something like this&lt;/i&gt;.  For example, how did the current_user variable get set?  Maybe by parsing the subdomain?  And how do we know what article_id is?  We extracted it from the URL path.&lt;/p&gt;
&lt;p&gt;Suddenly you realize that repackaging that logic to be used in both places and remain DRY may not be trivial.  For one controller it’s not so bad, but remember that  you may have this idiom repeated over and over in 20 different controllers, each with their own routes and query params.  The question really becomes: what message should you put on the queue so that your workers don’t all need custom duplicate logic?&lt;/p&gt;
&lt;p&gt;We ended up taking an rather clever approach to this problem (thanks, &lt;a href="http://justinleitgeb.com/"&gt;Justin&lt;/a&gt;).  We already have code that works when it’s a web request.  What if we just serialize the URL and HTTP params and put them on the queue.  Our worker can pick them up and just call the controller method directly.&lt;/p&gt;
&lt;p&gt;Rails already has this packaged nicely for us with the &lt;a href="http://api.rubyonrails.org/classes/ActionController/Integration/Session.html"&gt;ActionController::Integration::Session&lt;/a&gt; class, which is typically used for integration testing.&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;
#first deserialize the message to a hash object
path   = message[:path]
params = message[:params]
app = ActionController::Integration::Session.new
app.host! "foo.example.com"
app.get(path, params)
csv = app.response.body
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Works like a charm!  We go through the same code path as a regular web request, but we do it all in-process.  We never go over the wire.  Suddenly you don’t care if the process takes 2 seconds or 2 minutes.  It’s running happily in the background and you’re good to go.&lt;/p&gt;
&lt;p&gt;Then days go by, then the weeks.  Suddenly your comment thread has gone from 1,000 records to 10,000 records.  The background job gets slower and slower.  Which is okay, but you notice it’s using more and more machine resources.&lt;/p&gt;
&lt;p&gt;What’s happening?  Well, a good guess is that finder.all is putting all 10,000 ActiveRecord objects into memory at once, which consumes a ton of resources.  If you haven’t read the &lt;a href="http://www.engineyard.com/blog/2009/thats-not-a-memory-leak-its-bloat/"&gt;Engine Yard post on memory bloat&lt;/a&gt;, I highly recommend it.&lt;/p&gt;
&lt;p&gt;No problem!  Rails 2.3 ships with easy utility functions &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/Batches/ClassMethods.html"&gt;find_in_batches &amp; find_each&lt;/a&gt; which pulls 1,000 records at a time and iterates through them all.&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;
format.csv do
  csv = ""
  finder.all.find_each do |records|
    csv &lt;&lt; records.to_csv
  end
  send_csv csv
end
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;Great!  Memory usage plummets and everything is honky dory.&lt;/p&gt;
&lt;p&gt;Then days go by, then the weeks.  Suddenly your comment thread has gone from 10,000 records to 100,000 records.  The background job gets slower and slower.  Which is okay, but you notice it’s using more and more machine resources.&lt;/p&gt;
&lt;p&gt;Wait, what?  Why did you repeat that?  What happened?  I thought we fixed that.&lt;/p&gt;
&lt;p&gt;Yeah, me too.  But suddenly our export started taking forever and using 1GB+ of memory.  What the deuce?  find_each should have solved this problem.  We tested the export code over and over.  We couldn’t reproduce the problem.  We had unit tests and integration tests and load tests. We tried in IRB and rake tasks and just couldn’t reproduce.&lt;/p&gt;
&lt;p&gt;After much investigation and a great tip from &lt;a href="http://www.quirkey.com"&gt;Aaron Quint&lt;/a&gt;, we discovered a nasty little gotcha:  in Rails 2, &lt;i&gt;the ActiveRecord cache is enabled automatically for all controller actions&lt;/i&gt; (&lt;a href="http://dev.rubyonrails.org/changeset/6189"&gt;&lt;a href="http://dev.rubyonrails.org/changeset/6189"&gt;http://dev.rubyonrails.org/changeset/6189&lt;/a&gt;&lt;/a&gt;).  Because we were calling app.get in our worker task, it was automatically loading the query cache.  So every instance of a Comment was being cached, all 100,000 of them, even if we were only finding 1,000 at a time.  The problem only showed up when called via the controller because the cache is disabled by default everywhere else.&lt;/p&gt;
&lt;p&gt;Turns out the problem is trivially fixable by wrapping find_each in an uncached{} block:&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;
format.csv do
  csv = ""
  Comment.uncached do
    finder.all.find_each do |records|
      csv &lt;&lt; records.to_csv
    end
  end
  send_csv csv
end
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;And voila!  We now have a background task that calls a single bit of DRY controller code, processes in batches, and doesn’t use a lot of memory.  Wawaweewa!&lt;/p&gt;</description><link>http://pro.benjaminste.in/post/437368566</link><guid>http://pro.benjaminste.in/post/437368566</guid><pubDate>Tue, 09 Mar 2010 15:27:54 -0500</pubDate></item><item><title>Admit It, Microsoft: You Suck at the Web – GigaOM</title><description>&lt;a href="http://gigaom.com/2010/01/30/admit-it-microsoft-you-suck-at-the-web/"&gt;Admit It, Microsoft: You Suck at the Web – GigaOM&lt;/a&gt;: &lt;p&gt;Let’s see… 60% of the browser market, one of the top 3 most visited web sites, one of the top 3 search engines, and $40B in cash…&lt;/p&gt;
&lt;p&gt;I would hate to see what things would look like if they were just “pretty good at the web.”&lt;/p&gt;</description><link>http://pro.benjaminste.in/post/370570255</link><guid>http://pro.benjaminste.in/post/370570255</guid><pubDate>Thu, 04 Feb 2010 08:53:48 -0500</pubDate></item><item><title>Pratik has a very thorough and well written post about the upcoming changes to the ActiveRecord...</title><description>&lt;p&gt;Pratik has a very thorough and well written post about the &lt;a href="http://m.onkey.org/2010/1/22/active-record-query-interface"&gt;upcoming changes to the ActiveRecord finder methods in Rails 3.1 and 3.2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Specifically, the current options parameter is going to be removed in favor of method chaining.&lt;/p&gt;
&lt;p&gt;For example,&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;Car.all(:conditions=&gt;{:color=&gt;'black'}, :order=&gt;'cars.price DESC', :limit=&gt;10)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;will be replaced by:&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;Car.where(:color =&gt; 'black').order('cars.price DESC').limit(10)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While I do think the new syntax looks nice, my first thought was “how much time is this going to take to upgrade our app”&lt;/p&gt;
&lt;pre&gt;$ grep ":conditions" app lib vendor/gems vendor/plugins | wc -l
350&lt;/pre&gt;
&lt;p&gt;Okay, so that pretty much means we’re not moving to the new syntax any time soon.  We obviously rely heavily on the exisiting :conditions syntax.  There will be an officially supported plugin to keep the old-style, and I applaud the core team for doing that.&lt;/p&gt;
&lt;p&gt;We have become quite fond of building up an array of options to pass to finder methods.  This idiom works incredibly well when deal with user-defined queries.  Consider an example where a user can query for their social graph.&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;
Class User
  has_many :relationships
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now consider a web interface to query for friends.  The user can sort by name (the default) or age, can choose to see 10, 20, or all of them, and can choose to only see men, women or both.  Here’s how I would code that up (ignoring sanitization for now)*:&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;options={}
options[:order]=params[:order] if params[:order]
options[:limit]=params[:limit] if params[:limit]
options[:conditions]={:gender=&gt;params[:gender]} if params[:gender]
user.relationships.all options
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;How would you do that with the new syntax?  Well, instead of building up an array of options, you would need to conditionally pass messages:&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;relationships = user.relationships
relationships = relationships.limit(params[:limit]) if params[:limit]
relationships = relationships.order(params[:order]) if params[:order]
relationships = relationships.where(:gender=&gt;params[:gender] ) if params[:gender]
relationships.all&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;They are both about the same amount of code, and will generate the SQL under the hood. But the latter requires you understand the way ActiveRecord lazy loads associations and handles message.  In this case, I much prefer the former; building up options and passing them to a finder is a much simpler concept.&lt;/p&gt;
&lt;p&gt;* NB You can’t simply do this:&lt;/p&gt;
&lt;pre&gt;&lt;code class="ruby"&gt;user.relationships.limit(params[:limit]).order(params[:order]).where(:gender=&gt;params[:where])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;because all the params are optional. As designed, these queries will use the default values from the has_many association. Passing in :gender=&gt;nil is very different than the default.&lt;/p&gt;</description><link>http://pro.benjaminste.in/post/353120660</link><guid>http://pro.benjaminste.in/post/353120660</guid><pubDate>Mon, 25 Jan 2010 16:31:53 -0500</pubDate></item><item><title>kevin:guillee:


Star Wars opening crawl, using only HTML &amp;...</title><description>&lt;img src="http://24.media.tumblr.com/tumblr_ktut57zrWg1qz4ueho1_500.png"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;a href="http://wtfispantone.com/post/344383890/guillee-im-done-star-wars-opening-crawl"&gt;kevin&lt;/a&gt;:&lt;a href="http://blog.gesteves.com/post/261593774/im-done-star-wars-opening-crawl-using-only-html"&gt;guillee&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://www.gesteves.com/experiments/starwars.html"&gt;Star Wars opening crawl&lt;/a&gt;, using only HTML &amp; CSS.&lt;/p&gt;
&lt;p&gt;Caveats: It only works in Snow Leopard in Safari 4.0.4 and the &lt;a href="http://nightly.webkit.org/"&gt;WebKit nightly&lt;/a&gt;. Nothing else supports the CSS &lt;a href="http://webkit.org/blog/386/3d-transforms/"&gt;3D transforms&lt;/a&gt; and &lt;a href="http://webkit.org/blog/324/css-animation-2/"&gt;animations&lt;/a&gt; I used, but I just wanted to see if it could be done.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;Lovin’ HTML5. Pretty much everywhere, it’s gonna be hot.&lt;/p&gt;</description><link>http://pro.benjaminste.in/post/344392998</link><guid>http://pro.benjaminste.in/post/344392998</guid><pubDate>Wed, 20 Jan 2010 10:03:04 -0500</pubDate></item><item><title>From Charles Nutter: “Lately my interest in JRuby on...</title><description>&lt;img src="http://26.media.tumblr.com/tumblr_kwiqxbsMYv1qadru1o1_400.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;From &lt;a href="http://blog.headius.com/2010/01/busy-week-jruby-with-android-maven-rake.html"&gt;Charles Nutter&lt;/a&gt;: “Lately my interest in JRuby on Android has increased. I realized very recently that JRuby is just about the only mainstream JVM languge that can create *new* code while running on the device, which opens up a whole host of possibilities. It is not possible to implement an interactive shell in Groovy or Scala or Clojure, for example, since they all must first compile code to JVM bytecode, and JVM bytecode can’t run on the Dalvik VM directly.”&lt;/p&gt;
&lt;p&gt;That’s pretty dope. Seems like a fun project to play with to satisfy your weekend hacking cravings.&lt;/p&gt;</description><link>http://pro.benjaminste.in/post/343370135</link><guid>http://pro.benjaminste.in/post/343370135</guid><pubDate>Tue, 19 Jan 2010 19:05:35 -0500</pubDate></item><item><title>Speaking Schedule: Jan 19th @ Pivotal Labs in NYC</title><description>&lt;p&gt;I’ll be speaking this Tuesday at Pivotal’s NYC office about architecting successful software platforms that are heavily reliant on (inherently unreliable) 3rd party web services and services in the cloud.&lt;/p&gt;
&lt;p&gt;Here’s the abstract:&lt;/p&gt;
&lt;blockquote&gt;Beyond the Hype: What it &lt;i&gt;Really&lt;/i&gt; Takes to Build a Technology Business on the Cloud&lt;br/&gt;&lt;br/&gt;After the marketing and sales people leave the room, what does it &lt;i&gt;really&lt;/i&gt; take to run a successful business relying on the cloud? Using real world use-cases, Mobile Commons CTO Benjamin Stein discusses the unique challenges of building a company reliant on 3rd party APIs, including vendor selection, system architecture, production support, and the factors that determine customer loyalty.&lt;/blockquote&gt;</description><link>http://pro.benjaminste.in/post/339402686</link><guid>http://pro.benjaminste.in/post/339402686</guid><pubDate>Sun, 17 Jan 2010 12:59:27 -0500</pubDate></item><item><title>100% of all Browser Certificate Warnings are from Legitimate Sites</title><description>&lt;p&gt;This is just another interesting tidbit from the podcast this morning:&lt;/p&gt;
&lt;p&gt;Setting up SSL properly is really hard and letting an SSL certificate accidentally expire is really easy.  I think every web developer ever has had a problem with SSL at some point in their career.&lt;/p&gt;
&lt;p&gt;On the other hand, malicious web sites work very hard to make sure they look legit.  Either they don’t use SSL at all, or they make sure their certificate appears kosher.  No malicious sites use mismatched certificates.&lt;/p&gt;
&lt;p&gt;In other words, we can assume that almost 100% of all browser certificate warnings are actually from &lt;i&gt;legitimate&lt;/i&gt; sites.  Weird, right?&lt;/p&gt;</description><link>http://pro.benjaminste.in/post/331110575</link><guid>http://pro.benjaminste.in/post/331110575</guid><pubDate>Tue, 12 Jan 2010 16:39:29 -0500</pubDate></item></channel></rss>
