<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hello, World! on Rodaine</title><link>https://rodaine.com/</link><description>Recent content in Hello, World! on Rodaine</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://rodaine.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Go Module Rename &amp; V2 Release</title><link>https://rodaine.com/til/2023/05/go-module-rename-v2/</link><pubDate>Tue, 16 May 2023 00:00:00 +0000</pubDate><guid>https://rodaine.com/til/2023/05/go-module-rename-v2/</guid><description>&lt;p>Today, I&amp;rsquo;m working on a project that intends to both rename a Go module and cut a v2 release (all while keeping &lt;code>main&lt;/code> as the default branch). Why do both? Essentially rebranding without losing existing links.&lt;/p>
&lt;p>In any case, before attempting this level of shenanigans, I wanted to make sure that it worked (spoiler alert: it did). Below are the steps I followed that got me there using a dummy repository:&lt;/p></description></item><item><title>A sh, shebang, and pipefail fail</title><link>https://rodaine.com/til/2020/11/sh-shebang-pipefail/</link><pubDate>Tue, 10 Nov 2020 00:00:00 +0000</pubDate><guid>https://rodaine.com/til/2020/11/sh-shebang-pipefail/</guid><description>&lt;p>It could be argued this falls squarely under &lt;abbr title="Read The Fucking Manual">RTFM&lt;/abbr>, but in any case this was a bit of a wild ride.&lt;/p>
&lt;p>At work, we have a piece of software that receives a shell script via an API and executes it. Simple enough. The script looked something like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#!/usr/bin/env bash
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>&lt;span class="nb">set&lt;/span> -eu
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># do some real work&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;done!&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>I needed to do some refactoring in that script. Mostly out of habit, I also added the &lt;code>pipefail&lt;/code> option alongside my changes.&lt;/p></description></item><item><title>Static vs Dynamic Linking in Go</title><link>https://rodaine.com/til/2020/11/go-static-vs-dynamic-linking/</link><pubDate>Tue, 03 Nov 2020 00:00:00 +0000</pubDate><guid>https://rodaine.com/til/2020/11/go-static-vs-dynamic-linking/</guid><description>&lt;p>Ran into some linking weirdness with a couple of Go binaries from a seemingly innocuous change. Suppose you have some code that depends on some C bindings. The simplest such program would be:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-go" data-lang="go">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">package&lt;/span> &lt;span class="nx">main&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="s">&amp;#34;C&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kd">func&lt;/span> &lt;span class="nf">main&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="cm">/* … */&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Building this on linux/amd64, you get a dynamically-linked binary:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">$ go build -o my.bin
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">$ file my.bin
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">my.bin: … , dynamically linked, …
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To make this static, you can tell &lt;code>go build&lt;/code> to pass the right flags to the C linker:&lt;/p></description></item><item><title>git checkout -</title><link>https://rodaine.com/til/2020/10/git-checkout-dash/</link><pubDate>Fri, 23 Oct 2020 00:00:00 +0000</pubDate><guid>https://rodaine.com/til/2020/10/git-checkout-dash/</guid><description>&lt;p>I am already familiar with &lt;code>cd -&lt;/code>, which I use often to toggle between two directories. In zsh with &lt;code>setopt AUTO_CD&lt;/code>, this is even shorter: &lt;code>-&lt;/code>. Mechanically, it&amp;rsquo;s pretty simple. When you &lt;code>cd&lt;/code> into a directory, the previous directory is first set to &lt;code>$OLDPWD&lt;/code>. A call to &lt;code>cd -&lt;/code> swaps &lt;code>$PWD&lt;/code> and &lt;code>$OLDPWD&lt;/code>. Easy-peasy.&lt;/p>
&lt;p>So, definitely chuffed to discover &lt;code>git checkout -&lt;/code> toggles between branches the current and last branch! How it operates is a bit more complicated.&lt;/p></description></item><item><title>Break The Golang Context Chain</title><link>https://rodaine.com/2020/07/break-context-cancellation-chain/</link><pubDate>Thu, 30 Jul 2020 00:00:00 +0000</pubDate><guid>https://rodaine.com/2020/07/break-context-cancellation-chain/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>Go 1.21 Update&lt;/strong>: Apparently alongside me writing this article, the Go project was tracking this very same &lt;a href="https://github.com/golang/go/issues/40221">issue&lt;/a>. Comments in the thread bring up some very valid concerns with this pattern beyond the caveats I cover below, but ultimately the feature is now part of the Go 1.21 changeset as &lt;a href="https://pkg.go.dev/context@go1.21rc2#WithoutCancel">&lt;code>context.WithoutCancel&lt;/code>&lt;/a>.&lt;/p>
&lt;/blockquote>
&lt;p>Recently, I recalled a useful pattern that&amp;rsquo;s cropped up a few times at work. API handlers (think &lt;code>http.Handler&lt;/code>), include a &lt;code>context.Context&lt;/code> tied to the connectivity of the caller. If the client disconnects, the context closes, signaling to the handler that it can fail early and clean itself up. Importantly, the handler function returning &lt;em>also&lt;/em> cancels the context.&lt;/p></description></item><item><title>The X-Files: Avoiding Concurrency Boilerplate With golang.org/­​x/​sync</title><link>https://rodaine.com/2018/08/x-files-sync-golang/</link><pubDate>Wed, 15 Aug 2018 00:00:00 +0000</pubDate><guid>https://rodaine.com/2018/08/x-files-sync-golang/</guid><description>&lt;p>Go makes concurrent programming dead simple with the &lt;code>go&lt;/code> keyword. And, with its &lt;a href="https://blog.golang.org/share-memory-by-communicating">&amp;ldquo;share memory by communicating&amp;rdquo;&lt;/a> mantra, channels perform as a thread-safe mechanism for IO between threads. These primitives more than meet the demands of most parallel tasks.&lt;/p>
&lt;p>But sometimes workloads need extra coordination, particularly around error propagation or synchronization. For example, goroutines often need access to a shared yet thread-&lt;em>unsafe&lt;/em> resource. Enter the standard library&amp;rsquo;s &lt;a href="https://golang.org/pkg/sync/">&lt;code>sync&lt;/code>&lt;/a> package with &lt;code>WaitGroup&lt;/code>, &lt;code>Once&lt;/code>, and &lt;code>Mutex&lt;/code>. For the brave of heart, &lt;code>sync/atomic&lt;/code> beckons. These utilities along with channels annihilate data races, but can result in a lot of nuanced boilerplate. Wouldn&amp;rsquo;t it makes sense to lift this code into portable abstractions?&lt;/p></description></item><item><title>The X-Files: Controlling Throughput with rate.Limiter</title><link>https://rodaine.com/2017/05/x-files-time-rate-golang/</link><pubDate>Mon, 22 May 2017 00:00:00 +0000</pubDate><guid>https://rodaine.com/2017/05/x-files-time-rate-golang/</guid><description>&lt;p>In this first &lt;em>X-Files&lt;/em> post, I&amp;rsquo;ll cover the simple yet powerful &lt;a href="https://godoc.org/golang.org/x/time/rate">golang.org/x/time/rate&lt;/a>. This package provides a &lt;code>Limiter&lt;/code> that controls throughput to an arbitrary resource. There’s a ton of utility in &lt;code>rate&lt;/code>, and to show its virtues, I will use it to enforce an SLA on an HTTP service.&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/p>
&lt;h3 id="slas-and-rate-limiting">SLAs and Rate Limiting&lt;/h3>
&lt;p>When creating a new service, it is prudent to specify a service level agreement, or SLA. This promises an expected availability given some throughput from consumers. The benefits of an SLA are twofold. First, it provides &lt;a href="https://en.wikipedia.org/wiki/High_availability#.22Nines.22">a metric&lt;/a> by which the success of a service is measurable. Is it exceeding expecations, or are changes necessary to achieve the SLA? Second, it is enforceable as a means to protect upstream dependencies (like a database) from a &lt;a href="https://en.wikipedia.org/wiki/Cascading_failure">cascading failure&lt;/a>. One of the simplest ways to impose such an SLA is rate limiting incoming requests.&lt;/p></description></item><item><title>The X-Files: Exploring the Golang Standard Library Sub-Repositories</title><link>https://rodaine.com/2017/05/x-files-intro/</link><pubDate>Sun, 21 May 2017 00:00:00 +0000</pubDate><guid>https://rodaine.com/2017/05/x-files-intro/</guid><description>&lt;p class="padded">&lt;img src="x-files-logo.svg" alt="The X-Files logo">&lt;/p>
&lt;p>This post will be the start of &lt;strong>The X-Files&lt;/strong>, a blog series exploring the Go sub-repositories located at &lt;code>golang.org/x/*&lt;/code>. Chances are, you may not have heard them called that before or know where they came from. Introductions are in order&amp;hellip;&lt;/p>
&lt;h3 id="a-brief-origin-story">A brief origin story&lt;/h3>
&lt;p>Go promises, with reasonable exceptions, that its compiler and standard library will remain &lt;a href="https://golang.org/doc/go1compat">forward-compatible&lt;/a> for all minor releases of the Go 1 language specification. This is incredibly refreshing, especially if you&amp;rsquo;ve ever used a framework or language that seems to break the world on every patch release. While perhaps this makes Go &lt;a href="https://www.youtube.com/watch?v=4Dr8FXs9aJM">boring&lt;/a>, it permits developers to confidently use the language and stdlib, leaving the core team to focus on performance in the compiler, optimizations to the garbage collector, and other quality-of-life improvements.&lt;/p></description></item><item><title>Asynchronously Split an io.Reader in Go (golang)</title><link>https://rodaine.com/2015/04/async-split-io-reader-in-golang/</link><pubDate>Sat, 25 Apr 2015 00:00:00 +0000</pubDate><guid>https://rodaine.com/2015/04/async-split-io-reader-in-golang/</guid><description>&lt;p>I have fallen in love with the flexibility of &lt;a href="https://golang.org/pkg/io/#Reader">&lt;code>io.Reader&lt;/code>&lt;/a> and &lt;a href="https://golang.org/pkg/io/#Writer">&lt;code>io.Writer&lt;/code>&lt;/a> when dealing with any stream of data in Go. And while I am more or less smitten at this point, the reader interface challenged me with something you might think simple: splitting it in two.&lt;/p>
&lt;p>I&amp;rsquo;m not even certain &amp;ldquo;split&amp;rdquo; is the right word. I would like to receive an &lt;code>io.Reader&lt;/code> and read over it multiple times, possibly in parallel. But because readers don&amp;rsquo;t necessarily expose the &lt;code>Seek&lt;/code> method to reset them, I need a way to duplicate it. Or would that be clone it? Fork?!&lt;/p></description></item><item><title>Develop Locally with WordPress</title><link>https://rodaine.com/2013/10/develop-locally-with-wordpress/</link><pubDate>Mon, 14 Oct 2013 00:00:00 +0000</pubDate><guid>https://rodaine.com/2013/10/develop-locally-with-wordpress/</guid><description>&lt;p>There seems to be a common complaint that working on WordPress plugins and themes locally is difficult to accomplish. If you only need to manage a handful of plugins or a couple themes, the tedium of setting up a dev environment isn&amp;rsquo;t too complicated; you would probably just have a single install of WP on a MAMP server. As my 8th-grade english teacher would say: done, like a cupcake!&lt;/p>
&lt;p>Things start to get real messy, though, when you manage 20+ client projects including custom themes, plus a slew of shared plugins between them. Throw in source control (this should go without question, but I hope you&amp;rsquo;re using source control), and you have a nightmarish franken-MAMP that requires so much overhead to switch between themes and plugins it&amp;rsquo;s just not worth the effort. Next thing you know, you&amp;rsquo;re cowboy-coding on a live site in an alleyway with an ancient MacBook with broken &lt;code>(&lt;/code>, &lt;code>-&lt;/code> and &lt;code>[&lt;/code> keys. Or so I&amp;rsquo;ve been told&amp;hellip;&lt;/p></description></item><item><title>Add A Custom WordPress Admin Contextual Help Menu To Your Plugin Or Theme</title><link>https://rodaine.com/2013/09/add-a-custom-wordpress-admin-contextual-help-menu-to-your-plugin-or-theme/</link><pubDate>Wed, 25 Sep 2013 00:00:00 +0000</pubDate><guid>https://rodaine.com/2013/09/add-a-custom-wordpress-admin-contextual-help-menu-to-your-plugin-or-theme/</guid><description>&lt;p>New post on the &lt;a href="http://www.clarknikdelpowell.com/blog/">CNP Blog&lt;/a> today covering a little-known (or perhaps little-used) feature of the WordPress Admin: custom contextual help tabs&amp;hellip;&lt;/p>
&lt;blockquote>
 &lt;p>If you are familiar with the WordPress admin, you probably noticed the “Help” tab at the top right of nearly every screen. Clicking this little gem reveals a series of helpful topics related to the current page. For example, on the Dashboard, the tab offers an overview of what’s currently displayed, how to navigate the admin in general and what the different boxes on the screen do. This information is invaluable to a new user of WordPress and stays politely out of the way for the more experienced.&lt;/p></description></item><item><title>Experimenting with Canvas and request­Animation­Frame</title><link>https://rodaine.com/2013/09/experimenting-with-canvas-and-requestanimationframe/</link><pubDate>Tue, 17 Sep 2013 00:00:00 +0000</pubDate><guid>https://rodaine.com/2013/09/experimenting-with-canvas-and-requestanimationframe/</guid><description>&lt;p class="codepen" data-height="288" data-default-tab="result" data-slug-hash="DqPzPB" data-editable="false" data-user="rodaine" style="height: 288px;">
 &lt;span>See the &lt;a href="https://codepen.io/rodaine/pen/DqPzPB">Pen&lt;/a> by &lt;a href="https://codepn.io/rodaine">@rodaine&lt;/a> on &lt;a href="https://codepen.io">CodePen&lt;/a>.&lt;/span>
&lt;/p>

&lt;p>Recently at work, I was checking out some designs for a client&amp;rsquo;s print piece, and was struck by this mesmerizing geometric pattern in the background. I mentioned to &lt;a href="http://taylorpatrickgorman.com/">Taylor Gorman&lt;/a> that it&amp;rsquo;d be awesome if – when these designs were translated to their site – the background was animated similar to the old &lt;a href="http://www.youtube.com/watch?v=sql60Bvz0rU">bezier screensaver&lt;/a> that used to come with Windows (it might still do?).&lt;/p></description></item><item><title>How to Report a Bug to a Web Developer</title><link>https://rodaine.com/2013/09/how-to-report-a-bug-to-a-web-developer/</link><pubDate>Tue, 10 Sep 2013 00:00:00 +0000</pubDate><guid>https://rodaine.com/2013/09/how-to-report-a-bug-to-a-web-developer/</guid><description>&lt;p>Over on the &lt;a href="http://www.clarknikdelpowell.com/blog/">CNP Blog&lt;/a>, I contributed a post meant specifically for our clients: a guide on how to report bugs to web developers:&lt;/p>
&lt;blockquote>
 &lt;p>Oftentimes, this process is slowed, to the frustration of everyone involved, by a lack of information about the problem. So I implore you, dear reader, to take a few minutes to familiarize yourself with the following questions and the reasons why they are important to debugging a website. If you can answer any of these, your developer will be grateful and will likely be able to make the changes faster&amp;hellip;&lt;/p></description></item><item><title>Untangle HTML and Javascript using Dependency Injection</title><link>https://rodaine.com/2013/07/untangle-html-and-javascript-using-dependency-injection/</link><pubDate>Tue, 16 Jul 2013 00:00:00 +0000</pubDate><guid>https://rodaine.com/2013/07/untangle-html-and-javascript-using-dependency-injection/</guid><description>&lt;p>On the &lt;a href="http://www.clarknikdelpowell.com/blog">CNP Blog&lt;/a> today, I wrote a post outlining a technique for dependency injection in JavaScript. We&amp;rsquo;ve all been there in a JS project: a series of simple, innocuous event bindings explodes into thousands of lines of unmanageable code so reliant on the markup that making changes potentially generates more bugs than it fixes. Hyperbole? Perhaps not:&lt;/p>
&lt;blockquote>
 &lt;p>For small projects with minimal JavaScript, abstraction of this nature is unnecessary, but as soon as the project grows to more than a few hundred lines with many moving parts, managing the code and its relationship to the markup becomes exponentially more difficult. Implementing changes, new features and bug fixes might have unintended side effects that slow down development and produce serious code smell. By decoupling the DOM from the JavaScript and using dependency injection to associate functionality with the elements on the page, we can easily improve the quality of our code and make it more flexible, testable and reusable across projects.&lt;/p></description></item><item><title>404: Not Found</title><link>https://rodaine.com/404.html</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://rodaine.com/404.html</guid><description>&lt;p class="transparent">&lt;img src="https://rodaine.com/travolta.gif" alt="Confused Travolta Meme">&lt;/p></description></item><item><title>About Me</title><link>https://rodaine.com/chris-roche/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://rodaine.com/chris-roche/</guid><description>&lt;p>Oakland born and Orlando raised, I am a software engineer wrangling IDLs at &lt;a href="https://buf.build">Buf&lt;/a>. Previously, I worked with the kick-ass teams at &lt;a href="https://splice.com/">Splice&lt;/a>, &lt;a href="https://crossnokaye.com/">CrossnoKaye&lt;/a>, &lt;a href="https://www.lyft.com">Lyft&lt;/a>, &lt;a href="https://vsco.co">VSCO&lt;/a>, and &lt;a href="http://www.clarknikdelpowell.com">Clark/Nikdel/Powell&lt;/a>.&lt;/p>
&lt;p>In my time away from code, you can usually find me playing video games on the PlayStation or PC, watching TV shows on Netflix, Hulu and CrunchyRoll, or cooking up something new in the kitchen. Weekends you&amp;rsquo;ll find me hanging out with my friends at the bottom of a bottle of Malbec.&lt;/p></description></item></channel></rss>