<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Posts on Dan Peterson</title><link>https://danp.net/posts/</link><description>Recent content in Posts on Dan Peterson</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 27 Feb 2025 12:38:49 -0400</lastBuildDate><atom:link href="https://danp.net/posts/atom.xml" rel="self" type="application/rss+xml"/><item><title>Transportation and mental health</title><link>https://danp.net/posts/transportation-mental-health/</link><pubDate>Thu, 27 Feb 2025 12:38:49 -0400</pubDate><guid>https://danp.net/posts/transportation-mental-health/</guid><description>&lt;p&gt;&lt;em&gt;This is an email I sent to Mayor Andy Fillmore and Councillors Hinch and White on Feburary 27, 2025. An extra link to his Windsor Street Exchange comments added and a couple terms expanded for longer-term context.&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;Hi Mayor,&lt;/p&gt;&#10;&lt;p&gt;During &lt;a href="https://pub-halifax.escribemeetings.com/Players/ISIStandAlonePlayer.aspx?Id=1a99836f-812a-4a9a-9fed-6e78ef8874d1&amp;amp;initial_seek=14422" target="_blank"&gt;Tuesday&amp;rsquo;s Windsor Street Exchange&lt;/a&gt; item you said something about the impact of traffic or congestion on people&amp;rsquo;s mental health.&lt;/p&gt;&#10;&lt;p&gt;I think you meant because they are sitting in their cars and somehow a new Windsor Street Exchange or other projects are going to &amp;ldquo;ease congestion&amp;rdquo; and help that. (We know that private vehicle congestion can never be &amp;ldquo;eased,&amp;rdquo; except when the amount of private vehicles is reduced through mode shifts, congestion pricing, etc)&lt;/p&gt;</description></item><item><title>Making the Halifax sidewalk snow clearing map people want</title><link>https://danp.net/posts/halifax-sidewalk-snow-clearing-map/</link><pubDate>Sun, 23 Feb 2025 13:12:32 -0400</pubDate><guid>https://danp.net/posts/halifax-sidewalk-snow-clearing-map/</guid><description>&lt;p&gt;It snows in Halifax!&lt;/p&gt;&#10;&lt;p&gt;The city clears some sidewalks themselves and contracts out clearing of others.&lt;/p&gt;&#10;&lt;p&gt;If you want to find out when a sidewalk will be cleared, you need to know or look at:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://www.halifax.ca/transportation/winter-operations/snow-clearing-service-standards" target="_blank"&gt;Standards and timelines for sidewalk clearing&lt;/a&gt; (be sure you don&amp;rsquo;t look at street standards by mistake)&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://www.arcgis.com/apps/webappviewer/index.html?id=e1a41ad4fcd24fcfa40cc9bfb5048d56&amp;amp;extent=-7086587.3693%2C5563420.8546%2C-7068242.4825%2C5573137.9118%2C102100" target="_blank"&gt;Priority of the relevant sidewalk&lt;/a&gt; (again, be sure you don&amp;rsquo;t look at the street priorities map by mistake)&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://www.halifax.ca/transportation/winter-operations/service-updates" target="_blank"&gt;Service updates for the &amp;ldquo;weather event end time&amp;rdquo;&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;For example, sidewalks on Bloomfield St on the Halifax Peninsula are priority 3.&#10;That means they should be cleared within 36 hours from the end of a weather event.&#10;If an event ends at 9 am, they should be cleared by 9 pm the next day.&lt;/p&gt;</description></item><item><title>Better GitHub Actions caching for Go</title><link>https://danp.net/posts/github-actions-go-cache/</link><pubDate>Tue, 18 Feb 2025 12:23:45 -0400</pubDate><guid>https://danp.net/posts/github-actions-go-cache/</guid><description>&lt;p&gt;I&amp;rsquo;ve been spending some time on &lt;a href="https://en.wikipedia.org/wiki/Continuous_integration" target="_blank"&gt;CI&lt;/a&gt; improvements at &lt;a href="https://www.grax.com/" target="_blank"&gt;work&lt;/a&gt; recently, mostly around cutting down how long things take.&lt;/p&gt;&#10;&lt;p&gt;As I looked to see if anything about our overall process could be improved, a couple things bothered me:&lt;/p&gt;&#10;&lt;p&gt;Why, if we were using a pretty standard GitHub Actions setup, were there indications that modules were being downloaded as part of every run?&#10;Shouldn&amp;rsquo;t that all be cached?&lt;/p&gt;&#10;&lt;p&gt;Why did it seem like there was always a delay before tests actually started running?&#10;Shouldn&amp;rsquo;t the first few packages&amp;rsquo; fast tests complete quickly?&lt;/p&gt;</description></item><item><title>pgx, database/sql transactions, and COPY</title><link>https://danp.net/posts/pgx-tx-copy/</link><pubDate>Sun, 02 Feb 2025 14:01:32 -0400</pubDate><guid>https://danp.net/posts/pgx-tx-copy/</guid><description>&lt;p&gt;At &lt;a href="https://www.grax.com/" target="_blank"&gt;work&lt;/a&gt;, we&amp;rsquo;ve just about completed a migration from the &lt;a href="https://pkg.go.dev/github.com/lib/pq" target="_blank"&gt;lib/pq&lt;/a&gt; Go PostgreSQL driver to &lt;a href="https://pkg.go.dev/github.com/jackc/pgx/v5" target="_blank"&gt;pgx&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;We use the pgx &lt;a href="https://pkg.go.dev/github.com/jackc/pgx/v5/stdlib" target="_blank"&gt;database/sql compatibility layer&lt;/a&gt; so our code doesn&amp;rsquo;t need to care which driver is used, for the most part.&lt;/p&gt;&#10;&lt;p&gt;As we neared the end of the migration, one unsolved issue remained: using &lt;a href="https://www.postgresql.org/docs/current/sql-copy.html" target="_blank"&gt;&lt;code&gt;COPY&lt;/code&gt;&lt;/a&gt; inside transactions.&lt;/p&gt;&#10;&lt;p&gt;We use &lt;code&gt;COPY&lt;/code&gt; in a few places to bulk load data. With lib/pq, that looks something &lt;a href="https://pkg.go.dev/github.com/lib/pq#hdr-Bulk_imports" target="_blank"&gt;like this&lt;/a&gt;:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#177500"&gt;// db is a *database/sql.DB&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000"&gt;tx&lt;/span&gt;, &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#000"&gt;db&lt;/span&gt;.&lt;span style="color:#000"&gt;Begin&lt;/span&gt;()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;!=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;nil&lt;/span&gt; { &lt;span style="color:#177500"&gt;// ...&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;defer&lt;/span&gt; &lt;span style="color:#000"&gt;tx&lt;/span&gt;.&lt;span style="color:#000"&gt;Rollback&lt;/span&gt;()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000"&gt;stmt&lt;/span&gt;, &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#000"&gt;tx&lt;/span&gt;.&lt;span style="color:#000"&gt;Prepare&lt;/span&gt;(&lt;span style="color:#000"&gt;pq&lt;/span&gt;.&lt;span style="color:#000"&gt;CopyIn&lt;/span&gt;(&lt;span style="color:#c41a16"&gt;&amp;#34;users&amp;#34;&lt;/span&gt;, &lt;span style="color:#c41a16"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;, &lt;span style="color:#c41a16"&gt;&amp;#34;age&amp;#34;&lt;/span&gt;))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;!=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;nil&lt;/span&gt; { &lt;span style="color:#177500"&gt;// ...&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;for&lt;/span&gt; &lt;span style="color:#000"&gt;_&lt;/span&gt;, &lt;span style="color:#000"&gt;user&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;range&lt;/span&gt; &lt;span style="color:#000"&gt;users&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#000"&gt;_&lt;/span&gt;, &lt;span style="color:#000"&gt;err&lt;/span&gt; = &lt;span style="color:#000"&gt;stmt&lt;/span&gt;.&lt;span style="color:#000"&gt;Exec&lt;/span&gt;(&lt;span style="color:#000"&gt;user&lt;/span&gt;.&lt;span style="color:#000"&gt;Name&lt;/span&gt;, &lt;span style="color:#a90d91"&gt;int64&lt;/span&gt;(&lt;span style="color:#000"&gt;user&lt;/span&gt;.&lt;span style="color:#000"&gt;Age&lt;/span&gt;))&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#9;&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;!=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;nil&lt;/span&gt; { &lt;span style="color:#177500"&gt;// ...&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000"&gt;_&lt;/span&gt;, &lt;span style="color:#000"&gt;err&lt;/span&gt; = &lt;span style="color:#000"&gt;stmt&lt;/span&gt;.&lt;span style="color:#000"&gt;Exec&lt;/span&gt;()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;!=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;nil&lt;/span&gt; { &lt;span style="color:#177500"&gt;// ...&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000"&gt;err&lt;/span&gt; = &lt;span style="color:#000"&gt;stmt&lt;/span&gt;.&lt;span style="color:#000"&gt;Close&lt;/span&gt;()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;!=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;nil&lt;/span&gt; { &lt;span style="color:#177500"&gt;// ...&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#000"&gt;err&lt;/span&gt; = &lt;span style="color:#000"&gt;tx&lt;/span&gt;.&lt;span style="color:#000"&gt;Commit&lt;/span&gt;()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;!=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;nil&lt;/span&gt; { &lt;span style="color:#177500"&gt;// ...&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;pq.CopyIn(&amp;quot;users&amp;quot;, &amp;quot;name&amp;quot;, &amp;quot;age&amp;quot;)&lt;/code&gt; produces a statement that looks like:&lt;/p&gt;</description></item><item><title>Coming in Go 1.24: testing/synctest experiment for time and concurrency testing</title><link>https://danp.net/posts/synctest-experiment/</link><pubDate>Sun, 08 Dec 2024 09:01:58 -0400</pubDate><guid>https://danp.net/posts/synctest-experiment/</guid><description>&lt;p&gt;Testing code that involves time or concurrency can be a struggle.&#10;It often leads to hard-to-debug flakes in CI or long-running tests.&lt;/p&gt;&#10;&lt;p&gt;Go 1.24 is &lt;a href="https://go.dev/wiki/Go-Release-Cycle" target="_blank"&gt;scheduled to be released&lt;/a&gt; in February and the release freeze has begun.&lt;/p&gt;&#10;&lt;p&gt;It&amp;rsquo;s set to include an &lt;a href="https://github.com/golang/go/issues/69687" target="_blank"&gt;experimental &lt;code&gt;testing/synctest&lt;/code&gt; package&lt;/a&gt;&#10;designed to make testing code that involves time or concurrency precise and fast.&lt;/p&gt;&#10;&lt;p&gt;I&amp;rsquo;m pretty excited about it!&lt;/p&gt;&#10;&lt;h2 id="time-testing-trouble"&gt;Time testing trouble&lt;/h2&gt;&#10;&lt;p&gt;Suppose you have a test that looks like this:&lt;/p&gt;</description></item><item><title>Field Test Mode</title><link>https://danp.net/posts/field-test-mode/</link><pubDate>Mon, 18 Nov 2024 17:37:08 -0400</pubDate><guid>https://danp.net/posts/field-test-mode/</guid><description>&lt;p&gt;I&amp;rsquo;ve been having a lot of call trouble at home lately using &lt;a href="https://eastlink.ca/" target="_blank"&gt;Eastlink&lt;/a&gt; and an iPhone 13 mini.&lt;/p&gt;&#10;&lt;p&gt;Even though I have all the signal bars:&lt;/p&gt;&#10;&lt;figure&gt;&lt;img src="https://danp.net/posts/field-test-mode/bars.png"&#10;&#9;&#9;&#9;alt="A screenshot of the top of my phone&amp;#39;s home screen showing full cell signal bars."&gt;&lt;figcaption&gt;&#10;&#9;&#9;&#9;&lt;p&gt;Full bars&lt;/p&gt;&#10;&#9;&#9;&lt;/figcaption&gt;&#10;&lt;/figure&gt;&#10;&#10;&lt;p&gt;Received and placed calls would fail right away or audio would cut in and out for both sides.&lt;/p&gt;&#10;&lt;p&gt;I&amp;rsquo;ve been working with Eastlink support but no breakthroughs yet.&lt;/p&gt;</description></item><item><title>Monitoring convergence</title><link>https://danp.net/posts/monitoring-convergence/</link><pubDate>Sun, 20 Nov 2022 00:00:00 +0000</pubDate><guid>https://danp.net/posts/monitoring-convergence/</guid><description>&lt;p&gt;Where possible, I like to build systems around convergence.&lt;/p&gt;&#10;&lt;p&gt;These systems generally look something like:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Tick on some regular interval (10 minutes, 1 hour, etc)&lt;/li&gt;&#10;&lt;li&gt;Update the view of the world (discover new data, observe a value, etc)&lt;/li&gt;&#10;&lt;li&gt;Act on the updated view, possibly comparing to the previous view (stop some servers, process newly discovered data, etc)&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;For example, an auto scaling group would continually check instance health, load, etc,&#10;and converge on the desired or optimal number of servers by starting new ones or stopping existing ones.&lt;/p&gt;</description></item><item><title>My Mastodon setup</title><link>https://danp.net/posts/my-mastodon-setup/</link><pubDate>Sun, 13 Nov 2022 00:00:00 +0000</pubDate><guid>https://danp.net/posts/my-mastodon-setup/</guid><description>&lt;p&gt;It seems like Twitter may not be around much longer.&#10;Even if does stay around, it&amp;rsquo;s not likely to be a place I want to be anymore.&lt;/p&gt;&#10;&lt;p&gt;Like many folks, I decided to dip into the &lt;a href="https://en.wikipedia.org/wiki/Fediverse" target="_blank"&gt;Fediverse&lt;/a&gt;.&#10;Using &lt;a href="https://joinmastodon.org/" target="_blank"&gt;Mastodon&lt;/a&gt; seemed like a good first step.&#10;I set up an account on &lt;a href="https://mastodon.social/" target="_blank"&gt;mastodon.social&lt;/a&gt; but quickly realized it was overwhelmed.&#10;There were other servers to join but I wanted to run my own.&lt;/p&gt;&#10;&lt;p&gt;My goals:&lt;/p&gt;</description></item><item><title>macOS DNS resolving change in Go 1.20</title><link>https://danp.net/posts/macos-dns-change-in-go-1-20/</link><pubDate>Tue, 08 Nov 2022 00:00:00 +0000</pubDate><guid>https://danp.net/posts/macos-dns-change-in-go-1-20/</guid><description>&lt;h1 id="summary"&gt;Summary&lt;/h1&gt;&#10;&lt;p&gt;Starting in Go 1.20&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;, DNS lookups when running on macOS will be done via the system instead of via Go&amp;rsquo;s built-in resolver.&#10;That&amp;rsquo;s even when cgo is not available, such as when cross-compiling from Linux.&lt;/p&gt;&#10;&lt;p&gt;That should reduce surprises for people using tools cross-compiled for macOS from Linux, such as CLIs like terraform and kubectl.&#10;It should also make it easier for developers of those tools as building on macOS may no longer be necessary.&lt;/p&gt;</description></item><item><title>Mapping Halifax Traffic Calming Requests</title><link>https://danp.net/posts/mapping-halifax-traffic-calming-requests/</link><pubDate>Wed, 03 Mar 2021 12:00:00 +0000</pubDate><guid>https://danp.net/posts/mapping-halifax-traffic-calming-requests/</guid><description>&lt;p&gt;Halifax has a systemic road safety problem. One way it manifests is people driving too fast, especially on residential&#10;streets.&lt;/p&gt;&#10;&lt;p&gt;Recently, Halifax Regional Council mostly approved their 2021 capital budget. It includes $1 million for traffic calming&#10;and the final budget may include $1 million more. Read more about that&#10;&lt;a href="https://www.halifaxexaminer.ca/city-hall/halifax-councillors-vote-for-175-million-capital-budget-may-add-another-million-for-traffic-calming/" target="_blank"&gt;here&lt;/a&gt;&#10;or&#10;&lt;a href="https://www.cbc.ca/news/canada/nova-scotia/halifax-council-traffic-calming-budget-speeding-road-safety-1.5926663" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;The city&#10;&lt;a href="https://www.halifax.ca/transportation/streets-sidewalks/road-safety/traffic-calming-for-safer-streets" target="_blank"&gt;publishes&lt;/a&gt; a&#10;ranked list of approved requests. Not all requests are approved due to rules that contribute to the systemic&#10;problem. Even so, as of the last update on November 27, 2020, there are 282 approved requests.&lt;/p&gt;</description></item><item><title>Injecting errors to test idempotency</title><link>https://danp.net/posts/injecting-errors-to-test-idempotency/</link><pubDate>Wed, 24 Feb 2016 00:00:00 +0000</pubDate><guid>https://danp.net/posts/injecting-errors-to-test-idempotency/</guid><description>&lt;p&gt;As part of &lt;a href="https://www.heroku.com/private-spaces" target="_blank"&gt;Heroku Private Spaces&lt;/a&gt; we attach extra &lt;a href="http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html" target="_blank"&gt;Elastic Network Interfaces&lt;/a&gt;&#10;to instances, and we do that in Go with &lt;a href="https://github.com/aws/aws-sdk-go/" target="_blank"&gt;aws-sdk-go&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p&gt;The process isn&amp;rsquo;t the most idempotent and we recently discovered we were occasionally leaking ENIs. This could happen if we created an ENI and then encountered an error later in the process, such as when attaching it to an instance. I set out this morning to find a better way.&lt;/p&gt;&#10;&lt;p&gt;When an ENI is created, it can be assigned a description. Previously we used descriptions only for the ENI&amp;rsquo;s function (eg, &amp;ldquo;nat&amp;rdquo;) and not anything specific to the instance the ENI was intended for. After seeing that listing ENIs allows filtering on the description, I decided to make that the foundation of the new approach.&lt;/p&gt;</description></item><item><title>Reducing nesting in Go functions with early returns</title><link>https://danp.net/posts/reducing-go-nesting/</link><pubDate>Mon, 02 Nov 2015 00:00:00 +0000</pubDate><guid>https://danp.net/posts/reducing-go-nesting/</guid><description>&lt;p&gt;One of my favorite localized Go refactorings is reducing nesting by using &lt;code&gt;return&lt;/code&gt; as early as possible. Take this example, based on a recently-refactored function at Heroku:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="background-color:#fff;-moz-tab-size:2;-o-tab-size:2;tab-size:2;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a90d91"&gt;func&lt;/span&gt; &lt;span style="color:#000"&gt;example&lt;/span&gt;() &lt;span style="color:#a90d91"&gt;error&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#000"&gt;start&lt;/span&gt;(); &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;!=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;nil&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#000"&gt;existing&lt;/span&gt;, &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;:=&lt;/span&gt; &lt;span style="color:#000"&gt;fetchExisting&lt;/span&gt;()&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;err&lt;/span&gt; &lt;span style="color:#000"&gt;!=&lt;/span&gt; &lt;span style="color:#a90d91"&gt;nil&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a90d91"&gt;return&lt;/span&gt; &lt;span style="color:#000"&gt;err&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a90d91"&gt;if&lt;/span&gt; &lt;span style="color:#000"&gt;existing&lt;/span&gt;.&lt;span style="color:#000"&gt;IsWorking&lt;/span&gt;() {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a90d91"&gt;return&lt;/span&gt; &lt;span style="color:#a90d91"&gt;nil&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; } &lt;span style="color:#a90d91"&gt;else&lt;/span&gt; {&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a90d91"&gt;return&lt;/span&gt; &lt;span style="color:#000"&gt;errors&lt;/span&gt;.&lt;span style="color:#000"&gt;New&lt;/span&gt;(&lt;span style="color:#c41a16"&gt;&amp;#34;found existing but it&amp;#39;s not working&amp;#34;&lt;/span&gt;)&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a90d91"&gt;return&lt;/span&gt; &lt;span style="color:#a90d91"&gt;nil&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This can be hard to follow due to nesting inside &lt;code&gt;if ...; err != nil&lt;/code&gt; and use of &lt;code&gt;else&lt;/code&gt;. I prefer to &lt;code&gt;return&lt;/code&gt; as early as possible and avoid &lt;code&gt;else&lt;/code&gt;. Applying that, it now looks something like this:&lt;/p&gt;</description></item><item><title>Using postgression on Travis CI</title><link>https://danp.net/posts/postgression-on-travis-ci/</link><pubDate>Sun, 12 May 2013 00:00:00 +0000</pubDate><guid>https://danp.net/posts/postgression-on-travis-ci/</guid><description>&lt;p&gt;At &lt;a href="https://www.heroku.com" target="_blank"&gt;Heroku&lt;/a&gt; we use &lt;a href="http://about.travis-ci.org/docs/user/travis-pro/" target="_blank"&gt;Travis CI&lt;/a&gt; to run project tests on push to &lt;a href="https://github.com/" target="_blank"&gt;GitHub&lt;/a&gt;. While Travis CI offers &lt;a href="http://about.travis-ci.org/docs/user/database-setup/#PostgreSQL" target="_blank"&gt;PostgreSQL&lt;/a&gt; in their environment, it&amp;rsquo;s version 9.1. A project I&amp;rsquo;m working on recently started using PostgreSQL 9.2&amp;rsquo;s &lt;a href="http://www.postgresql.org/docs/9.2/static/datatype-json.html" target="_blank"&gt;JSON data type&lt;/a&gt;, which 9.1 does not have.&lt;/p&gt;&#10;&lt;p&gt;Needing 9.2, I searched for ways to make it available in the Travis CI environment. I found guides that suggested &lt;a href="http://reefpoints.dockyard.com/ruby/2013/03/29/running-postgresql-9.2-on-travis-ci.html" target="_blank"&gt;upgrading PostgreSQL&lt;/a&gt; in a &lt;code&gt;before_script&lt;/code&gt; but I didn&amp;rsquo;t have much luck with that approach. Plus, it would add time to each build which I was hoping to avoid. I knew &lt;a href="https://postgres.heroku.com/" target="_blank"&gt;Heroku Postgres&lt;/a&gt; offered 9.2 &lt;a href="https://postgres.heroku.com/blog/past/2013/4/18/postgres_92_now_default/" target="_blank"&gt;by default&lt;/a&gt;, what I really wanted was a fresh Heroku Postgres database for every test run.&lt;/p&gt;</description></item><item><title>Introduction to Ledger</title><link>https://danp.net/posts/introduction-to-ledger/</link><pubDate>Sun, 28 Aug 2011 00:00:00 +0000</pubDate><guid>https://danp.net/posts/introduction-to-ledger/</guid><description>&lt;p&gt;Since July 30th, I&amp;rsquo;ve been using &lt;a href="http://www.ledger-cli.org/" target="_blank"&gt;ledger&lt;/a&gt; (on &lt;a href="https://github.com/jwiegley/ledger" target="_blank"&gt;GitHub&lt;/a&gt;) to track my personal finances. What did I use before? I&amp;rsquo;m ashamed to say nothing beyond my banks&amp;rsquo; sites.&lt;/p&gt;&#10;&lt;p&gt;I stumbled upon ledger via &lt;a href="http://bugsplat.info/2011-07-09-program-your-finances-reporting-for-fun-and-profit.html" target="_blank"&gt;this blog post&lt;/a&gt;, linked from Hacker News. It took me a while to try it, for a few reasons. First, I had a weird notion that there would be a better time in my various &amp;ldquo;fiscal cycles&amp;rdquo; to start using such a thing. Should I wait until the end of the monthly statement periods for my various accounts? No, this was just procrastination. Second, I need to easily deal in both USD and CAD. I live in Canada and am paid in CAD but being a US citizen from Arizona I still have many dealings in the US that involve USD. My Canadian and US RBC accounts are linked and it&amp;rsquo;s easy (and instant) to transfer between them, though I usually only go from my Canadian accounts to my US accounts. That had been a big barrier in trying things like &lt;a href="https://github.com/jamis/bucketwise" target="_blank"&gt;bucketwise&lt;/a&gt;, though I do like its concept.&lt;/p&gt;</description></item></channel></rss>