<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ross&#183;kaff</title>
	<atom:link href="http://www.rosskaff.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.rosskaff.com</link>
	<description>never stop learning</description>
	<lastBuildDate>Thu, 09 Feb 2012 06:03:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Presentation: Intro to Javascript&#160;MVC</title>
		<link>http://www.rosskaff.com/2012/02/presentation-intro-to-javascript-mvc/</link>
		<comments>http://www.rosskaff.com/2012/02/presentation-intro-to-javascript-mvc/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 06:03:17 +0000</pubDate>
		<dc:creator>rossta</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.rosskaff.com/?p=353</guid>
		<description><![CDATA[Today, I made a brown bag case to my colleagues: let&#8217;s approach client-side development in a more structured, disciplined and flexible way; in other words, add a model-view-controller javascript layer to our web app. Included is some background for the discussion and a brief introduction to Backbone.js. I use the phrase &#8220;MV*&#8221; to embrace various [...]]]></description>
			<content:encoded><![CDATA[<p>Today, I made a brown bag case to my colleagues: let&#8217;s approach client-side development in a more structured, disciplined and flexible way; in other words, add a model-view-controller javascript layer to our web app. Included is some background for the discussion and a brief introduction to Backbone.js. I use the phrase &#8220;MV*&#8221; to embrace various implementations of MVC-like javascript frameworks, most of which have different takes on what object take on the responsibility for hooking up models and views.</p>
<p><a href="http://daftpunkjs.heroku.com/">Brown Bag Presentation: Javascript MV*</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.rosskaff.com/2012/02/presentation-intro-to-javascript-mvc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Toggle Rails Caching in RSpec&#160;Suites</title>
		<link>http://www.rosskaff.com/2011/12/toggle-rails-caching-in-rspec-suite/</link>
		<comments>http://www.rosskaff.com/2011/12/toggle-rails-caching-in-rspec-suite/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 13:43:52 +0000</pubDate>
		<dc:creator>rossta</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.rosskaff.com/?p=343</guid>
		<description><![CDATA[A useful feature of RSpec is the ability to pass metadata to tests and suites and configure the test environment according. For example, Capybara provides :js options to enable the javascript driver for a given spec. Another use case for RSpec metadata is to test the effects of Rails caching in requests. The Rails test environment ships [...]]]></description>
			<content:encoded><![CDATA[<p>A useful feature of RSpec is the ability to pass metadata to tests and suites and configure the test environment according. For example, <a href="https://github.com/jnicklas/capybara">Capybara</a> provides :js options to enable the javascript driver for a given spec. Another use case for RSpec metadata is to test the effects of Rails caching in requests.</p>
<p>The Rails test environment ships with controller caching disabled, which you might not prefer. Otherwise, it may be useful to be able to toggle it on/off during the test run. To provide an optional caching mechanism for your specs, configure an around block:</p>
<p><script type="text/javascript" src="https://gist.github.com/1510261.js?file=caching_config.rb"></script></p>
<p>The around block takes the RSpec example object as an argument. The block is triggered when :caching is detected as a key in an example&#8217;s metadata. The example object provides a number of methods for test introspection, allowing you to make changes before and after calling #run to execute the spec. Here, we are storing the previously set value of ActionContoller::Base.perform_caching, setting it for the local suite, and setting it back to the original value after it completes. </p>
<p>As a result, we now have a simple, explicit mechanism for introducing caching to individual specs and suites:<br />
<script type="text/javascript" src="https://gist.github.com/1510261.js?file=example_spec.rb"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.rosskaff.com/2011/12/toggle-rails-caching-in-rspec-suite/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>When Your Fat Models Need to Go on a Diet, Part&#160;2</title>
		<link>http://www.rosskaff.com/2011/10/when-your-fat-models-need-to-go-on-a-diet-part-2/</link>
		<comments>http://www.rosskaff.com/2011/10/when-your-fat-models-need-to-go-on-a-diet-part-2/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 04:01:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.rosskaff.com/?p=303</guid>
		<description><![CDATA[In part 1 of this post, I talked about using modules to help break source code of large models into smaller, comprehensible pieces. As Ariel Valentin pointed out, we need to do more to lighten up the runtime memory footprint when large models are instantiated. Let&#8217;s imagine we have an application with a User model [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="http://www.rosskaff.com/2011/09/when-your-fat-models-need-to-go-on-a-diet">part 1</a> of this post, I talked about using modules to help break source code of large models into smaller, comprehensible pieces. As <a title="XP in Anger" href="http://blog.arielvalentin.com/" target="_blank">Ariel Valentin</a> pointed out, we need to do more to lighten up the runtime memory footprint when large models are instantiated.</p>
<p>Let&#8217;s imagine we have an application with a <code>User</code> model (might not be a stretch) and we&#8217;re building a page that loads a bunch of user gravatars. Our <code>User</code> model has accumulated a ton of attributes, but we may only need a limited set to render the gravatar properly. We might add a line like this in the controller action to select only the needed attributes:</p>
<p><code>@users = User.select(%w[ id name gravatar_id ]).all</code></p>
<p>Perhaps to make this more readable, we&#8217;ll extract our select statement into a scope in the <code>User</code> model:</p>
<p><code># user.rb<br />
scope :select_gravatar_attributes, select(%w[ id name gravatar_id ])</code></p>
<p># controller action<br />
@users = User.select_gravatar_attributes.all</p>
<p>We&#8217;ll incur less memory overhead during this action at runtime since the app won&#8217;t have to load as much data. The caveat is that our <code>@users</code> won&#8217;t have access to the data we left behind, so we need to take care only to call methods that rely on the data we have actually loaded. It would be easier to test our lighter users if we could treat them as a different type.</p>
<p>&nbsp;</p>
<p>Applying the model-slimming refactoring we discussed in <a href="http://www.rosskaff.com/2011/09/when-your-fat-models-need-to-go-on-a-diet/">part 1</a>, we can extract gravatar related functionality into a <code>UserExtensions::Gravatar</code> module and create a <code>Gravatar::User</code> that inherits from our <code>User</code> model. Furthermore, we can change our <code>select_gravatar_attributes</code> to a <code>default_scope</code> in the subclass, so whenever we grab <code>Gravatar::User</code> from the db, it&#8217;ll have only the attributes we need. Our controller action would now look like this:</p>
<p><code>@users = Gravatar::User.all</code></p>
<p>To put our savings to the test, we can run some basic benchmark tests. I created a sample rails 3.1 app and created ~2000 users records in my development database and ran the <code>rails benchmarker</code> script to load all users both normally and as gravatars. Here are the results:</p>
<p>All users<br />
<a href="http://www.rosskaff.com/wp-content/uploads/2011/10/user-perf-test1.jpg"><img class="alignleft size-full wp-image-319" title="user-perf-test" src="http://www.rosskaff.com/wp-content/uploads/2011/10/user-perf-test1.jpg" alt="" width="401" height="291" /></a></p>
<p>All as gravatars<br />
<a href="http://www.rosskaff.com/wp-content/uploads/2011/10/gravatar-user-perf-test1.jpg"><img class="alignleft size-full wp-image-320" title="gravatar-user-perf-test" src="http://www.rosskaff.com/wp-content/uploads/2011/10/gravatar-user-perf-test1.jpg" alt="" width="404" height="294" /></a></p>
<p>The memory footprint for gravatar users is half of that for our &#8216;fat&#8217; users. Obviously results will vary greatly depending on architecture, application and the attributes selected, but this anecdotal case demonstrates potential for some big wins in instantiating slimmer subclasses of your heavy models.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rosskaff.com/2011/10/when-your-fat-models-need-to-go-on-a-diet-part-2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>When Your Fat Models Need to Go on a&#160;Diet</title>
		<link>http://www.rosskaff.com/2011/09/when-your-fat-models-need-to-go-on-a-diet/</link>
		<comments>http://www.rosskaff.com/2011/09/when-your-fat-models-need-to-go-on-a-diet/#comments</comments>
		<pubDate>Fri, 30 Sep 2011 23:18:37 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.rosskaff.com/?p=290</guid>
		<description><![CDATA[Most Rails apps I&#8217;ve worked on have followed the pattern &#8220;skinny controllers, fat models.&#8221; The controller shouldn&#8217;t have know what attributes and joins to make when asking for data from the models; one line methods calls in controller actions are a thing of beauty. Controller specs are simplified and the complexity of business logic and [...]]]></description>
			<content:encoded><![CDATA[<p>Most Rails apps I&#8217;ve worked on have followed the pattern &#8220;<a href="http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model" title="the buckblogs here">skinny controllers, fat models</a>.&#8221; The controller shouldn&#8217;t have know what attributes and joins to make when asking for data from the models; one line methods calls in controller actions are a thing of beauty. Controller specs are simplified and the complexity of business logic and database access can be stuffed into the models. Fatten&#8217; up those models!</p>
<p>But what happens when your models grow too large? It&#8217;s common to have one or two models (Users and Groups, anyone?) carry a large burden. Over time, we see Ruby files approaching and surpassing thousands of lines and their associated tables accumulating column excess. Before you know it, it&#8217;s time to put your models on a diet. It&#8217;s useful to have some patterns in your tool-belt to start trimming the fat.</p>
<p>A good refactoring step is to pull out modules of related behavior. In the User model, for example, we might extract modules for related instance methods, associations and validations for functional scopes like admin access or group memberships. I prefer to namespace the modules under UserExtensions so it&#8217;s clear, at least in this case, that these are meant for composition of the User model rather than for sharing code across objects. Now ActiveSupport::Concern makes it super-simple to define both instance and class methods in your module and ensure they&#8217;re included properly. (Some good reading on <a href="http://yehudakatz.com/2009/11/12/better-ruby-idioms/">better ruby idioms</a> for <a href="http://www.fakingfantastic.com/2010/09/20/concerning-yourself-with-active-support-concern/">mixing in class and instance methods</a>).</p>
<p><script src="https://gist.github.com/1255232.js?file=user.rb"></script></p>
<p><script src="https://gist.github.com/1255232.js?file=admin.rb"></script></p>
<p>One convention is to place the modules in &#8220;#{model_name}_extensions&#8221; folders in your app/models directory to group the code logically. For example, UserExtensions::Admin would be located at app/models/user_extensions/admin.rb. Breaking out the code in to functional chunks like this is a good first step in downsizing your model files. It also more easily allows  methods and associations to be extracted into other classes/tables.</p>
<p>Added: Check out <a href="http://www.rosskaff.com/2011/10/when-your-fat-models-need-to-go-on-a-diet-part-2/" title="When Your Fat Models Need to Go on a Diet, Part 2">part 2</a> of this post for thoughts on slimming down our models at runtime.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rosskaff.com/2011/09/when-your-fat-models-need-to-go-on-a-diet/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Lean Startup Meetup&#160;Ignited</title>
		<link>http://www.rosskaff.com/2011/06/lean-startup-meetup-ignited/</link>
		<comments>http://www.rosskaff.com/2011/06/lean-startup-meetup-ignited/#comments</comments>
		<pubDate>Thu, 23 Jun 2011 14:21:43 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Lean Startup]]></category>
		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.rosskaff.com/?p=285</guid>
		<description><![CDATA[The NYC Lean Startup Meetup sponsored their first Ignite event last night at Pivotal Labs in Union Square. Fourteen speakers were given five minutes to share their thoughts and lessons learned relating to the lean startup methodology. The catch with Ignite: the slides are fixed in number (20) and auto-advance every 15 seconds. Combine that [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.meetup.com/lean-startup">NYC Lean Startup Meetup</a> sponsored their first Ignite event last night at Pivotal Labs in Union Square. Fourteen speakers were given five minutes to share their thoughts and lessons learned relating to <a href="http://theleanstartup.com/">the lean startup</a> methodology. The catch with Ignite: the slides are fixed in number (20) and auto-advance every 15 seconds. Combine that with a packed house and open bar and the results are fast-paced, high-energy and fun.</p>
<p>A few impressions:</p>
<p><a href="http://twitter.com/ericries">Eris Reis</a> demonstrated how Ghostbusters is about a lean startup at its core&#8230; guys start something on the side, try to turn it into a business from nothing, get their first customer just when the money is about to run out, interesting things start to happen as the business grows.  Perhaps the GBs were lucky that Zul arrived when he did, but real startups don&#8217;t have that luxury&#8230; instead of &#8220;waiting for Zul&#8221;, lean startups need to be more flexible and proactive&#8230;</p>
<p><a href="http://twitter.com/farrahbostic">Farrah Bostic</a> quit her job at an ad agency after trying to apply lean methodology to a business model that wasn&#8217;t set up to interact with customers that way&#8230;</p>
<p>When startups try to do much, it&#8217;s hard to do much well. It may be better to pick one idea to focus on, or as Brittany Laughlin explained about her experiences with here social travel app <a href="http://www.gtrot.com/">gtrot.com</a>, &#8220;It&#8217;s better to be young and simple, than young and stupid.&#8221;</p>
<p>It was inspiring to hear that Yipit took off after a pivot that took days to turnaround. Their first attempt took 9 months to implement, the next, 3 months, but the idea that stuck was built in 3 days at first. They proved their idea with an initially low-tech solution&#8211;including an late night &#8220;crawler&#8221; that involved crawling out of bed at 3 am nightly to copy and paste data&#8211;that they were able to build into something more robust later with more confidence. Founder <a href="http://twitter.com/vacanti">Vin Vacanti</a> challenged the audience, &#8220;If we can prove a business idea in 3 days, why aren&#8217;t you doing it too?&#8221;</p>
<p><a href="http://twitter.com/giffconstable">Giff Constable</a> provided a retrospective on one of his failed ideas: not enough resources, picking a difficult problem&#8230; His talk reinforced the lean notion that it&#8217;s okay to fail; the knowledge gained from our failures is invaluable to our future efforts.</p>
<p>Shout outs to NYC Lean Startup for running a successful event and to Pivotal Labs for hosting.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rosskaff.com/2011/06/lean-startup-meetup-ignited/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Opt-in XSS protection for Rails 3&#160;upgrade</title>
		<link>http://www.rosskaff.com/2011/02/opt-in-xss-protection-for-rails-3-upgrade/</link>
		<comments>http://www.rosskaff.com/2011/02/opt-in-xss-protection-for-rails-3-upgrade/#comments</comments>
		<pubDate>Sat, 26 Feb 2011 05:51:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Weplay]]></category>
		<category><![CDATA[html escaping]]></category>
		<category><![CDATA[Rails 3 upgrade]]></category>
		<category><![CDATA[rails_xss]]></category>
		<category><![CDATA[XSS protection]]></category>

		<guid isPermaLink="false">http://www.rosskaff.com/?p=213</guid>
		<description><![CDATA[When I&#8217;m really hungry, all I want is a Chipotle burrito. It seems like a good idea &#8211; it&#8217;s big, it tastes good and it&#8217;s right there across the street! It&#8217;s not long before I regret taking on that much food in one sitting. So it goes for upgrading Weplay to Rails 3. A fundamental [...]]]></description>
			<content:encoded><![CDATA[<p>When I&#8217;m really hungry, all I want is a Chipotle burrito. It seems like a good idea &#8211; it&#8217;s big, it tastes good and it&#8217;s right there across the street! It&#8217;s not long before I regret taking on that much food in one sitting. So it goes for upgrading <a href="http://www.weplay.com">Weplay</a> to Rails 3.</p>
<p>A fundamental shift in Rails 3 is html escaping by default. A number of posts describe the need for this change, an important tool against cross-site scripting (XSS) attacks. Rather than rely on developers to escape user content where needed, all strings that don&#8217;t originate from Rails (link_to, form_for, etc.) are treated as unsafe. This is a good thing. Unfortunately, for most running Rails 2 apps, automatically html-escaping our views without adjustments results in a hot steaming pile of onscreen view-source dung.</p>
<p><img src="http://www.rosskaff.com/wp-content/uploads/2011/02/The-Redskins-Golf-Team-Weplay.jpg" alt="Weplay home page when html-escaped" width="75%" /></p>
<p>This is exactly what you see the first time you install the recommended <a href="https://github.com/rails/rails_xss">rails_xss</a> plugin to provide Rails 3 XSS protection for your Rails 2 app. Despite the obvious work entailed to get things back to normal, this is another good thing. Making the switch to Rails 3 overnight may not be feasible, but adding XSS protection ahead of time will help smooth the transition.</p>
<p>Except perhaps when your app is large. At the present count, we have over 1500 *.html.erb files in Weplay&#8217;s main repo. We simply can&#8217;t afford to devote the days to focus solely on fixes for excess html escaping in our templates. We need to be able to iterate on this change like everything else; incrementally instead of as an overhaul.</p>
<p>We came up with an alternative: <a href="https://github.com/weplay/rails_xss">we forked rails_xss</a> to <em>disable</em> automatic html escaping by default while still providing the use of &#8220;html safe&#8221; strings and the Erubis ERB template engine. Developers can turn on html escaping locally using the <strong>autoescape</strong> block helper.</p>
<p><script src="https://gist.github.com/844730.js?file=rails_xss"></script></p>
<p>Everything within the helper is escaped. Anything outside the helper is not escaped. Nesting autoescapes is ok: everything inside the outermost invocation is escaped.</p>
<p><script src="https://gist.github.com/844730.js?file=Additional%20uses"></script></p>
<p>The autoescape helper allows us to apply the fixes on a view-by-view basis. We can devote most of our time to building features to help us make money and chip away at templates and partials as they pop up in our workflow. We even have a script to tell us how many files we still need to address.</p>
<p>The key to this change is manipulating the original rails_xss plugin behavior. Rails 3 helpers are composed of the String subclass <a href="http://yehudakatz.com/2010/02/01/safebuffers-and-rails-3-0/">SafeBuffer</a>, which will escape concatenated content not already marked as &#8220;html safe&#8221;.  Internally, calling .html_safe on a string simply sets a flag on the string object and this is flag is checked when adding to a string to SafeBuffer. By monkey-patching String, we disable the automatic escaping by always returning true for the html_safe? check. The autoescape flips on the flag, yields to the content block and flips the flag check back off afterwards. When autoescaping is already turned on, the block is returned as-is to allow nested autoescaping.</p>
<p>There are alternatives. We could all crash on the upgrade (no time!) or we could keep the fully &#8220;escaped&#8221; version of our app in a separate branch, chip away at it, merge occasionally (not fun!).</p>
<p>The opt-in approach works well for our agile mindset of fast incremental improvement and frequent deployment. I recommend using our fork if you have similar needs. It may even help with the heartburn.</p>
<p>Resources</p>
<ul>
<li><a href="https://github.com/rails/rails_xss">rails/rails_xss</a></li>
<li><a href="https://github.com/weplay/rails_xss">weplay/rails_xss</a></li>
<li><a href="http://yehudakatz.com/2010/02/01/safebuffers-and-rails-3-0/">Safe Buffer</a></li>
<li><a href=http://www.stjhimy.com/posts/16-xss-protection">Nice explanation of XSS</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.rosskaff.com/2011/02/opt-in-xss-protection-for-rails-3-upgrade/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Behavior-driven + event-driven: eventmachine +&#160;rspec</title>
		<link>http://www.rosskaff.com/2010/12/behavior-driven-event-driven-eventmachine-rspec/</link>
		<comments>http://www.rosskaff.com/2010/12/behavior-driven-event-driven-eventmachine-rspec/#comments</comments>
		<pubDate>Mon, 27 Dec 2010 04:47:13 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[eventmachine]]></category>

		<guid isPermaLink="false">http://www.rosskaff.com/?p=182</guid>
		<description><![CDATA[A walkthrough example of testing a server-client socket connection through eventmachine with rspec.]]></description>
			<content:encoded><![CDATA[<p>With all the hubbub around <a href="http://nodejs.org/">node.js</a> lately, it&#8217;s been easy to forget established event-driven server-side processing solutions in Ruby. One option is <a href="http://rubyeventmachine.com/">eventmachine</a>, which I recently used to develop a multi-player online sudoku game, <a href="http://rosskaff.github.com/sudokill/">Sudokill</a>, for my Heuristics class at NYU. </p>
<p>As the game designer, I needed to build a game server that could easily handle multiple socket connections to player programs written by my classmates. Leveraging the event-driven nature of eventmachine, I was able to build a server that is fast, efficient and easy to maintain.</p>
<p>A commonly-cited drawback to event-driven programming is that it&#8217;s hard. For starters, we can easily wrap our heads around a procedural approach to a server connecting to a client:<br />
<code>
<ol>
<li>Server waits for client 1</li>
<li>Client attempts to connect to server</li>
<li>Server accepts connection with client 1</li>
<li>Server tells client 1 to wait</li>
<li>Now server waits for client 2</li>
<li>Repeat as before and so on...</li>
</ol>
<p></code></p>
<p>This pattern is familiar: like a cookbook recipe or instructions for building a model airplane, we are well-equpped to handle things one step at a time. With the event model, we think in terms of discrete behaviors instead of ordered steps. We need to identify important events and their responses:</p>
<p><code>
<ul>
<li>Whenever a socket connection is received, say hello</li>
<li>Whenever a message through a socket connection, process it</li>
<li>Whenever a socket connection disconnects, say goodbye</li>
</ul>
<p></code></p>
<p>This model is common for front-end development (e.g. onclick, onmousever, etc.), but the notion of attaching events is not restricted to writing javascript for the DOM. Eventmachine provides some out-of-box hooks for adding behavior to expected events, like accepting socket connections. It also provides methods for defining and triggering our own custom behaviors. </p>
<p>Speaking of behavior: what about behavior-driven development with eventmachine? Absorbing the conceptual leap to programming to events is one challenge, and now, the mechanics of writing tests for them present another.</p>
<p>Let&#8217;s consider how we would test a client player connecting to my game server through a socket. I&#8217;ll build a class called Server which will be responsible for starting the eventmachine when its #start method is called. When a socket connection is made, I want to add the new player to a list of players kept on the server and send the message &#8220;READY&#8221; back to the client. </p>
<p>How would we write an integration test for this with rspec? The test would have to start an instance of my server class and separately initiate a client socket connection. Once the connection is made, then the test assertions can be run. After some digging around, I found some good examples to follow in the Ilya Grigorik&#8217;s eventmachine-backed websocket server, <a href="https://github.com/igrigorik/em-websocket">em-websocket</a>. Here&#8217;s the basic approach:</p>
<p>An eventmachine process runs in a loop: once we start the loop, it will run forever until we trigger the event to stop the loop. All of our eventmachine code will happen in the event loop. We setup the loop by passing our code in a block to the <a href="http://eventmachine.rubyforge.org/EventMachine.html#M000461">run</a> method:<br />
<script src="https://gist.github.com/755550.js?file=The%20event%20loop"></script></p>
<p>So in our test, we&#8217;ll create the event loop with EM.run and pass a block with our test code in which we can start the game server and the socket connection. Once the assertions have been made, we&#8217;ll call EM.stop to end the event loop. Otherwise, it would run forever; we&#8217;d never get to the next test!</p>
<p>An eventmachine socket server can be initiated with the <a href="http://eventmachine.rubyforge.org/EventMachine.html#M000470">start_server</a> method. We&#8217;ll give this method a host and port where it will listen for clients.</p>
<p>We&#8217;ll also use eventmachine&#8217;s <a href="http://eventmachine.rubyforge.org/EventMachine.html#M000473">connect</a> method to make the client socket connection to the server. When a socket connection is made, eventmachine creates an instance of EventMachine::Connection which responds to certain methods representing different phases of the socket connection: after initialization, when a message is received, when the connection is broken, etc. EM.connect accepts a module or class inheriting from EventMachine::Connection which allows us to mix in our app or test logic to the connection. </p>
<p>To take the place of a player client in the test, I&#8217;ve borrowed FakeSocketClient (which subclasses EventMachine::Connection) from the em-websocket test suite and defined it in my spec_helper.rb. The fake client exposes attr_accessors onopen, omessage and onclose that we&#8217;ll treat like callbacks in the test.</p>
<p><script src="https://gist.github.com/754704.js?file=FakeSocketClient"></script></p>
<p>We&#8217;ll assign a proc to the #onopen callback in FakeSocketClient. This proc will be triggered the first time the client socket receives a message. Since we want to the server to send a message when the connection is established, we expect this message to be &#8220;READY&#8221;. In addition, we&#8217;ll assert that there is one player added to the server&#8217;s list of players. Then we stop the event machine.</p>
<p><script src="https://gist.github.com/755460.js?file=eventmachine%20%2B%20rspec%20example"></script></p>
<p>The key for making our rspec assertions: the socket connection between the server and client is accepted after the rest of the code in the EM.run block has been called. The instance FakeSocketClient receives #initialize and #post_init when EM.connect is called, but then the context returns to our test: we can now assign procs to FakeSocketClient&#8217;s onopen, onmessage and onclose callbacks as needed. </p>
<p>The #start method of our server is straightforward. It must start its own event loop and call EM.start_server previously discussed:</p>
<p><script src="https://gist.github.com/755862.js?file=eventmachine%20start_server"></script></p>
<p>Other tests may include multiple client connections where we may need to assert that different messages like &#8220;YOUR TURN&#8221; and &#8220;WAIT YOUR TURN&#8221; are sent to the correct players. </p>
<p>For more reading on the subject of event programming, I recommend <a href="http://pdos.csail.mit.edu/~rtm/papers/dabek:event.pdf">Dabek, et.al, Event-driven Programming for Robust Software</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rosskaff.com/2010/12/behavior-driven-event-driven-eventmachine-rspec/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Heuristics</title>
		<link>http://www.rosskaff.com/2010/12/heuristics/</link>
		<comments>http://www.rosskaff.com/2010/12/heuristics/#comments</comments>
		<pubDate>Sat, 25 Dec 2010 06:19:39 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Computer Science]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.rosskaff.com/?p=164</guid>
		<description><![CDATA[I just completed another semester of grad school at NYU. Progress towards my computer science degree has been slow: this is my fourth year in the program. As a part-time student, one class at a time is all I can handle. This time, the course was Heuristics, which by itself was more than almost anyone [...]]]></description>
			<content:encoded><![CDATA[<p>I just completed another semester of grad school at NYU. Progress towards my computer science degree has been slow: this is my fourth year in the program. As a part-time student, one class at a time is all I can handle. This time, the course was <a href='http://cs.nyu.edu/courses/fall10/G22.2965-001/index.html'>Heuristics</a>, which by itself was more than almost anyone can handle.</p>
<p>At its core, the course is about solving puzzles. What is the shortest route that passes through all the cities (<a href="http://cs.nyu.edu/courses/fall10/G22.2965-001/travelingsalesman.html">Traveling Salesman</a>)? How many injured people around the city can you pick up in your ambulances in time (<a href="http://cs.nyu.edu/courses/fall10/G22.2965-001/ambulance.html">Ambulance Planning</a>)? What strategy is best for winning more area than your opponents (<a href="http://cs.nyu.edu/courses/fall10/G22.2965-001/voronoi.html">Voronoi</a>)? Who&#8217;s the best match across these 30 personality traits (Dating Game)?</p>
<p>Most of these problems fall into the category called NP-hard, which may be roughly defined as the class of problems that are at least as hard as those that can be solved in non-deterministic polynomial time. The more useful way for us to think about the general definition is to say that there is a verifiable best answer to the problem, but it would be very difficult, perhaps impossible, to design a general approach that would find this solution quickly. </p>
<p>Our goal for each problem then was to apply an appropriate set of heuristics: strategies to estimate a solution that would come as close as possible to the best solution in a reasonable amount of time. Two minutes in fact. Every week then, we had write a program to solve a NP-hard problem in competition with our classmates. If the program didn&#8217;t run, we lost. If it went over the two minute time limit, we lost. </p>
<p>Most problems involved interacting with a server via sockets. One student was chosen as the &#8220;architect&#8221; each week. Instead of solving the problem, the architect created an interface and protocol for communicating with the player clients, and a GUI to display the game progress and results. Extra pressure came with this role: if the server didn&#8217;t work or if player clients had difficulty connecting, the competition would be a failure. I chose to be the architect for the final game of the semester, <a href="http://cs.nyu.edu/courses/fall10/G22.2965-001/sudokill.html">Sudokill</a>, a form of competitive Sudoku. I plan to write more about Sudokill in the near future.</p>
<p>By far, this course was the most difficult class I&#8217;ve taken in grad school, both conceptually and regarding the workload. At its peak, I spent 30-40 hours a week preparing for the Monday competition. This was often time spent in the early morning hours before and after work. By the end of the semester, fewer than 50% of students were completing their assignments on time. Despite the burden on my free time, this was also the most fun and rewarding class I&#8217;ve ever taken. It certainly helped that I was allowed to write my programs in Ruby; this is a rare opportunity in department where most of the faculty prefers Java and C++.</p>
<p>I&#8217;ve posted my class solutions in a single project on github:<br />
<a href="https://github.com/rosskaff/heuristics">https://github.com/rosskaff/heuristics</a></p>
<p>My code for the Sudokill game server:<br />
<a href="https://github.com/rosskaff/sudokill">https://github.com/rosskaff/sudokill</a></p>
<p>Check out the game too:<br />
<a href="http://rosskaff.github.com/sudokill/">http://rosskaff.github.com/sudokill</a><br />
<a href="http://cs.nyu.edu/courses/fall10/G22.2965-001/sudokill.html">Game rules</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.rosskaff.com/2010/12/heuristics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Step up to&#160;the soapbox</title>
		<link>http://www.rosskaff.com/2010/09/step-up-to-the-soapbox/</link>
		<comments>http://www.rosskaff.com/2010/09/step-up-to-the-soapbox/#comments</comments>
		<pubDate>Wed, 08 Sep 2010 12:10:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Javascript]]></category>

		<guid isPermaLink="false">http://www.rosskaff.com/?p=145</guid>
		<description><![CDATA[Recently, I cobbled together an entry for the 10K Apart Contest. The contest encouraged participants to build an entirely front-end web application in HTML/CSS/Javascript in under 10 kb of total assets, not including some allowable third party libraries such as jQuery or Prototype. Entries must also leverage HTML5 features, some of which include local storage, [...]]]></description>
			<content:encoded><![CDATA[<p>Recently, I cobbled together an entry for the <a href="http://10k.aneventapart.com/">10K Apart Contest</a>. The contest encouraged participants to build an entirely front-end web application in HTML/CSS/Javascript in under 10 kb of total assets, not including some allowable third party libraries such as jQuery or Prototype. Entries must also leverage HTML5 features, some of which include local storage, the canvas API, and web workers. </p>
<p>Several entries had already been submitted by the time I heard of the contest back in mid-July. I found games, like <a href="http://10k.aneventapart.com/Entry/62">Lines</a>, search engines, to-do lists, and so on. I considered implementing a Flickr slideshow that would make use of the contributions I&#8217;ve made to the <a href="http://github.com/weplay/supersized">supersized</a> jQuery plugin at Weplay, but ultimately decided on a Keynote/Powerpoint alternative. </p>
<p>It&#8217;s called soapbox. The inspiration comes from <a href="http://github.com/schacon/showoff">showoff</a>, which is backed by a server. soapbox provides an in-browser interface to create, preview and present slides with <a href="http://daringfireball.net/projects/markdown/">markdown</a> or markup. Slides are auto-saved to local storage, if available, as json. I sent in <a href="http://10k.aneventapart.com/Entry/361">my 10K Apart entry</a> on the deadline day. You can also find the latest on <a href="http://github.com/rosskaff/soapbox">github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rosskaff.com/2010/09/step-up-to-the-soapbox/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Race Results: Park City Mossman Tri&#160;2010</title>
		<link>http://www.rosskaff.com/2010/08/race-results-park-city-mossman-tri-2010/</link>
		<comments>http://www.rosskaff.com/2010/08/race-results-park-city-mossman-tri-2010/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 00:20:54 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Bio]]></category>
		<category><![CDATA[Triathlon]]></category>

		<guid isPermaLink="false">http://www.rosskaff.com/?p=105</guid>
		<description><![CDATA[2010 Park City Mossman Triathlon &#8211; Olympic Age Group, M 30-34 August 16, 2010 in Seaside Park, Bridgeport, CT ROSS KAFFENBERGER #60 NEW YORK, NY Age: 33 Gender: M Distance Intermediate Clock Time 02:24:27 Overall Place 82 / 360 Gender Place 69 Division Place 6 / 22 Swim 0:23:17 T1 0:01:42 Bike 1:12:41 T2 0:00:53 [...]]]></description>
			<content:encoded><![CDATA[<p>2010 Park City Mossman Triathlon &#8211; Olympic<br />
Age Group, M 30-34<br />
August 16, 2010 in Seaside Park, Bridgeport, CT</p>
<p><a href="http://wepl.us/eNc4">ROSS KAFFENBERGER</a> #60<br />
NEW YORK, NY<br />
Age: 33 Gender: M</p>
<p>Distance	Intermediate<br />
Clock Time	02:24:27<br />
Overall Place	82 / 360<br />
Gender Place	69<br />
Division Place	6 / 22<br />
Swim   0:23:17<br />
T1       0:01:42<br />
Bike	   1:12:41<br />
T2       0:00:53<br />
Run	   0:45:51</p>
<p>Swim rank 67, pace 1:23 min/100 yds<br />
Bike rank 126, pace 2:55 min/mi<br />
Run rank 85, pace 7:23 min/mi</p>
]]></content:encoded>
			<wfw:commentRss>http://www.rosskaff.com/2010/08/race-results-park-city-mossman-tri-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

