<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>m4rc.io</title>
        <link>http://m4rc.io/</link>
        <atom:link href="http://m4rc.io/rss.xml" rel="self" type="application/rss+xml" />
        <description>Old Man Yells at Cloud</description>
        <language>en-us</language>
        <pubDate>Sat, 08 Mar 2014 15:19:12 -0800</pubDate>
        <lastBuildDate>Sat, 08 Mar 2014 15:19:12 -0800</lastBuildDate>
        
            <item>
                <title>Definitely Maybe</title>
                <link>http://m4rc.io/2014/03/08/definitely-maybe.html</link>
                <pubDate>Sat, 08 Mar 2014 00:00:00 -0800</pubDate>
                <author>marc@badfriend.org (Marc Bollinger)</author>
                <guid>http://m4rc.io/2014/03/08/definitely-maybe</guid>
                <description>&lt;p&gt;Over the past few months, I've spent spent most of my time settling into my new (well, now not-so-new) role from working in backend Web architecture in .NET to building out data warehousing and analysis systems. It's quite a difference, not least of which going from the B2B world to the massive online B2-Web-at-large world--though most &quot;full-stack engineer&quot; work can be somewhat agnostic to the differences, if you're careful about your architecture.&lt;/p&gt;

&lt;p&gt;I've also been thinking along the way about blogging in general. During the intervening months since my last post, I've tried to rethink what purpose I'm trying to serve, as well as looking at examples of bloggers at the extremes of style, while still staying within the bounds of tech. Notable examples include &lt;a href=&quot;http://ayende.com/blog/archive/2007/6&quot;&gt;Ayende's&lt;/a&gt; insane month of June, 2007, in which he wrote &lt;strong&gt;150 blog posts&lt;/strong&gt; (more than I'm sure I tweet most months), and &lt;a href=&quot;http://steve-yegge.blogspot.com/2012_10_01_archive.html&quot;&gt;Steve Yegge&lt;/a&gt;, who wrote the longest review of Borderlands 2 I'm sure is in existence--this is somewhat uncharacteristic; he's one of my go-to reads for tech interviewers and interviewees--but hasn't written anything publicly for about 15 months. I'm not sure where I'll eventually fall over time (though I lean, as a reader, toward the Yegge model), but I have settled on some topics and themes for the forthcoming months, attempting to be both less and more pretentious.&lt;/p&gt;

&lt;p&gt;Oh, and before I forget, relating to working at Lumos, I'd like to just put it on the Web here that &lt;strong&gt;R is the PHP of data analysis&lt;/strong&gt;. I've mentioned the comparison to friends, and it's like watching them achieve a lesser form of Illumination in front of me. That shit looks like its API has been &lt;a href=&quot;http://news.php.net/php.internals/70691&quot;&gt;cobbled together over decades by non-programmers&lt;/a&gt;, and I'm sure that's somewhere close to the truth.&lt;/p&gt;

&lt;h3&gt;Probabilistic data structures&lt;/h3&gt;

&lt;p&gt;So one direction that I've decided to go is to delve into describing, providing motivation for, and implementing probabilistic data structures. It's somewhat self-serving, and in the case of Bloom filters, there already has been quite a lot said, though I suspect even those have not yet been exhausitively evangelized. My basic model for this is Kyle Kingsbury's fantasically excellent &lt;a href=&quot;http://aphyr.com/tags/jepsen&quot;&gt;Jepsen&lt;/a&gt; series on exploring partition tolerance and recovery models for modern distributed databases. If you aren't already reading along, it comes highly, highly recommended. Similarly, his series on &lt;a href=&quot;http://aphyr.com/tags/Clojure-from-the-ground-up&quot;&gt;Clojure from the ground up&lt;/a&gt; is phenomenal, and not just for its lucidity or technical merit; here's paragraph 2:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Science, technology, engineering, and mathematics are deeply rewarding fields, yet few women enter STEM as a career path. Still more are discouraged by a culture which repeatedly asserts that women lack the analytic aptitude for writing software, that they are not driven enough to be successful scientists, that it’s not cool to pursue a passion for structural engineering. Those few with the talent, encouragement, and persistence to break in to science and tech are discouraged by persistent sexism in practice: the old boy’s club of tenure, being passed over for promotions, isolation from peers, and flat-out assault. This landscape sucks. I want to help change it.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;How amazing is this guy?&lt;/em&gt; Anyway, similar to naming his series 'Jepsen' after Carly Rae Jepsen's &lt;em&gt;&quot;Call Me, Maybe&quot;&lt;/em&gt;, my project's working title is going to be 'Gallagher', after the Gallagher brothers of Oasis, whose debue albume was &lt;a href=&quot;http://en.wikipedia.org/wiki/Definitely_Maybe&quot;&gt;&quot;Definitely Maybe&quot;&lt;/a&gt;, which seems an apt name for a walkthrough of probabilistic data structures.&lt;/p&gt;

&lt;p&gt;This is certainly going to take awhile to read, ingest, synthesize, and write all of this, but I imagine the order will go something like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jasondavies.com/bloomfilter/&quot;&gt;Bloom filters&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;A lot examples already exist of this, and some excellent ones even &lt;a href=&quot;http://www.michaelnielsen.org/ddi/why-bloom-filters-work-the-way-they-do/&quot;&gt;go into mathematical detail&lt;/a&gt;, proving their efficacy, but these are &lt;em&gt;so prevalent&lt;/em&gt; in large-scale systems, often to speed tasks that &lt;a href=&quot;https://blog.liveramp.com/2013/04/03/bloomjoin-bloomfilter-cogroup/&quot;&gt;are not, intrinsically, probabilistic in nature&lt;/a&gt;, that I think it's worth [re]visiting.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://static.googleusercontent.com/media/research.google.com/en/us/pubs/archive/40671.pdf&quot;&gt;HyperLogLog&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Is a 'near-optimal' cardinality estimation structure of which I'm completely unfamiliar of the inner workings of at present, but understand that it is basically made of magic.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://dimacs.rutgers.edu/~graham/pubs/papers/cm-full.pdf&quot;&gt;Count-Min Sketch&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;Can be thought of simplistically as a kind of generalization of bloom filters. It uses two-dimensional arrays, instead of one-dimensional, and you're counting, instead of setting bits, but the why and how are fairly similar.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Modular synthesizers&lt;/h3&gt;

&lt;p&gt;This is something of a shorter topic, but in my personal life, I've been diving headfirst into modular synths for the past few months. It can get expensive, so I'm limiting myself to a reasonable budget, and building some units, like &lt;a href=&quot;http://www.thonk.co.uk/shop/music-thing-modular-turing-machine-random-sequencer-kit/&quot;&gt;this random sequence generator&lt;/a&gt; from kits. I feel like this is nerdy enough to get lumped into the same bucket of posts, and I think I'll find some interesting insight along the way to share. This also means I've spent far too much time on &lt;a href=&quot;http://www.muffwiggler.com/&quot;&gt;MuffWiggler&lt;/a&gt;.&lt;/p&gt;
</description>
            </item>
        
            <item>
                <title>Where We're Going, We Don't Need Control Flow</title>
                <link>http://m4rc.io/2013/09/02/where-were-going-we-dont-need-control-flow.html</link>
                <pubDate>Mon, 02 Sep 2013 00:00:00 -0700</pubDate>
                <author>marc@badfriend.org (Marc Bollinger)</author>
                <guid>http://m4rc.io/2013/09/02/where-were-going-we-dont-need-control-flow</guid>
                <description>&lt;p&gt;I recently stumbled upon &lt;a href=&quot;http://blogs.law.harvard.edu/futureoftheinternet/2013/08/12/the-generativity-of-programming-languages-why-open-source-about-expressive-power/&quot;&gt;this article&lt;/a&gt; from a former &lt;a href=&quot;https://twitter.com/wilbanks/status/366932534283603971&quot;&gt;neighbor&lt;/a&gt;'s Twitter feed&lt;sub&gt;†&lt;/sub&gt;, which is about the generativity of programming languages, and how that relates (or doesn't) to modern copyright law. It's a great article by a student who understands technology, (some aspects of) philosophy of technology, and communication; hope for the future, n'all that. That said, it's formed more as a question than a &lt;a href=&quot;http://en.wikipedia.org/wiki/Golden_Path_(Dune)&quot;&gt;roadmap&lt;/a&gt;, and it tends to get both lost in some of the technical weeds, and not far out enough into others. I'm starting to do that myself here, but for its deep-dive-into-C-compilation-for-a-short-article, notable non-mentions include &lt;a href=&quot;http://en.wikipedia.org/wiki/Prolog&quot;&gt;Prolog&lt;/a&gt;, progenitor of 'version 1' in the article, and &lt;a href=&quot;http://clang.llvm.org/&quot;&gt;Clang&lt;/a&gt;, a now-ubiquitous-thanks-to-Apple C language compiler frontend, which adds yet more generative complexity to the same examples given.&lt;/p&gt;

&lt;p&gt;So let's look at that first example, which caught my eye:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;alice = one_of(1,2,3)
bob = one_of(1,2,3)
claire = one_of(1,2,3)
forbid(alice = bob  or  bob = claire  or  alice = claire)
forbid(bob = 3)
forbid(alice – claire = 1  or  claire – alice = 1)
forbid(claire &amp;lt; bob)
display(alice, bob, claire)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which is accompanied by the statement: &lt;em&gt;&quot;As it turns out, almost no mainstream programming language can easily express a program that looks like the first version.&quot;&lt;/em&gt; Good thing &lt;a href=&quot;https://twitter.com/hipsterhacker&quot;&gt;I don't like mainstream programming languages&lt;/a&gt;. So as mentioned, we can start with the fact that Prolog can do this, and more than likely informs the example (though I'm fairly certain this is at least some level of pseudocode, without &lt;code&gt;brew install swi-prolog&lt;/code&gt;). But it's cool to note; Prolog is basically a notation for an inference engine.&lt;/p&gt;

&lt;p&gt;I've got another blog post broaching the topic, but I've recently moved on to Lumosity, where we're using &lt;a href=&quot;https://github.com/nathanmarz/cascalog/wiki&quot;&gt;Cascalog&lt;/a&gt;. You can hopefully see the portmanteau coming a mile away. However, it actually refers not to Prolog at large, but &lt;a href=&quot;http://en.wikipedia.org/wiki/Datalog&quot;&gt;Datalog&lt;/a&gt;, a super-early internal DSL of Prolog, which strictly refers to the inference of data and their relationships. The other half of the portmanteau is Cascading, which I'm not even going to bother linking, because it's not at issue here, and Get On With It, besides. In sum, Cascalog is a variant of a subset of Prolog, except that it runs on Hadoop, so you can reason over datasets unimaginable in 1977 (much less extant).&lt;/p&gt;

&lt;p&gt;Anyway, after reading the article, being newish to Cascalog, and reading the quoted statement above as a challenge, my eyes lit up, and I had to write this trivial motivating example in the declarative version:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(&amp;lt;- 
  [?alice ?bob ?claire]
  ((one_of [1 2 3]) ?alice)
  ((one_of [1 2 3]) ?bob)
  ((one_of [1 2 3]) ?claire)
  (cross-join)

  (forbid ?alice = ?bob) (forbid ?bob = ?claire) (forbid ?alice = ?claire)
  (forbid ?bob = 3)
  (forbid ?alice - ?claire = 1) (forbid ?claire - ?alice = 1)
  (forbid ?claire &amp;lt; ?bob)))
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are some differences, to be sure. The first line is the projecting the values of the tuples out (which is the last line in the first example). The sixth line is a bit thornier. I'm not entirely sure yet (70%, say) of the technical reasoning, but because the primitives of Cascading don't, and weren't intended to, map one-to-one with that of Datalog, you can't just arbitrarily introduce streams of values. Cascading was ultimately built for ETLs, not reasoning over arbitrary data stores, and so it lends itself better to either transforming a single stream of tuples (including tuple generation, like a &lt;code&gt;flatmap&lt;/code&gt;), or joining data that has some relation to the main stream of tuples (e.g. an inner or outer join on a lookup table). We really want the cross product of three tuple streams (or generators, in this case, the mystical &lt;code&gt;one_of&lt;/code&gt; in the original example), and so we can use &lt;code&gt;cross-join&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That said, using Cascalog 1.10.2, the current stable in &lt;a href=&quot;https://clojars.org/cascalog&quot;&gt;Clojars&lt;/a&gt;, I wasn't able to get it working. While Cascading most certainly &lt;em&gt;is&lt;/em&gt; available for enterprise support, the DSLs, written[ish] and maintained by Twitter, are, well, not. So things can get weird, if you walk into the weeds, like in &lt;code&gt;cross-join&lt;/code&gt;--it's simply something that that docs say you shouldn't need in a Hadoop workflow very often and I'm not surprised it may have suddenly stopped working. Fortunately, we're using &lt;a href=&quot;https://github.com/technomancy/leiningen/&quot;&gt;Leiningen&lt;/a&gt;, so this was as easy as bumping down the version of Cascalog, and re-running &lt;code&gt;lein deps&lt;/code&gt;. Boom, works. &lt;del&gt;I also introduced a filter operation &lt;code&gt;forbid-sub&lt;/code&gt; to encapsulate subtraction (the usage here read like: &quot;operand1 minus operand2 must not equal operand3&quot;). There's probably a cleaner way to handle that, but Cascalog can get funny with Clojure-native operations on vars in a query, in a way that I'm not entirely familiar with yet, and fine, you have to build these out to discrete map/reduce tasks in Java, it's worth some pain.&lt;/del&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Edit:&lt;/em&gt; Actually, in retrospect, there was a clean[ish] immediate solution here. Clojure supports &lt;em&gt;&quot;arity overloading&quot;&lt;/em&gt;, which basically means you're free to provide multiple implementations of a function, based on the number (though not &lt;em&gt;type&lt;/em&gt;) of arguments. If we're worried about simply mimicking the interface informally laid out by the example, simply adding a five-argument implementation with &lt;code&gt;op1, operator, op2, comparator, comp2&lt;/code&gt; will suffice.&lt;/p&gt;

&lt;p&gt;For the interested, the full gist is &lt;a href=&quot;https://gist.github.com/slpsys/6409864&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;†: Years ago as a recent grad, I naïvely asked a startup CEO over a phone interview why he'd choose to start the company in Silicon Valley, and not New York or elsewhere. Granted, there are some very, very smart people in New York, but the culture just doesn't hum with the kind of intellectual cross-pollination that goes on here&lt;sub&gt;‡&lt;/sub&gt;. On the best days, it yields ideas that will change the world for the better; increasingly, just &lt;a href=&quot;http://whitemenwearinggoogleglass.tumblr.com/&quot;&gt;white men wearing Google Glass&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;‡: By here, of course, I mean the Bay Area in general. In choosing to live [and love] in Oakland, I've basically resigned myself to never working outside of SF or Oakland for the foreseeable future.&lt;/p&gt;
</description>
            </item>
        
            <item>
                <title>Who Peed in the Object Pool?</title>
                <link>http://m4rc.io/2013/06/12/who-peed-in-the-object-pool.html</link>
                <pubDate>Wed, 12 Jun 2013 00:00:00 -0700</pubDate>
                <author>marc@badfriend.org (Marc Bollinger)</author>
                <guid>http://m4rc.io/2013/06/12/who-peed-in-the-object-pool</guid>
                <description>&lt;p&gt;In the past few weeks, I'd read via Twitter an awesome rationalization for immutability, which invokes a now-deeply-held bugaboo [&lt;a href=&quot;https://twitter.com/jessitron/status/333228687208112128&quot;&gt;Source&lt;/a&gt;]:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;GOTO was evil because we asked, &quot;how did I get to this point of execution?&quot; Mutability leaves us with, &quot;how did I get to this state?&quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I've been [lazily] evangelizing here, to work colleagues, around the block, ad nauseum, about the benefits of modern functional languages, not least of which being a ground-up approach to embracing immutability (by default, if not by decree). This recently bit me in the ass with some code I'd naïvely written a few years ago.&lt;/p&gt;

&lt;p&gt;Not uncommonly, we have certain classes of data--metadata, in this case--that are extremely read-heavy, and only updated on occasion; maybe months, potentially years. In this particular case, it's metadata about financial instruments; alternate identifiers, full names, which exchange it's listed on, that sort of thing. As one might expect, this is retrieved by almost every user-facing request in some capacity; if it doesn't scale, nothing scales. The retrieval system itself is something of hybrid &lt;a href=&quot;http://en.wikipedia.org/wiki/Strategy_pattern&quot;&gt;Strategy pattern&lt;/a&gt;, where each concrete strategy looks roughly like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;string GetCacheKey(Tkey key)
Tval Get(string key)
void SetOther(Tkey key, Tval value)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The basic premise here is that each request walks a list of implementations, ordered by cost-of-access from least to greatest, and that any given strategy/implementation, if successful, has the ability to promote its result to a faster cache layer, typically with a shorter TTL. The first two implementations of this are basically reading directly from memory: the first is in-process, the second is out-of-process (e.g. external cache server[s]). A network hop, especially in EC2, is not free, and again, this data doesn't change much. If we have to go out to the cache server, let's at least promote it to in-process cache, so that we have faster access next time.&lt;/p&gt;

&lt;p&gt;Fine, great. Early in the project, I'd added copy-on-set logic to the in-process cache, so that if a request retrieved an object from slow storage and promoted, the caller can freely modify it for the lifetime of the request, while leaving a pristine copy in cache.&lt;/p&gt;

&lt;p&gt;lulz&lt;/p&gt;

&lt;p&gt;Like &quot;knowing,&quot; that was half the battle, and that suited perfectly fine for a long time, because this metadata wasn't mutated by convention. Even the error case that eventually cropped up wasn't caught by any tests. At some point, some additional entitlement restrictions were added, requiring that if a user did not have particular licensing documentation in place, a few fields would need to be scrubbed before being returned.&lt;/p&gt;

&lt;h4&gt;So who peed in the object pool?&lt;/h4&gt;

&lt;p&gt;So yeah, that doesn't cut it. The thing is, while we had unit tests with pretty good coverage, no one, not test accounts, not &lt;em&gt;gulp&lt;/em&gt; live users, caught it for a long time, because not many people &lt;em&gt;had&lt;/em&gt; the proper licenses. When it was--painfully, and after over too long a period--discovered, it became clear that what was going down was that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At some point, a user retrieves a value warm in cache&lt;/li&gt;
&lt;li&gt;The user did not have the proper license, and the fields were scrubbed&lt;/li&gt;
&lt;li&gt;All subsequent reads, until the key expired, had those fields scrubbed&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So there's your culprit. The &lt;a href=&quot;http://www.snopes.com/science/poolpiss.asp&quot;&gt;pool-pisser&lt;/a&gt;. And the immediate solution there was pretty simple: adding copy-on-read semantics to the in-process cache. I guess. Begrudgingly. The way forward? Oh, I don't pretend to know. But making things &lt;a href=&quot;https://en.wikipedia.org/wiki/Functional_programming#Functional_programming_in_non-functional_languages&quot;&gt;immmutable&lt;/a&gt;, at least &lt;a href=&quot;http://blog.zilverline.com/2011/02/01/towards-an-immutable-domain-model-introduction-part-1/&quot;&gt;by default&lt;/a&gt;, seems like a good start. Or &lt;a href=&quot;http://en.wikipedia.org/wiki/Copy-on-write&quot;&gt;copy-on-write&lt;/a&gt;, which would be transparent to the user, and carry the safety of immutability, but (on first blush) it seems like adding that kind of complexity to all your precious POJOs and POCOs and POROs would be overkill.&lt;/p&gt;

&lt;p&gt;Seems.&lt;/p&gt;
</description>
            </item>
        
            <item>
                <title>Who Moved My Data Cheese?</title>
                <link>http://m4rc.io/2013/05/15/who-moved-my-data-cheese.html</link>
                <pubDate>Wed, 15 May 2013 00:00:00 -0700</pubDate>
                <author>marc@badfriend.org (Marc Bollinger)</author>
                <guid>http://m4rc.io/2013/05/15/who-moved-my-data-cheese</guid>
                <description>&lt;p&gt;Recently, during what should probably be a more broadly-practiced routine of wearing other people's hats for a week, I delved into some pretty spotty code (not the person whose hat I was wearing, just some legacy code). Unfortunately, this code also depends on the kindness of strangers (well, vendors) to not change the format of the data it's parsing (some of which may be very unclean). Upon figuring out what it was doing, and were it was going wrong, I made mention on an email thread that the retry logic is somewhat deficient. A bit later, this was met with something along the lines of:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;try {
    doSomething();
}
catch {
    doSomething();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Well, yes, that's a good start--obviously, there are better generalized patterns for doing this, but that's out of scope for now. The broader question is: &lt;em&gt;what kind of failure modes are there, and how am I handling them&lt;/em&gt;? These can roughly be summed up into four modes, only one of which is &lt;em&gt;actually&lt;/em&gt; handled correctly in the above scenario:&lt;/p&gt;

&lt;h5&gt;1. Ephemeral processing issues&lt;/h5&gt;

&lt;h5&gt;2. Persistent processing issues&lt;/h5&gt;

&lt;h5&gt;3. Ephemeral data issues&lt;/h5&gt;

&lt;h5&gt;4. Persistent data issues&lt;/h5&gt;

&lt;p&gt;Let's break those down.&lt;/p&gt;

&lt;br/&gt;


&lt;h4&gt;Ephemeral processing issues&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Example: transaction becomes a database &lt;a href=&quot;http://www.codinghorror.com/blog/2008/08/deadlocked.html&quot;&gt;deadlock victim&lt;/a&gt;&lt;/em&gt;. Perhaps this should be spoiler tagged, but basically: this is the only failure mode actually corrected by the above changeset. What the changeset itself is doing is trying something, failing, and immediately [key] trying again. There are definitely subclasses of problems that can be addressed this way, but there are many others &lt;em&gt;not&lt;/em&gt; covered by this, which I'll get to.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Alright, what can I do?&lt;/em&gt; Well, test, for one. You can unit test, but depending on the subclass, these sorts of things can be hard to mock, and fairly low-level. Some other subclasses you can fake with known-bad data, but there are &lt;a href=&quot;http://en.wikipedia.org/wiki/There_are_known_knowns&quot;&gt;unknown-unknowns&lt;/a&gt;, and it's hard to fake deadlocks. You can use &lt;a href=&quot;http://martinfowler.com/articles/mocksArentStubs.html&quot;&gt;stubs&lt;/a&gt;, but this seems really, really contrived, and of dubious value. Your best bets are being very pessimistic, building a great method for logging/analyzing errors, and knowing your stack.&lt;/p&gt;

&lt;h4&gt;Persistent processing issues&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Example: your code is terrible.&lt;/em&gt; This is the simplest class of problems to understand, but it's not fixed with the changeset, and wouldn't be fixed with an infinite loop around a try/catch block. I'm not going to beat this dead horse, because:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Alright, what can I do?&lt;/em&gt; This is also the simplest class of problems to solve. Persistently-failing processes on a known set of data should be cataloged, understood, corrected, and met with regression tests. Persistently-failing processes on an unknown set of data should be met with exasperation and scotch.&lt;/p&gt;

&lt;h4&gt;Ephemeral data issues&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Example: sorry that your data is bad, but it'll be good, we promise!&lt;/em&gt; This is actually the motivating example behind this post, and the fact that it &lt;em&gt;isn't&lt;/em&gt; covered by the changeset is the motivation for the post itself. What was at issue is that some of the data was hyperlinked to other documents, which were not available at the time of processing, yielding broken processing. I'm not familiar with the underlying data set or its [lack of] atomicity, but this can be generalized to any data set that is eventually consistent. In this case, there's nothing intrinsically wrong with the concept of simply retrying, but the chronology is almost certainly wrong: you have little control over when the retry happens (and are likely going to be wrong if you try, depending on the semantics of the api/data source)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Alright, what can I do?&lt;/em&gt; Again, known unkowns and estimated unknowns can be tested, regressed against, etc. What's really at issue here is your retry &lt;em&gt;framework&lt;/em&gt;, not your retry logic. If you can't process it now, reprocessing it immediately may not help, and you're not going to be able to synchronously solve the problem. &lt;em&gt;Maybe&lt;/em&gt;. Discerning this class from the first requires familiarity with the data set. A good solution to this problem will involve persisting the job, and inserting it in a system of work retry queues. Depending on the scenario, this may be done at regular intervals, with some sort of &lt;a href=&quot;http://en.wikipedia.org/wiki/Exponential_backoff&quot;&gt;exponential backoff&lt;/a&gt;, etc.&lt;/p&gt;

&lt;h4&gt;Pesistent data issues&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Example: the data is, and will likely remain, in a format that's either currently not useful, or permanently not useful.&lt;/em&gt; This, too, should be met with scotch. This is arguably the worst case, because like #2, this will never work through retries alone, but unlike #2, may be out of your control entirely. Sometimes, this involves better parsing or processing, which may be a significant engineering investment. Sometimes, it just can't.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Alright, what can I do?&lt;/em&gt; Find a nice Islay. In most cases, the best scenario is to be able to discern this case from the others, and simply log and accept that this won't be able to be parsed. Reattempting in some fashion is just a waste of resources.&lt;/p&gt;
</description>
            </item>
        
            <item>
                <title>We Call That 'Schönfinkelling' Where I Come From</title>
                <link>http://m4rc.io/2013/03/10/we-call-that-schonfinkelling.html</link>
                <pubDate>Sun, 10 Mar 2013 00:00:00 -0800</pubDate>
                <author>marc@badfriend.org (Marc Bollinger)</author>
                <guid>http://m4rc.io/2013/03/10/we-call-that-schonfinkelling</guid>
                <description>&lt;p&gt;A friend and I were discussing &lt;a href=&quot;http://www.bluebytesoftware.com/blog/PermaLink,guid,14b37ade-3110-4596-9d6e-bacdcd75baa8.aspx&quot;&gt;this blog post&lt;/a&gt; by Joe Duffy, about type classes and C#. It's deep enough that it took a second reading to really gel, but we'd discussed in person after the first time, in which I'd mostly skimmed the samples, and just read the commentary. Obviously, this is not verbatim (nor did I spell out the symbols):&lt;/p&gt;

&lt;p&gt;Me:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;I've been meaning to read 'Learn You a Haskell for Great Good' for a while now, but I know literally zero Haskell. Function signature syntax like &quot;isin :: Eq a =&gt; a -&gt; [a] -&gt; Bool&quot; just seems unnecessarily...Perlish in its use of symbols.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Him:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Yeah, all function type defs in Haskell are in the form of, err...you know, when a function taking multiple arguments is represented as successive single-argument functions?&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Me:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Ah, right; currying. &lt;em&gt;That makes so much more sense&lt;/em&gt;, in retrospect.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;At the time, I shrugged off its forced use in Haskell, chalking it up to intentional esotericism. Some 15 hours later I was in the shower, having &lt;a href=&quot;/img/doc_brown.jpg&quot;&gt;a Doc Brown moment&lt;/a&gt;. &lt;em&gt;Hey!&lt;/em&gt; &lt;a href=&quot;http://en.wikipedia.org/wiki/Haskell_Curry&quot;&gt;That is the actual man's friggin' last name&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also, &lt;a href=&quot;http://en.wikipedia.org/wiki/Moses_Sch%C3%B6nfinkel#Work&quot;&gt;about the title&lt;/a&gt;.&lt;/p&gt;
</description>
            </item>
        
            <item>
                <title>Out, damned spot! Out, I say! [Pt 1]</title>
                <link>http://m4rc.io/2013/03/02/out-damned-spot.html</link>
                <pubDate>Sat, 02 Mar 2013 00:00:00 -0800</pubDate>
                <author>marc@badfriend.org (Marc Bollinger)</author>
                <guid>http://m4rc.io/2013/03/02/out-damned-spot</guid>
                <description>&lt;p&gt;Another post that starts its life as an email response to a coworker:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;What's our spot instance strategy?&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;We don't really have one. Nor, I suspect, do most people. If you've somehow managed to end up here, you're most likely at least passingly familiar with EC2 &lt;a href=&quot;http://aws.amazon.com/ec2/spot-instances/&quot;&gt;spot instances&lt;/a&gt;, a concept that sounds cooler in theory than it is, but whose practicality can reach peak awesome, if you build your systems correctly, which I'll get into.&lt;/p&gt;

&lt;p&gt;At first glance, it &lt;em&gt;seems&lt;/em&gt; very interesting because, hey, it's raw computing power, sold on the open market! &lt;em&gt;This sounds like the future, man&lt;/em&gt;. About a year ago, I was working closely with a product manager at a commodities exchange on a project involving all manner of derivatives, and in discussing cloud computing at the time, it was hard not to joke about crazy, exotic leveraging schemes and complex derivative instruments, based on computing. After all, the use of the term &quot;spot&quot; here is borrowed directly from a &lt;a href=&quot;http://en.wikipedia.org/wiki/Spot_contract&quot;&gt;related concept&lt;/a&gt; in financial markets.&lt;/p&gt;

&lt;p&gt;But you'll immediately notice some differences in the market behavior though, looking at the pricing history charts available. There's no &lt;a href=&quot;http://en.wikipedia.org/wiki/Brownian_motion&quot;&gt;Brownian-style motion&lt;/a&gt; (you can also check out how &lt;a href=&quot;http://en.wikipedia.org/wiki/Brownian_model_of_financial_markets&quot;&gt;Brownian motion&lt;/a&gt; is applied to markets, but there aren't any gifs). Pricing over time tends to resemble a step function. There are some ways in which the EC2 spot market differs from a real, actual Market which play out in odd ways.&lt;/p&gt;

&lt;p&gt;So how does the spot market differ from, say, an equities market (think NASDAQ)? This list may lean somewhat on financial jargon, but I'll disambiguate immediately after:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Amazon only quotes one side of the book&lt;/li&gt;
&lt;li&gt;Market participants do not have full depth-of-book insight (or any insight)&lt;/li&gt;
&lt;li&gt;Spot instance prices are necessarily chained to the on-demand (and reserved) price&lt;/li&gt;
&lt;/ul&gt;


&lt;h5&gt;Amazon only quotes one side of the book&lt;/h5&gt;

&lt;p&gt;Typical financial markets have a concept known as a &lt;a href=&quot;http://en.wikipedia.org/wiki/Market_maker&quot;&gt;market maker&lt;/a&gt;: an entity from whom you can both buy and sell a thing. One way to conceptualize this would be a currency exchange booth at an international airport; they have different prices for each direction of conversion, and pocket the difference, hoping to make enough money on the spread to offset the market volaltility (jay kay, they always do, especially at airports). This differs greatly from what Amazon does, because you can't buy a spot contract, wait for some upward price pressure, and unload your position for a profit--at the cost of system throughput, obviously; we &lt;em&gt;are&lt;/em&gt; still talking about computers, believe it or not. There's nothing inherently wrong with this model, but it's not particularly market-like. That said, while I'm not a financier by training or trade, I'm pretty certain that in the absence of the other bullet points (among other things), even if you AMZN did quote both sides of the book, it would make working with spot instances a hellish, unlivable nightmare, unless you really, truly &lt;a href=&quot;http://incompetech.com/Images/caring.png&quot;&gt;could not care less&lt;/a&gt; about spot availability.&lt;/p&gt;

&lt;h5&gt;Market participants do not have full depth-of-book insight (or any insight)&lt;/h5&gt;

&lt;p&gt;This is also a pretty big departure from real, adult markets. You may not &lt;em&gt;actually&lt;/em&gt; need full depth-of-book access to trade securities. Maybe you got a hot tip from an AdWords ad in Gmail. Maybe you're timing the market. Maybe you're actually an idiot. Who knows! Point being, even free-ass Yahoo! Finance will give you top-of-book right now, and what any respectable algorithm will be doing is taking into account just what the stakes are on either side of the book.&lt;/p&gt;

&lt;p&gt;To de-jargonate a bit, going back to bullet #1, &quot;the book&quot; in finance refers to the order book. Orders get placed into the exchange for something, and bids lower than the lowest offer, or offers higher than lowest bid, get stacked with each other, along with their respective volumes. Real market participants pay Cash Money to have access to exactly what the full state of the market looks like, because it drives the direction of the price. If people are looking to unload AAPL (which they have for some weeks now), this will be reflected in downward price pressure, as they'll quickly exhaust the existing Best Bids, and people will replace them with even lower bids, ad nauseum. Basically: just knowing the intentions of others in the market (at least, as much as they're willing to divulge; this too is a strategy) affects the market.&lt;/p&gt;

&lt;p&gt;None of this nonsense exists in the spot world, and as a result, everyone just guesses how high everyone else is willing to go, and [hopefully] sets their price appropriately to how much risk they can tolerate, again in terms of system throughput. Here we are, talking about stupid computers again.&lt;/p&gt;

&lt;h5&gt;Spot instance prices are necessarily chained to the on-demand (and reserved) price&lt;/h5&gt;

&lt;p&gt;This is really the largest departure, in my opinion. For however much people are prattling on about the price of gold or Google, there is no externally-mandated value for these things. By comparison, it would make no sense to start making spot requests in a hot market, and live in constant fear of your instances being yanked, when you could just start up some plain ol' on-demand instances. This creates some odd effects, the most noticeable of which being that the market will always tend back to a very cheap equilibrium. Between the inherent risk and the fact that there's a fixed price for the underlying good, unless the standard, on-demand EC2 instances start seeing high rates of startup requests being denied due to capacity problems, it would make no sense for spots to ever stray. You'll never actually see that play out though, because that would involve both an incredible lack of capacity planning on Amazon's part, but also an overt move to not draw capacity for spot from the same pool as on-demand instances. That would not only be insane business--not to mention cutting off your nose to spite your face--but it would run counter to their [sensible] goal of consistency. You get a hefty discount just by paying upfront for reserved instnaces, allowing them to better plan capacity as it is.&lt;/p&gt;

&lt;p&gt;There are certainly other deviations, but these are the ones that really pop out to me; put together, you get...not a market. I suspect this is why for the first few years, you'd see the term 'market' pop up in the AWS marketing, product descriptions, news articles, but its use has pretty much been scrubbed, save for some leftover Google ghosts. I didn't initially intend for this two be a two-part post, and I already have pictures to look at for the &lt;em&gt;second&lt;/em&gt; half, but it was just too engrossing to give up the armchair markets discussion. I'll get into the actual computers in the next post.&lt;/p&gt;
</description>
            </item>
        
            <item>
                <title>Manufacturing Consent</title>
                <link>http://m4rc.io/2013/02/26/manufacturing-consent.html</link>
                <pubDate>Tue, 26 Feb 2013 00:00:00 -0800</pubDate>
                <author>marc@badfriend.org (Marc Bollinger)</author>
                <guid>http://m4rc.io/2013/02/26/manufacturing-consent</guid>
                <description>&lt;p&gt;From a coworker:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt; Sounds good to me.  I cannot wait to see those emails go away.  :)&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Magically, for the past two weeks, we saw a fairly high percentage (nearing 50%) of our EC2 instances start up with misconfigured local drives.  And obviously, this makes the system complain a lot. Getting a chance to dive a little deeper over the weekend, I was able to make it complain a lot more.&lt;/p&gt;

&lt;p&gt;The quote above refers to a perfectly rational approach to solving the problem, but it did occur to me that this is basically Propaganda 101: manufacture an unendurable scenario, propose to the public a terrible--but manageable--solution, and let them come to their own conclusion. Step 4, profit.&lt;/p&gt;
</description>
            </item>
        
            <item>
                <title>Fist Proust</title>
                <link>http://m4rc.io/2013/02/11/fist-proust.html</link>
                <pubDate>Mon, 11 Feb 2013 00:00:00 -0800</pubDate>
                <author>marc@badfriend.org (Marc Bollinger)</author>
                <guid>http://m4rc.io/2013/02/11/fist-proust</guid>
                <description>&lt;p&gt;À la recherche d'un bon début.&lt;/p&gt;
</description>
            </item>
        
    </channel>
</rss>