Robin Sloan
the lab
March 2021

Cloud study

A lovely impressionistic watercolor of an anonymous patch of clouds.
Cloud study, anonymous, 19th century

The web­site you’re read­ing is mostly sta­tic HTML, just web pages on a CDN, but for newslet­ter sub­scribers, it does offer a few bits of interactiv­ity, and those bits require code to run some­where other than your browser.

For my projects, that “some­where” has lately and reli­ably become cloud func­tions. They fit at least two ways:

Back in January, when I was putting this web­site together, I’d already imple­mented the sub­scriber tools on AWS Lambda when Google announced that their Cloud Func­tions would sup­port Ruby. I did a lit­tle inves­ti­ga­tion and was so impressed that I switched every­thing over; now, I want to share a cou­ple of findings.

The winner

I appreciate AWS Lambda’s role in kick­start­ing the whole “floating wisp of code” model, but/and I have found the sys­tem itself very funky to work with. Google’s Cloud Functions, particularly in Ruby, par­tic­u­larly with the scaf­fold­ing of the Func­tions Framework, has been a bet­ter expe­ri­ence in every respect.

There’s a simple, use­ful local devel­op­ment mode. The func­tion runs exactly as it would in the cloud, with no spe­cial setup or extra tinkering required.

Dependencies are as easy as a Gemfile. AWS, by contrast, requires funky “layers” that you need to build and maintain separately.

The single-page view of each function is terrific. Google’s dash­board shows you every­thing you need to know in one screen: the func­tion’s activ­ity over time, how quickly it’s responding, how many copies are running, etc. It’s perfect.

All in all, Google’s sys­tem has pro­vided the most potent dose of like, “suddenly expanded tech­ni­cal capability” I’ve received since, I don’t know … Slicehost??

The mega function

One well-established draw­back of cloud func­tions is the “cold start” problem. When your func­tion is getting used a lot, the system spins up as many copies as needed; very slick. When it’s not get­ting used, the system spins up: zero. So, the first request after a period of slum­ber can be quite slow. One imag­ines the sys­tem ner­vously pat­ting its pockets: “Where did I put that code … ?”

It’s really not a huge deal, but there is a notice­able dif­fer­ence between the per­for­mance of a func­tion that’s “cold” vs. one that’s being pinged by a few thou­sand newslet­ter sub­scribers. The lat­ter purrs; the for­mer engages with a pal­pa­ble ker-thunk.

The solu­tion I’ve cho­sen might be “bad” practice, but it works for me. Instead of deploy­ing each of my functions as Actu­ally Dif­fer­ent cloud func­tions, I’ve rolled them up into one “mega func­tion”—really almost a tiny app.

The result is that when some­one arrives to, say, mod­ify their newslet­ter subscription, they rouse the code not only for future subscription-modifiers but for anyone who might need any part of it. That might include their future self, per­form­ing a different operation.

For routing, I use a para­me­ter in the pay­load called method:

case body["method"]
when "get_tags"
when "update_tags"
when "send_response"
when "check_email"

Here, I’ll drop in one of my little response fields, just for the pleasure of plugging into a warmed-up function:

Whatever you choose, Robin will see that this response is coming from . Please also sign it with your preferred name ✌️

Another advantage, for me, of putting every­thing into one mega func­tion is that it “fails fast”; if some­thing isn’t working, nothing is working.

This is all in the context of an incon­se­quen­tial per­sonal web­site … but that’s not an uncom­mon con­text! Just because crit­i­cal enter­prise data­bases exist doesn’t mean we all need to pro­gram as if we’re sup­porting them.

Sloan’s mega func­tion: I recommend it.

Pretty much the same as the first watercolor, but with the red glow of sunset.
Cloud study, anonymous, 19th century

March 2021