<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>tychoish</title>
    <link>http://tychoish.com/index.xml</link>
    <description>Recent content on tychoish</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <copyright>Licensed under a [Creative Commons Attribution-ShareAlike 4.0 International License.](https://creativecommons.org/licenses/by-sa/4.0/)</copyright>
    <lastBuildDate>Tue, 17 Jan 2017 00:00:00 +0000</lastBuildDate>
    <atom:link href="http://tychoish.com/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Amboy: Golang Queue Introduction</title>
      <link>http://tychoish.com/post/amboy-golang-queue-introduction/</link>
      <pubDate>Tue, 17 Jan 2017 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/post/amboy-golang-queue-introduction/</guid>
      <description>&lt;p&gt;Amboy is centered around a collection of interfaces: queues to
describe &amp;quot;collections of offline work,&amp;quot; jobs for &amp;quot;units of work&amp;quot;,
runners for &amp;quot;task executors.&amp;quot; There&#39;s also a notion of a &amp;quot;remote
queue&amp;quot; which has some additional abstraction around non-local
persistence of work.&lt;/p&gt;
&lt;p&gt;Then, if you can define your applications core work (e.g. &amp;quot;business
logic&amp;quot;) in terms of discrete units of work, then you can use these
workers and the infrastructure around them to manage &lt;em&gt;most&lt;/em&gt; of the
work of your application. And the infrastructure around them is pretty
useful: you can read some &lt;a class=&#34;reference external&#34; href=&#34;http://tychoish.com/post/amboy-golang-worker-queues&#34;&gt;background on this project in an earlier
post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Amboy is two things: first a collection of interfaces that define a
simple worker/queue system, and second a collection of simple
straightforward example implementations tailored to a few basic use
cases.&lt;/p&gt;
&lt;div class=&#34;section&#34; id=&#34;one-buildsystems-a-la-make&#34;&gt;
&lt;h1&gt;One: Buildsystems a la Make&lt;/h1&gt;
&lt;p&gt;A collection of features make it pretty possible to implement a simple
Make-like engine using Amboy for all the task processing. The
&lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/mongodb/amboy/dependency#Manager&#34;&gt;dependency.Manager&lt;/a&gt;
interface which is a property of every Job, makes it possible to
define relationships between jobs, as well as define arbitrary checks
to determine if a job should run.&lt;/p&gt;
&lt;p&gt;The &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/mongodb/amboy/queue#LocalOrdered&#34;&gt;LocalOrderedQueue&lt;/a&gt; uses
this dependency manager information, to dispatch jobs to workers
ordered by dependencies and prerequisites.&lt;/p&gt;
&lt;p&gt;The limitation of this queue is that all tasks must be defined before
starting the queue. It&#39;s also a &amp;quot;local&amp;quot; queuue, and only stores queues
locally, and cannot persist workers. Nevertheless, I&#39;d be interested
in developing implementations that would provide the same kind of
ordering benefits without these requirements.&lt;/p&gt;
&lt;p&gt;Amboy is not a make &lt;em&gt;replacement&lt;/em&gt; but it has all the tools needed to
build a custom build system.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;section&#34; id=&#34;two-job-base-for-simple-job-construction&#34;&gt;
&lt;h1&gt;Two: job.Base for Simple Job Construction&lt;/h1&gt;
&lt;p&gt;The &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/mongodb/amboy/job#Base&#34;&gt;job.Base&lt;/a&gt;
struct implements all requireed methods of the &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/mongodb/amboy#Job&#34;&gt;Job&lt;/a&gt; interface other
than the Run method. This means that by including this structure you
only need to implement a constructor a &lt;tt class=&#34;docutils literal&#34;&gt;Run()&lt;/tt&gt; method to have a job.&lt;/p&gt;
&lt;p&gt;There are cases, when it makes sense to implement custom handlers,
particularly (e.g. constraining default SetDependency/Dependency
getters/setters,) but for the most part tasks should be easier to
define.&lt;/p&gt;
&lt;p&gt;As a general rule, I&#39;d treat &lt;tt class=&#34;docutils literal&#34;&gt;Run&lt;/tt&gt; methods like the &lt;tt class=&#34;docutils literal&#34;&gt;main&lt;/tt&gt; methods of
your program, mostly to make it easier to test and organize.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;section&#34; id=&#34;three-job-centric-application&#34;&gt;
&lt;h1&gt;Three: Job Centric Application&lt;/h1&gt;
&lt;p&gt;Many applications are reasonably job-oriented, or have significant
components that are offline require asynchronous job processing:
downloading large numbers of files, validating resources, generating
content from templates, running tests.&lt;/p&gt;
&lt;p&gt;I end up writing a fair number of command line tools, which are
generally &amp;quot;read a config file and command line operations and then
complete a number of tasks, and the return.&amp;quot; Often the &amp;quot;number of
tasks&amp;quot; in the middle of this translate easily in to a Job, in the
Amboy sense.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;section&#34; id=&#34;four-queue-as-embedded-tool&#34;&gt;
&lt;h1&gt;Four: Queue as Embedded Tool&lt;/h1&gt;
&lt;p&gt;In a number of cases, it makes sense to keep the worker-queue and job
aspects of your application as an implementation detail. I did this a
bunch in the &lt;a class=&#34;reference external&#34; href=&#34;https://github.com/tychoish/bond&#34;&gt;bond&lt;/a&gt; package, which
provides a functional interface, around something (downloading release
archives) that&#39;s implemented using an amboy queue. It&#39;s also core to
the way the S3 file syncing tool works inside of &lt;a class=&#34;reference external&#34; href=&#34;https://github.com/mongodb/curator&#34;&gt;curator&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;section&#34; id=&#34;five-one-queue-many-workers&#34;&gt;
&lt;h1&gt;Five: One Queue Many Workers&lt;/h1&gt;
&lt;p&gt;The &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/mongodb/amboy/queue#RemoteUnordered&#34;&gt;remote queue&lt;/a&gt;
and the &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/mongodb/amboy/queue/driver&#34;&gt;queue driver package&lt;/a&gt; make it
possible to have multiple queue front ends acting on a single queue
back end. When the queue back end (e.g. the persistence layer,) is
in-memory, this isn&#39;t super exciting; however, when that persistence
layer is a database, say, the possibilities are more exciting.&lt;/p&gt;
&lt;p&gt;The job, then, becomes a way that the application can persist data
(though need not be the only unit of persistence,) and indeed jobs
themselves might want to access a persistence layer outside of their
own internal state, and a way that application instances can attempt
to achieve statelessness.&lt;/p&gt;
&lt;p&gt;I&#39;m interested in writing additional queue front ends that use the
Driver interface: something that manages dependencies, perhaps. I&#39;m
also interested in thinking about the locking model, and seeing if
there are ways to simplify matters.&#39;&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;section&#34; id=&#34;six-the-rest-interface&#34;&gt;
&lt;h1&gt;Six: the REST Interface&lt;/h1&gt;
&lt;p&gt;Initially I thought that applications would have their own rest
interface, and clients would make requests that would trigger job
creation and execution the server.&lt;/p&gt;
&lt;p&gt;That&#39;s a nifty idea, but amboy already has this &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/mongodb/amboy/registry&#34;&gt;registry and
interchange&lt;/a&gt;
facility to make it possible to serialize jobs, and since jobs are
really just structs, and the operations around submitting a job.&lt;/p&gt;
&lt;p&gt;So there&#39;s a &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/mongodb/amboy/rest#Service&#34;&gt;Service&lt;/a&gt; (built
with &lt;a class=&#34;reference external&#34; href=&#34;https://github.com/tychoish/gimlet&#34;&gt;gimlet&lt;/a&gt;) and a &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/mongodb/amboy/service#Client&#34;&gt;Client&lt;/a&gt; which
you can use in your own applications for something that might look a
lot like RPC.&lt;/p&gt;
&lt;p&gt;Jobs, as part of their &lt;tt class=&#34;docutils literal&#34;&gt;Type()&lt;/tt&gt; method &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/mongodb/amboy#JobType&#34;&gt;have information&lt;/a&gt; that s helpful
to prevent incompatible clients and services. Having said that, I
think these aspects of amboy could use a lot more development,
including, better support for SSL/TLS, an implementation of &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/mongodb/amboy#Runner&#34;&gt;Runner&lt;/a&gt; that is
implemented on top of one or more remote REST interfaces.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Amboy: Golang Worker Queues</title>
      <link>http://tychoish.com/post/amboy-golang-worker-queues/</link>
      <pubDate>Mon, 16 Jan 2017 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/post/amboy-golang-worker-queues/</guid>
      <description>&lt;p&gt;This spring and summer I worked on a new Go library called Amboy that
provides a few useful (to my mind!) abstractions and tools around
worker pools and job queues, and as its stabilized a bit, I wanted to
take a chance to write more about it.&lt;/p&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;Amboy is really just a side effect of my main project over this time
period. I was working on a project to automate the way that we
generate Linux package repositories for our software. The procedure
itself is pretty straightforward, the challenges are about the number
and size of the files to download, the fact that the duration of the
operation can take many minutes, and figuring out the best way to
handle task overhead and parallelism of these tasks.&lt;/p&gt;
&lt;p&gt;Historically these operations have run on a single shared service, to
help cut the overhead and make it possible to reduce potential
concurrency bugs. While the project made it possible to break the
shared service into a bunch of different concurrent/stateless
processes, we delayed decisions about the process until quite late in
the process, leaving open the idea that we might want to use a shared
service.&lt;/p&gt;
&lt;p&gt;Enter Amboy.&lt;/p&gt;
&lt;p&gt;I wanted to be able to develop and test a system that ran as part of a
single local process: something with a command line interface that I
could run by hand as needed. But I also wanted to be able to run the
same code as a service. If things came to that.&lt;/p&gt;
&lt;p&gt;The thing about writing services, is I think it&#39;s important to do it
right. There had been a service but that&#39;s really stretching it: it
was a script in a cron job, and you could only run one copy of the
script at a time or &lt;em&gt;bad things happened&lt;/em&gt;. I&#39;ve also known lots of &amp;quot;real&amp;quot;
applications that don&#39;t &lt;em&gt;quite&lt;/em&gt; support multiple concurrent
instances. As a result I tend to think that applications have to be
stateless in order to be &amp;quot;real&amp;quot; and &amp;quot;deplorably.&amp;quot;&lt;/p&gt;
&lt;p&gt;Amboy is centered around a the idea of &amp;quot;offline&amp;quot; job queues, and
provides a collection of tools that address processing, storing,
groups of operations. If you define your work unit so that it
implements the &lt;tt class=&#34;docutils literal&#34;&gt;amboy.Job&lt;/tt&gt; interface, then you can execute it
locally, or you can submit it to a queue that many workers could
service. And there&#39;s a rest interface and client, or the tools to
build the same, as needed.&lt;/p&gt;
&lt;p&gt;The best, and perhaps most rewarding is seeing how in subsequent
projects there&#39;s been an Amboy-shaped aspect that appears pretty
naturally, and it&#39;s helped other projects, like &lt;a class=&#34;reference external&#34; href=&#34;https://github.com/mongodb/greenbay&#34;&gt;greenbay&lt;/a&gt; a
system tool and &lt;a class=&#34;reference external&#34; href=&#34;https://jira.mongodb.org/browse/MAKE-131&#34;&gt;an idea for a monitoring tool based on greenbay&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I want to write more about the system and some aspects that I hope to
develop as needed, but that feels like another issue for another
day.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Consciousness Rising</title>
      <link>http://tychoish.com/post/consciousiness-rising/</link>
      <pubDate>Thu, 24 Nov 2016 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/post/consciousiness-rising/</guid>
      <description>&lt;p&gt;The subtitle of this post should be &amp;quot;or, how the internet learned about
intersectionality,&amp;quot; but while I &lt;em&gt;love&lt;/em&gt; a good pretentious academic
title, I don&#39;t think that&#39;s particularly representative of my intent
here.&lt;/p&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;Sometime in the last 5 or 10 years, the popular discourse on justice
on the internet learned about &lt;em&gt;intersectionality&lt;/em&gt;. Which is
great. Intersectionality, generally is the notion that a single
identity isn&#39;t sufficient to explain an individuals social experience
particularly vis a vis privilege. Cool.&lt;/p&gt;
&lt;p&gt;This is really crucial and really important for understanding how the
world works, but for totally understandable and plain ways. People
have a lot of different identities which lead to many different
experiences, perspectives, and understandings. All of these
identities, experiences, perspectives, and understandings &lt;em&gt;interact with
each other&lt;/em&gt; in a big complex system&lt;/p&gt;
&lt;p&gt;Therefore our analysis of our experiences, thought, understandings,
and identities, must explore identities (&lt;em&gt;ET AL&lt;/em&gt;) not only on their
own terms, but in conversation with each other and with other aspects
of experience.&lt;/p&gt;
&lt;p&gt;Intersectionality is incredibly important. It&#39;s also incredibly useful
as a critical tool because it makes it possible for our thought to
reflect actual lived experiences and the way that various aspects of
experience interact to create &lt;em&gt;culture&lt;/em&gt; and &lt;em&gt;society&lt;/em&gt;. &lt;a class=&#34;footnote-reference&#34; href=&#34;#materialism&#34; id=&#34;id1&#34;&gt;[1]&lt;/a&gt;&lt;/p&gt;
&lt;table class=&#34;docutils footnote&#34; frame=&#34;void&#34; id=&#34;materialism&#34; rules=&#34;none&#34;&gt;
&lt;colgroup&gt;&lt;col class=&#34;label&#34; /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign=&#34;top&#34;&gt;
&lt;tr&gt;&lt;td class=&#34;label&#34;&gt;&lt;a class=&#34;fn-backref&#34; href=&#34;#id1&#34;&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;A lot of arguments in favor of intersectional
analysis and perspectives are &lt;em&gt;political&lt;/em&gt;, and raise the very real
critique that analysis that is not intersectional tends to
recapitulate normative cultural assumptions. I&#39;d argue,
additionally, that intersectionality is really the only way to
pull apart experiences and thoughts and understand &lt;em&gt;fundamentally&lt;/em&gt;
how culture works. It&#39;s not &lt;em&gt;just&lt;/em&gt; good politics, but required
methodology for learning about our world and our lives.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;While intersectionality is an interesting and important concept that
could certainly support an entire blog post, I&#39;m more interested, the
genealogy of this concept in the popular critical discourse.&lt;/p&gt;
&lt;p&gt;I know that I read a lot about intersectionality in college (in
2004-2007), I know that the papers I read were at least 10 years old,
and I know that intersectionality wasn&#39;t an available concept to
political conversations on the internet at the time in the way that it
is now. &lt;a class=&#34;footnote-reference&#34; href=&#34;#internet-learns&#34; id=&#34;id2&#34;&gt;[2]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Concepts take a long time, centuries sometimes, to filter into general
awareness, so the delay itself isn&#39;t particularly notable. Even the
specific route isn&#39;t &lt;em&gt;that&lt;/em&gt; interesting in and for itself. Rather, I&#39;m
interested in how a concept proliferates and what is required for a
concept to become available to a more popular discourse.&lt;/p&gt;
&lt;p&gt;If interesectionality was an available concept in the academic
literature, what changes and evolutions in thought--both about
intersectionality, but in the context--needed to happen for that
concept to become available more broadly.&lt;/p&gt;
&lt;table class=&#34;docutils footnote&#34; frame=&#34;void&#34; id=&#34;internet-learns&#34; rules=&#34;none&#34;&gt;
&lt;colgroup&gt;&lt;col class=&#34;label&#34; /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign=&#34;top&#34;&gt;
&lt;tr&gt;&lt;td class=&#34;label&#34;&gt;&lt;a class=&#34;fn-backref&#34; href=&#34;#id2&#34;&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;I admit that this post is based on the conceit
that there was a point when the popular discourse (on the internet)
was unaware of intersectionality followed linearly by another point
where the concept of intersectionality was available
generally. This isn&#39;t how the dissemination of concepts into
discourses work, and I&#39;m aware that I&#39;ve oversimplified the idea
somewhat. This is more about the process of popularization.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;I think it&#39;s particularly exciting to trace the recent intelectual
history of a specific concept in discourse, because it might give us
insight into the next concepts that will help inform our discourse
&lt;em&gt;and&lt;/em&gt; things we can do to facilitate this process in the future for
new concepts and perspectives.&lt;/p&gt;
&lt;p&gt;As we understand the history of this proliferation, we can also
understand its failures and inefficiencies and attempt to deploy new
strategies that resolve those shortcomings.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Cache Maintence</title>
      <link>http://tychoish.com/post/cache-maintence/</link>
      <pubDate>Fri, 11 Nov 2016 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/post/cache-maintence/</guid>
      <description>&lt;p&gt;Twice this fall I&#39;ve worked on code that takes a group of files and
ensures that the total size of the files are less than a given
size. The operation is pretty simple: identify all the files and their
size (recursively, or not but accounting for the size of directories,)
sort them, and and delete files from the front or back of the
populated list. When you&#39;ve reached the desired size.&lt;/p&gt;
&lt;p&gt;If you have a cache and you&#39;re constantly adding content to it,
eventually you will either need an infinite amount of storage &lt;em&gt;or&lt;/em&gt;
you&#39;ll have to delete something.&lt;/p&gt;
&lt;p&gt;But what to delete? And how?&lt;/p&gt;
&lt;p&gt;Presumably you use some items in the cache more often than others, and
some files that change very often while others change very rarely, and
in many cases, use and change frequency are orthogonal.&lt;/p&gt;
&lt;p&gt;For the cases that I&#39;ve worked on, the first case, frequency of use,
is the property that we&#39;re interested in. If we haven&#39;t used a file in
a while relative to the other files, the chances are its safe to
delete.&lt;/p&gt;
&lt;p&gt;The problem is that &lt;em&gt;access time&lt;/em&gt; (&lt;tt class=&#34;docutils literal&#34;&gt;atime&lt;/tt&gt;) is that while most file
systems have a concept of &lt;tt class=&#34;docutils literal&#34;&gt;atime&lt;/tt&gt;, most of them don&#39;t &lt;em&gt;update&lt;/em&gt;
it. Which makes sense: if every time you read a file you have to
update the metadata, then every read operation becomes a write
operations, and everything becomes slow.&lt;/p&gt;
&lt;p&gt;Relative access time or, &lt;tt class=&#34;docutils literal&#34;&gt;relatime&lt;/tt&gt;, helps some. Here &lt;tt class=&#34;docutils literal&#34;&gt;atime&lt;/tt&gt; is
updated, but only if you&#39;re writing to the file &lt;em&gt;or&lt;/em&gt; if it&#39;s been more
than 24 hours since your last update. The problem, of course, is that
if cache are write-once-read-many and operates with a time granularity of
less than a day, then &lt;tt class=&#34;docutils literal&#34;&gt;relatime&lt;/tt&gt; is often just creation time. That&#39;s
no good.&lt;/p&gt;
&lt;p&gt;The approach I&#39;ve been taking is to use the last &lt;em&gt;modification&lt;/em&gt; time,
(&lt;tt class=&#34;docutils literal&#34;&gt;mtime&lt;/tt&gt;), and to intentionally update &lt;tt class=&#34;docutils literal&#34;&gt;mtime&lt;/tt&gt; (e.g. using &lt;tt class=&#34;docutils literal&#34;&gt;touch&lt;/tt&gt;
or a similar operation,) after cache access. It&#39;s slightly less
elegant than it could be, but it works really well and requires very
little overhead.&lt;/p&gt;
&lt;p&gt;Armed with these decisions all you need is a thing that crawls a file
system, collects objects and stores their size and time, so we know
how large the cache is, and can maintain an ordered list of file
objects by &lt;tt class=&#34;docutils literal&#34;&gt;mtime&lt;/tt&gt;. The ordered lists of files &lt;em&gt;should&lt;/em&gt; be a heap,
but the truth is that you build and sort the structure once, and then
just remove the &amp;quot;lowest&amp;quot; (oldest) items until the cache is the right
size and then throwing it all away, so you&#39;re not really doing many
heap-ish operations.&lt;/p&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;Therefore, I present &lt;a class=&#34;reference external&#34; href=&#34;https://github.com/tychoish/lru&#34;&gt;lru&lt;/a&gt;. Earlier
this summer I wrote a less generic implementation of the same
principal, and was elbows deep into another project when I realized I
needed &lt;em&gt;another cache pruning tool&lt;/em&gt;. Sensing a trend, I decided to put
a little more time into the project and built it out as a library that
other people can use, though frankly I&#39;m mostly concerned about my
future self.&lt;/p&gt;
&lt;p&gt;The package has two types, a &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/tychoish/lru#Cache&#34;&gt;Cache&lt;/a&gt; type that
incorporates the core functionality and &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/tychoish/lru#FileObject&#34;&gt;FileObject&lt;/a&gt; which
represents items in the cache.&lt;/p&gt;
&lt;p&gt;Operation is simple. You can construct and add items to the cache
manually, or you can use &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/tychoish/lru#DirectoryContents&#34;&gt;DirectoryContents&lt;/a&gt;
or &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/tychoish/lru#TreeContents&#34;&gt;TreeContents&lt;/a&gt; which
build caches from a starting file system point. &lt;tt class=&#34;docutils literal&#34;&gt;DirectoryContents&lt;/tt&gt;
looks at the contents of a single directory (skipping sub-directories
optionally) and returns a &lt;tt class=&#34;docutils literal&#34;&gt;Cache&lt;/tt&gt; object with those contents. If you
do not skip directories, each directory has, in the cache the total
size of its contents.&lt;/p&gt;
&lt;p&gt;&lt;tt class=&#34;docutils literal&#34;&gt;TreeContents&lt;/tt&gt; recurses through the tree and ignores
directories, and returns a &lt;tt class=&#34;docutils literal&#34;&gt;Cache&lt;/tt&gt; object with all of those
elements. &lt;tt class=&#34;docutils literal&#34;&gt;TreeContents&lt;/tt&gt; does not clean up empty directories.&lt;/p&gt;
&lt;p&gt;Once you have a &lt;tt class=&#34;docutils literal&#34;&gt;Cache&lt;/tt&gt; object, use its &lt;a class=&#34;reference external&#34; href=&#34;https://godoc.org/github.com/tychoish/lru#Cache.Prune&#34;&gt;Prune&lt;/a&gt; method with
the maximum size of the cache (in bytes), any objects to exclude, and
an optional dry-run flag, to prune the cache down until it&#39;s less than
or equal to the max size.&lt;/p&gt;
&lt;p&gt;Done.&lt;/p&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;I&#39;m not planning any substantive changes to the library at this time
as it meets most of my needs but there are some obvious features:&lt;/p&gt;
&lt;ul class=&#34;simple&#34;&gt;
&lt;li&gt;a daemon mode where the cache object can &amp;quot;watch&amp;quot; a file system
(using ionotify or similar) and add items to or update existing
items in the cache. Potentially using &lt;a class=&#34;reference external&#34; href=&#34;https://github.com/fsnotify/fsnotify&#34;&gt;fsnotify&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;an option to delete empty directories encountered during pruning.&lt;/li&gt;
&lt;li&gt;options to use other time data from the file system when possible,
potentially using the &lt;a class=&#34;reference external&#34; href=&#34;https://github.com/djherbis/times&#34;&gt;times library&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;With luck, I can go a little while longer without doing this
again. With a little more luck, you&#39;ll find &lt;tt class=&#34;docutils literal&#34;&gt;lru&lt;/tt&gt; useful.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Deleuze and Grove</title>
      <link>http://tychoish.com/post/deleuze-and-grove/</link>
      <pubDate>Thu, 10 Nov 2016 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/post/deleuze-and-grove/</guid>
      <description>&lt;p&gt;I&#39;ve been reading, two books &lt;em&gt;non-fiction&lt;/em&gt; intermittently in the last
little bit: Andy Grove&#39;s &lt;em&gt;High Output Management&lt;/em&gt; and Deleuze and
Guatteri&#39;s &lt;em&gt;What is Philosophy?&lt;/em&gt;. Not only is reading non-fiction
somewhat novel for me, but I&#39;m sorting delighting in the
juxtaposition. And I&#39;m finding both books pretty compelling.&lt;/p&gt;
&lt;p&gt;These are fundamentally &lt;em&gt;materialist&lt;/em&gt; works. Grove&#39;s writing from his
experience as a manager, but it&#39;s a book about organizing that focuses
on personal and organizational effectiveness, with a lot of corporate
high-tech company examples. But the fact that it&#39;s a high-tech company
that works on actually producing things, means that he&#39;s thinking a
lot about production and material constraints. It&#39;s particularly
interesting because the discussion technology and management often
lead to popular writing that&#39;s &lt;em&gt;handwavey&lt;/em&gt; and abstract: this is not
what Grove&#39;s book is in the slightest.&lt;/p&gt;
&lt;p&gt;Deleuze is more complex, and Guatteri definitely tempers the
materialism, though less in the case of &lt;em&gt;What is Philosophy&lt;/em&gt; than the
earlier books. Having said that, I think &lt;em&gt;What is Philosophy&lt;/em&gt; is really an
attempt to both justify philosophy in and for itself, but also to
discuss the project of knowledge (&lt;em&gt;concept&lt;/em&gt;) creation in material,
mechanistic terms.&lt;/p&gt;
&lt;p&gt;To be honest this is the thing that I find the most compelling about
Deleuze in general: he&#39;s undeniably materialist in his outlook and
approach, but but his work often--thanks to Guatteri, I think--focuses
on issues central to non-materialist thought: interiority,
subjectivity, experience, and identity. Without loosing the need to
explore systems, mechanisms, and interfaces between and among related
components and concepts.&lt;/p&gt;
&lt;p&gt;I talked with a coworker about the fact that I&#39;ve been reading both of
these pieces together, and he said something to the effect of &amp;quot;yeah,
Grove rambles a bunch but has a lot of good points, which is basically
the same as Deleuze.&amp;quot; Fair. I&#39;d even go a bit further and say that
these are both books, that are despite their specialized topics and
focus, are really deep down books for everyone, and guides for
being in the world.&lt;/p&gt;
&lt;p&gt;Read them both.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Isolation and Ideology Change</title>
      <link>http://tychoish.com/post/isolation-ideology-change/</link>
      <pubDate>Thu, 10 Nov 2016 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/post/isolation-ideology-change/</guid>
      <description>&lt;p&gt;Following the 2016 election my father, who is a much more active
participant in Facebook than I, said something to the effect of &amp;quot;don&#39;t
mourn; organize. I had a long winded post on the topic of &#39;don&#39;t
celebrate; organize&#39;, but the bottom line is the same: organize.&amp;quot;&lt;/p&gt;
&lt;p&gt;I&#39;d append to this just to make clear that I&#39;m of the opinion that
self care, survival and the care for and survival of our communities
is &lt;em&gt;crucial&lt;/em&gt;. Which sometimes means celebration and sometimes means
mourning and sometimes means a quiet night at home with the and
friends.&lt;/p&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;At the 2016 New England Sacred Harp Convention a friend of mine gave a
lesion for those members of the community who were unable to attend
because of profound illness which was delivered in conjunction with a
lession in memorial for members of the community who had died in the
last year. These lessons are a common and enduring tradition of Sacred
Harp conventions.&lt;/p&gt;
&lt;p&gt;The lesson focused on isolation, and the ways that illness, care-giving
(and indeed dying, death, and grief) are isolating. But it went on to
discuss the ways that we combat isolation, through &lt;strong&gt;connections&lt;/strong&gt; to
people and communities, and by the project of &lt;strong&gt;meaning making&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Connection and meaning making are related, of course, and are central
to why I sing. I mean I also enjoy the music, but it&#39;s the connection
with other singers, and the ways that our practices in and around
singing are about making meaning.&lt;/p&gt;
&lt;p&gt;I heard this almost 6 weeks ago, but I keep coming back to this in a
number of different contexts. There&#39;s a lot in the world that either
directly isolates, or provokes feelings of isolation.&lt;/p&gt;
&lt;p&gt;Bottom line, the way that we can fight isolation is by forming
connections and by working to create meaning in our lives.&lt;/p&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;I was talking on Wednesday with a couple of friends, one of who was most
distraught at the seeming impossibility of progress. &amp;quot;What can I do?
There are all these people, and I&#39;m not sure anything I can do will
have any effect.&amp;quot; I think this distress is incredibly common and
reasonable, given the size of the task and the amount of time any
person has in the world.&lt;/p&gt;
&lt;p&gt;The task of effecting change is huge on its own, but the project is
compounded by its scale: there are a lot of people in the world and a
lot of different views. It&#39;s difficult to even know where to begin.&lt;/p&gt;
&lt;p&gt;I think fundamentally this kind of distress is about the isolation
created by the experience of difference, by the size of the task.&lt;/p&gt;
&lt;p&gt;There are tools that we can use for managing and fighting our own
isolation: building connections to each other, creating meaning in our
lives and in our social spheres.&lt;/p&gt;
&lt;p&gt;This is also, interestingly, these are the same methods that we use to
organize, to build consciousness, and to change ideologies.&lt;/p&gt;
&lt;p&gt;On Wednesday, I said, that (for the most part) people are just people:
the way that thought changes is through meaningfulrelationships,
conversation, and through additional opportunities to make meaning and
to form connections in a larger context.&lt;/p&gt;
&lt;p&gt;Seek out people and experiences that are different. Stay
safe. Listen. Learn. Talk. Teach. Share your experiences with people who are
like you. Work hard. Take breaks. Remember that people are, for the most
part, just people, and we&#39;re all alone in this together. All of us.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Shimgo Hugo</title>
      <link>http://tychoish.com/post/shimgo-hugo/</link>
      <pubDate>Sun, 06 Nov 2016 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/post/shimgo-hugo/</guid>
      <description>&lt;p&gt;In an effort to relaunch &lt;em&gt;tychoish&lt;/em&gt; with a more contemporary theme and
a publishing tool that (hopefully) will support a more regular posting
schedule, I also wrote a nifty go library for dealing with
reStructuredText, which may be useful &lt;em&gt;and&lt;/em&gt; I think illustrates
something about build systems.&lt;/p&gt;
&lt;p&gt;In my (apparently still) usual style, there&#39;s some narrative lead in
that that takes a bit to get through.&lt;/p&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;Over the past couple of weeks, I redesigned and redeployed my
blog. The system it replaced was somewhat cobbled together, was
missing a number of features (e.g. archives, rss feeds, social
features, etc) and to add insult to injury it was pretty publishing
was pretty slow, and it was difficult to manage a pipeline of posts.&lt;/p&gt;
&lt;p&gt;In short, I didn&#39;t post much, though I&#39;ve written things from time to
time that I haven&#39;t done a great job of actually posting them, and it
was hard to actually get people to read them, which was further
demotivating. I&#39;ve been reading a lot of interesting things, and I&#39;m
not writing that much for work any more, and I&#39;ve been doing enough
things recently that I want to write about them. See this &lt;a class=&#34;reference external&#34; href=&#34;https://twitter.com/tychoish/status/792143021156470784&#34;&gt;twitter
strand I had a bit ago on the topic&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So I started playing around again. Powering this blog is hard, because
I have a lot of content &lt;a class=&#34;footnote-reference&#34; href=&#34;#note&#34; id=&#34;id1&#34;&gt;[1]&lt;/a&gt; and I very much want to use
&lt;a class=&#34;reference external&#34; href=&#34;http://docutils.sourceforge.net/rst.html&#34;&gt;restructuredText&lt;/a&gt;.
&lt;a class=&#34;footnote-reference&#34; href=&#34;#rst&#34; id=&#34;id2&#34;&gt;[2]&lt;/a&gt; There&#39;s this thing called &lt;a class=&#34;reference external&#34; href=&#34;http://gohugo.io&#34;&gt;hugo&lt;/a&gt; which seems
to be pretty popular. I&#39;ve been using static site generators for
years, and prefer the approach. It&#39;s also helpful that I worked with
Steve (hugo&#39;s original author) during its initial development, and
either by coincidence, or as a result our conversations and a couple
of very small early contributions a number of things I cared about were
included in its design:&lt;/p&gt;
&lt;ul class=&#34;simple&#34;&gt;
&lt;li&gt;support for multiple text markup features (including
reStructuredText,) (I cobbled together rst support. )&lt;/li&gt;
&lt;li&gt;customizeable page metadata formats. (I think I pushed for support
of alternate front-matter formats, specifically YAML, and might have
made a few prototype commits on this project)&lt;/li&gt;
&lt;li&gt;the ability to schedule posts in the future, (I think we talked
about this.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think I also winged a bunch in those days about performance. I&#39;ve
written about this here before, but one of the classic problems with
static site generators is that no one expects sites with one or two
thousand posts/content atoms, and so they&#39;re developed against
relatively small corpus&#39; and then have performance that doesn&#39;t really
scale.&lt;/p&gt;
&lt;p&gt;Hugo is fast, but mostly because &lt;em&gt;go&lt;/em&gt; is fast, which I think is, in
most cases, good enough, but not in my case, and particularly not with
the rst implementation as it stood. After all this preamble, we&#39;ve
gotten to the interesting part: a tool I&#39;m calling &lt;a class=&#34;reference external&#34; href=&#34;http://github.com/tychoish/rst&#34;&gt;shimgo&lt;/a&gt;.&lt;/p&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;The initial support for rst in hugo is straight forward. Every time
hugo encounters an rst file, it calls the shell &lt;tt class=&#34;docutils literal&#34;&gt;rst2html&lt;/tt&gt; utility
that is installed when you install docutils, passing it the content of
the file on standard input, and parsing from the output, the content
we need. It&#39;s not pretty, it&#39;&#39;s not smart, but it works.&lt;/p&gt;
&lt;p&gt;Slowly: to publish all of &lt;em&gt;tychoish&lt;/em&gt; it took about 3 minutes.&lt;/p&gt;
&lt;p&gt;I attempted an rst-to-markdown translation of my exiting content and
then ran that through the markdown parsers in hugo, just to get
comparative timings: 3ish seconds.&lt;/p&gt;
&lt;p&gt;reStructuredText is a bit slower to parse than markdown, on account of
it&#39;s comparative strictness and the fact that the toolchain is in
python and not go, but this difference seemed absurd.&lt;/p&gt;
&lt;p&gt;There&#39;s a &lt;a class=&#34;reference external&#34; href=&#34;https://github.com/demizer/go-rst&#34;&gt;go-rst&lt;/a&gt; project to
write a pure-go implementation of reStructuredText, but I&#39;ve kept my
eye on that project for a couple of years, and it&#39;s a lot of work that
is pretty far off. While I do want to do more to support this project,
I wanted to get a new blog up and running in a few weeks, not years.&lt;/p&gt;
&lt;p&gt;Based on the differences in timing, and some intuition from years of
writing build systems, I made a wager with myself: while the python
rst implementation is likely really slow, it&#39;s not &lt;em&gt;that&lt;/em&gt; slow, and
I was loosing a lot of time to process creation, teardown, and context
switching: processing a single file is pretty quick, but the overhead
gets to be too much at scale.&lt;/p&gt;
&lt;p&gt;I built a little prototype where I ran a very small HTTP service that
took rst as a &lt;tt class=&#34;docutils literal&#34;&gt;POST&lt;/tt&gt; request and returned processed HTML. Now there
was one process running, and instead of calling fork/exec a bunch, we
just had a little but of (local) network overhead.&lt;/p&gt;
&lt;p&gt;Faster: 20 second.&lt;/p&gt;
&lt;p&gt;I decided I could deal with it.&lt;/p&gt;
&lt;p&gt;What remains is making it production worthy or hugo. While it was
good enough for me, I very much don&#39;t want to get into the position of
needing to maintain a single-feature fork of a software project in
active development, and frankly the existing rst support has a
difficult to express external dependency. Adding a HTTP service would
be a hard sell.&lt;/p&gt;
&lt;p&gt;This brings us to shimgo: the idea is to package &lt;em&gt;everything&lt;/em&gt; needed
to implement the above solution in an external go package, and package
it behind a functional interface, so that hugo maintainers don&#39;t need
to know &lt;em&gt;anything&lt;/em&gt; about its working.&lt;/p&gt;
&lt;p&gt;Isn&#39;t abstraction wonderful?&lt;/p&gt;
&lt;p&gt;So here we are. I&#39;m still working on getting this patch mainlined, and
there is some polish for shimgo itself (mostly the README file and
some documentation), but it works, and if you&#39;re doing anything with
reStructuredText in go, then you ought to give shimgo a try.&lt;/p&gt;
&lt;table class=&#34;docutils footnote&#34; frame=&#34;void&#34; id=&#34;note&#34; rules=&#34;none&#34;&gt;
&lt;colgroup&gt;&lt;col class=&#34;label&#34; /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign=&#34;top&#34;&gt;
&lt;tr&gt;&lt;td class=&#34;label&#34;&gt;&lt;a class=&#34;fn-backref&#34; href=&#34;#id1&#34;&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;While I think it would be reasonable to start afresh, I
think the whole point of having archives is that you mostly
just leave them around.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class=&#34;docutils footnote&#34; frame=&#34;void&#34; id=&#34;rst&#34; rules=&#34;none&#34;&gt;
&lt;colgroup&gt;&lt;col class=&#34;label&#34; /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign=&#34;top&#34;&gt;
&lt;tr&gt;&lt;td class=&#34;label&#34;&gt;&lt;a class=&#34;fn-backref&#34; href=&#34;#id2&#34;&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;It&#39;s not the most popular markup language, but I&#39;ve used it
more than any other text markup, and I find the fact that other
langauges (e.g. markdown) vary a lot between implementations to be
distressing. Admitedly the fact that there aren&#39;t other
implementations of rst is also distressing, but one the balance is
somewhat less distressing.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
    </item>
    
    <item>
      <title>About</title>
      <link>http://tychoish.com/about/</link>
      <pubDate>Sun, 30 Oct 2016 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/about/</guid>
      <description>&lt;p&gt;tychoish is an eclectic collection of posts on programming,
documentation, software development, folk dance, science fiction
literature, cyborgs, political economy, emacs, Python, Go, shape note
singing, and hand knitting.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Going Forward</title>
      <link>http://tychoish.com/post/going-forward/</link>
      <pubDate>Sun, 24 Jul 2016 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/post/going-forward/</guid>
      <description>&lt;p&gt;I wrote &lt;a class=&#34;reference external&#34; href=&#34;http://tychoish.com/posts/a-new-era/&#34;&gt;a post about moving on from being a technical writer&lt;/a&gt;, and I&#39;ve definitely written some since then
about programming and various side projects, but I haven&#39;t really done
the kind of public reflection on this topic that I&#39;ve done
historically about, many other things.&lt;/p&gt;
&lt;p&gt;When I switched to a programming team, I knew some things about
computers, and I was a decent Python programmer. The goal, then was to
teach myself a second programming language (Go,) and learn how to make
&amp;quot;real&amp;quot; software with other people, or on teams with other people. Both
of those projects are going well: I think I&#39;ve become pretty solid as
a Go programmer, although, it&#39;s hard to say what &amp;quot;real&amp;quot; software is,
or if I&#39;m good at making it, but all indications are positive.&lt;/p&gt;
&lt;p&gt;This weekend, for various reasons, I&#39;ve been reviving a project that I
did some work on this fall and winter, that I&#39;ve abandoned for about 6
months. It&#39;s been both troubling (there are parts that are truly
terrible,) and kind of rewarding to see how much I&#39;ve grown as a
programmer just from looking at the code.&lt;/p&gt;
&lt;p&gt;Queue then, I guess, the self reflective interlude.&lt;/p&gt;
&lt;p&gt;My reason for wanting to learn--really learn--a second programming
language, was to make sure that all the things I knew about system
design, algorithms, and data structures was generalizable, and not
rooted in the semantics of a specific language or even implementation
of that language. I was also interested in learning more about the
process of learning new programming languages so that I had some
experience with the learning process, which may come in handy in the
future.&lt;/p&gt;
&lt;p&gt;Learning Go, I think helped me achieve or realize these goals. While I
haven&#39;t really set out to learn a &lt;em&gt;third&lt;/em&gt; language yet, it feels
tractable. I&#39;ve also noticed some changes and differences in some
other aspects of my interests.&lt;/p&gt;
&lt;p&gt;I used to be really interested in programming qua programming, and I
thought a lot about programming languages. While I still can evaluate
programming languages, and have my own share of opinions about &amp;quot;the
way things work,&amp;quot; I&#39;m less concerned with the specific syntax or
implementation. I think a lot about build tools, platform support,
deployment models, and distributing methods and stories, rather than
what it can do or how you have to write it. Or, &lt;em&gt;how you make it ship
it and run it&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;I&#39;ve also gotten less interested in UNIX-esque systems administration
and operations, which is historically a thing I&#39;ve been quite
interested in. These days, I find myself thinking more about the
following kinds of problems:&lt;/p&gt;
&lt;ul class=&#34;simple&#34;&gt;
&lt;li&gt;build systems, the tools building software from source files, (and
sometimes testing it!) and the ways to do this super efficiently and
sensibly. Build systems are &lt;em&gt;quite&lt;/em&gt; hard because in a lot of ways
they&#39;re the point through which your software (as software)
interacts with all of the platforms it runs on. Efficient build
systems have a huge impact on developer productivity, which is a big
interest.&lt;/li&gt;
&lt;li&gt;developer productivity, this is a big catch all category, but it&#39;s
almost always true that people are more expensive than computers, so
working on tools and features (like better build systems, or
automating various aspects of the development process,)&lt;/li&gt;
&lt;li&gt;continuous integration and deployment, again connected to developer
productivity, but taking the &amp;quot;automate building and testing,&amp;quot; story
to its logical conclusion. CD environments mean you deploy changes
much more often, but you also require and force yourself to trust
the automated systems and make sure that project leadership and
management is just as automated as the development experience.&lt;/li&gt;
&lt;li&gt;internal infrastructure, as in &amp;quot;internal services and tools that all
applications need,&amp;quot; like logging, queuing systems, abstractions for
persistence, deployment systems, testing, and exposed interfaces
(e.g. RPC systems, REST/HTTP, or command line option option
parsing). Having good tools for these generic aspects of the
application make writing &lt;em&gt;actual features&lt;/em&gt; for users easier. I&#39;m
also increasingly convinced that the way to improve applications and
systems is to improve these lower level components and their
interfaces.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Free Software and open source are still important, as is UNIX, but
these kinds of developer productivity and automation issues are a
level above that. I&#39;ve changed in the last 5 years, software has
changed in the last five years, the way we run software on systems has
changed in the last 5 years. I&#39;m super excited to see what kinds of
things I can do in this space, and where I end up in 5 years.&lt;/p&gt;
&lt;p&gt;I&#39;m also interested in thinking about ways to write about this. I&#39;d
written drafts of a number of posts that were about learning how to
program, about systems administration, and now that I&#39;m finding and
making more time for writing, one of the things I don&#39;t really know
about is what kind of writing on these topics I&#39;m interested in doing,
or how to do it in a way that &lt;em&gt;anyone&lt;/em&gt; would be interested in reading.&lt;/p&gt;
&lt;p&gt;We shall see. Regardless, I hope that I&#39;m back, now.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Works In Progress</title>
      <link>http://tychoish.com/post/works-in-progress/</link>
      <pubDate>Sun, 08 Nov 2015 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/post/works-in-progress/</guid>
      <description>&lt;p&gt;I&#39;ve posed about some of these projects before, and I used to
regularly post little overviews of the things that I&#39;m working on. But
I&#39;ve not done a lot of this recently. Time to do some back fill.&lt;/p&gt;
&lt;p&gt;I think it&#39;s probably good to take a step back from time to time and
inventory and evaluate the priorities of various projects. Not to
mention the fact that I usually say &amp;quot;I&#39;m not really doing much these
days,&amp;quot; when this isn&#39;t really true. Here goes:&lt;/p&gt;
&lt;div class=&#34;section&#34; id=&#34;mango&#34;&gt;
&lt;h1&gt;Mango&lt;/h1&gt;
&lt;p&gt;This is a project that is private, at the moment, because its mostly
useful as an experimental piece of testing infrastructure for
work. The idea is to use the same underlying infrastructure to start,
stop, and configure processes, but provide REST and command line
interfaces for all of these operations.&lt;/p&gt;
&lt;p&gt;We have a lot of distinct software that does this internally and it&#39;s
always fragile and limited. While grand discussions of code reuse are
sort of silly, in this case, it&#39;s a bit annoying that we&#39;ve reinvented
this wheel a dozen times... And have to make different changes to a
dozen tools as configurations change.&lt;/p&gt;
&lt;p&gt;This was also my first project written in Go, which means its been a
great learning experience &lt;em&gt;and&lt;/em&gt; the place where a number of other Go
packages that have become useful in their own right.&lt;/p&gt;
&lt;p&gt;Future work:&lt;/p&gt;
&lt;ul class=&#34;simple&#34;&gt;
&lt;li&gt;Write all the tests.&lt;/li&gt;
&lt;li&gt;Make the REST interface feature compatible with one of the legacy
tools it aims to supplant.&lt;/li&gt;
&lt;li&gt;Make a new REST interface that&#39;s more sensible and might be easier
to use in more circumstances.&lt;/li&gt;
&lt;li&gt;Figure out better ways to block for the appearance of synchronous
operations, despite the fact that internally the operations are
non-blocking.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;section&#34; id=&#34;gimlet&#34;&gt;
&lt;h1&gt;Gimlet&lt;/h1&gt;
&lt;p&gt;&lt;a class=&#34;reference external&#34; href=&#34;http://www.tychoish.com/posts/have-a-gimlet-a-go-json-http-api-toolkit/&#34;&gt;Gimlet Blog Post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;reference external&#34; href=&#34;https://github.com/tychoish/gimlet&#34;&gt;Gimlet Github&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is really just some convenience work to make it easy to build
REST interfaces in Go, without needing to suffer through tools that
are designed to support complete &amp;quot;full-stack&amp;quot; web applications. It&#39;s
built on the same Negroni/Gorilla Mux stack that I think everyone
uses, and it&#39;s very &lt;tt class=&#34;docutils literal&#34;&gt;net/http&lt;/tt&gt; compliant, but with an API that makes
it easy (even fun,) to provide high quality JSON+HTTP interfaces.&lt;/p&gt;
&lt;p&gt;It struck me, when working on part of Mango, that this chunk of the
code didn&#39;t have anything to do with the actual core application and
was all about getting a REST-like application to happen. So I split
that out, for everyone&#39;s pleasure/suffering.&lt;/p&gt;
&lt;p&gt;Future work:&lt;/p&gt;
&lt;ul class=&#34;simple&#34;&gt;
&lt;li&gt;Documentation.&lt;/li&gt;
&lt;li&gt;More tests.&lt;/li&gt;
&lt;li&gt;Exposed API stabilization and versioning.&lt;/li&gt;
&lt;li&gt;Develop story for authentication, sessions and SSL termination.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;section&#34; id=&#34;grip&#34;&gt;
&lt;h1&gt;Grip&lt;/h1&gt;
&lt;p&gt;&lt;a class=&#34;reference external&#34; href=&#34;http://tychoish.com/posts/get-a-grip/&#34;&gt;Grip Blog Post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a class=&#34;reference external&#34; href=&#34;https://github.com/tychoish/grip&#34;&gt;Grip Github&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Grip is a logging package for Go that attempts to resolve my constant
feelings of &amp;quot;I miss &lt;em&gt;x&lt;/em&gt; feature of the Python logging package.&amp;quot; It&#39;s
not feature comparable with Python logging (but that&#39;s ok,) and since
I was working on writing a logging package, I got to add some nifty
features.&lt;/p&gt;
&lt;p&gt;Future Work:&lt;/p&gt;
&lt;ul class=&#34;simple&#34;&gt;
&lt;li&gt;More documentation.&lt;/li&gt;
&lt;li&gt;Better examples, and potentially support for &amp;quot;print this message
&lt;tt class=&#34;docutils literal&#34;&gt;x&lt;/tt&gt;% of the time.&amp;quot;&lt;/li&gt;
&lt;li&gt;Support for logging to conventional &lt;tt class=&#34;docutils literal&#34;&gt;syslog&lt;/tt&gt; sources in addition to
systemd&#39;s logging.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;section&#34; id=&#34;archer-dropkick&#34;&gt;
&lt;h1&gt;Archer/Dropkick&lt;/h1&gt;
&lt;p&gt;I&#39;ve wanted to work on a tool to unify a number of personal operations
and scripts in a single system and tool. The problem that I&#39;m trying
to solve is that I have a number of different computers that I use
with some frequency, including laptops, desktops, and a number of
servers, and test systems, and I want to be able to describe their
configuration, and synchronize files and &lt;tt class=&#34;docutils literal&#34;&gt;git&lt;/tt&gt; data between
machines with ease.&lt;/p&gt;
&lt;p&gt;My first approach was getting a bunch of random system setup scripts
out of a makefile and into a configuration file that a Go program knew
how to read and process, and then to expand from there.&lt;/p&gt;
&lt;p&gt;I haven&#39;t gotten to the git repository management stuff, because I was
working on the &lt;em&gt;Gitgone&lt;/em&gt; project.&lt;/p&gt;
&lt;p&gt;Future Work:&lt;/p&gt;
&lt;ul class=&#34;simple&#34;&gt;
&lt;li&gt;add better support for creating and managing containers and images
using &lt;tt class=&#34;docutils literal&#34;&gt;&lt;span class=&#34;pre&#34;&gt;systemd-nspawn&lt;/span&gt;&lt;/tt&gt; and &lt;tt class=&#34;docutils literal&#34;&gt;docker&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;support for setting up git repositories&lt;/li&gt;
&lt;li&gt;support for syncing automatically (i.e. dropox-like functional it -&amp;gt; &lt;em&gt;dropkick&lt;/em&gt;).&lt;/li&gt;
&lt;li&gt;report status of repositories via a REST API&lt;/li&gt;
&lt;li&gt;triggering syncs on remote systems.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;section&#34; id=&#34;gitgone&#34;&gt;
&lt;h1&gt;Gitgone&lt;/h1&gt;
&lt;p&gt;&lt;a class=&#34;reference external&#34; href=&#34;https://github.com/tychoish/gitgone&#34;&gt;Gitgone Github&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The idea here is to provide a consistent and full featured way to
access and interact with git repositories from Go without needing to
wrap the &lt;tt class=&#34;docutils literal&#34;&gt;git&lt;/tt&gt; command yourself (or worse, learn the ins and outs of
the &lt;a class=&#34;reference external&#34; href=&#34;https://github.com/libgit2/git2go&#34;&gt;git2go&lt;/a&gt;). This is largely
modeled off of a similar project I did as part of &lt;a class=&#34;reference external&#34; href=&#34;https://github.com/tychoish/libgiza&#34;&gt;libgiza&lt;/a&gt; that does the same sort of
thing for Python repositories.&lt;/p&gt;
&lt;p&gt;The cool thing about this project is its build abstractly so that you
can use one interface and switch between a &lt;a class=&#34;reference external&#34; href=&#34;https://libgit2.github.com/&#34;&gt;libgit2&lt;/a&gt; implementation and one that wraps the
&lt;tt class=&#34;docutils literal&#34;&gt;git&lt;/tt&gt; command itself.&lt;/p&gt;
&lt;p&gt;Future Work:&lt;/p&gt;
&lt;ul class=&#34;simple&#34;&gt;
&lt;li&gt;complete implementation using libgit2&lt;/li&gt;
&lt;li&gt;write more extensive tests.&lt;/li&gt;
&lt;li&gt;add support for creating repository tags.&lt;/li&gt;
&lt;li&gt;provide access to the log.&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class=&#34;section&#34; id=&#34;novel-project&#34;&gt;
&lt;h1&gt;Novel Project&lt;/h1&gt;
&lt;p&gt;I&#39;ve been, sporadically, working on notes for writing a new
novel. It&#39;s not going anywhere fast, and I&#39;m not even to the point.
where I&#39;m outling plot.&lt;/p&gt;
&lt;p&gt;I&#39;m trying to tell a story about urban development and how smaller
local communities/groups participate in larger communities/groups. How
does urban development in place a, impact nation building more
globally, and what does this all look like to people as they get to
work in the morning, and have to build neighborhood institutions like
gyms and restaurants and grocery stores.&lt;/p&gt;
&lt;p&gt;But there&#39;s a lot of work to do, and while thinking about the project
is fun, there&#39;s a &lt;em&gt;lot&lt;/em&gt; of work, and I feel like I&#39;m not ready to
commit to a writing project of this scope &lt;em&gt;and&lt;/em&gt;, I&#39;m not sure how
publishable this project will be (and furthermore, even if its&#39;
publishable, will I be willing to do all of that work.)&lt;/p&gt;
&lt;p&gt;Software projects are much harder to justify and prioritize than
writing projects.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Get a Grip</title>
      <link>http://tychoish.com/post/get-a-grip/</link>
      <pubDate>Sun, 01 Nov 2015 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/post/get-a-grip/</guid>
      <description>&lt;p&gt;I made another Go(lang) thing. &lt;a class=&#34;reference external&#34; href=&#34;https://github.com/tychoish/grip&#34;&gt;Grip&lt;/a&gt; is a set of logging tools modeled
on Go&#39;s standard logging system, with some additional (related)
features, including:&lt;/p&gt;
&lt;ul class=&#34;simple&#34;&gt;
&lt;li&gt;level-based logging, with the ability to set a minimum threshold to
exclude log messages based on priority (i.e. debugging.)&lt;/li&gt;
&lt;li&gt;Error capture/logging, to log Go &lt;tt class=&#34;docutils literal&#34;&gt;error&lt;/tt&gt; objects.&lt;/li&gt;
&lt;li&gt;Error aggregation, in continue-on-error situations, where you want
to perform a bunch of operations and then return any errors if &lt;em&gt;any&lt;/em&gt;
of them returned an error but don&#39;t want to return an error after
the first operation fails.&lt;/li&gt;
&lt;li&gt;Logging to the &lt;tt class=&#34;docutils literal&#34;&gt;systemd&lt;/tt&gt; journal with fallback to standard library
logging to standard output.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are helper functions for logging using different kinds of
default string formatting, as well as functions that take error
objects, and a &amp;quot;lazy&amp;quot; logging method that take a simple interface for
building log messages at log-time rather than at operation time.&lt;/p&gt;
&lt;p&gt;None of these features are terribly exciting, and the &lt;tt class=&#34;docutils literal&#34;&gt;systemd&lt;/tt&gt;
library wraps the &lt;tt class=&#34;docutils literal&#34;&gt;systemd&lt;/tt&gt; library from CoreOS. I&#39;m a big fan of
log levels and priority filtering, so it&#39;s nice to have a tool for
that.&lt;/p&gt;
&lt;p&gt;In the future, I&#39;d like to add more generic syslog support if that&#39;s
useful, and potentially tools for better categorical logging. There&#39;s
also a good deal of repeated code and it might be nice to us this as
an excuse to write a code-generator using &lt;tt class=&#34;docutils literal&#34;&gt;go tool&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Pull requests and feedback are, of course, welcome.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Said on the Train</title>
      <link>http://tychoish.com/post/said-on-the-train/</link>
      <pubDate>Fri, 04 Sep 2015 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/post/said-on-the-train/</guid>
      <description>&lt;p&gt;I finished, on the train this week, reading &lt;a class=&#34;reference external&#34; href=&#34;http://www.amazon.com/Freud-Non-European-Edward-W-Said/dp/1844675114&#34;&gt;Freud and the Non-European&lt;/a&gt;
by Edward Said (on the recommendation of &lt;a class=&#34;reference external&#34; href=&#34;http://Twitter.com/zmagg/&#34;&gt;zmagg&lt;/a&gt; and it was, one of the better reading
experiences I&#39;ve had in a while.&lt;/p&gt;
&lt;p&gt;Said is brilliant, and clear and says really complex important hard
things in a really clear and approachable style. He&#39;s also
frustratingly &lt;em&gt;correct&lt;/em&gt;, which isn&#39;t really a problem, but as an
engaged and independent reader, I occasionally realize that the
internal monologue of my response is an unintelligent &amp;quot;yep yep&amp;quot;
chorus, and I feel like I&#39;ve fallen down on the job of being a good
reader.&lt;/p&gt;
&lt;p&gt;I might have a bit of a complex.&lt;/p&gt;
&lt;p&gt;The thing is, that he actually is &lt;em&gt;very&lt;/em&gt; right, and does an amazing
job of meeting Freud in his historical context, respecting in that
context for the audacity of his mission and the power of his insights
to encourage us to think about culture, its impact on human
motivation, and how personal and cultural histories combine to produce
identity, and inspire behavior. Or, more simply, that self-hood and
experience are a product of history and context.&lt;/p&gt;
&lt;p&gt;Without, of course, in anyway excusing the flaws in Freud&#39;s methods,
biases, basis in fact (or lack there of), or utility (or lack there
of) in the care of the mentally ill.&lt;/p&gt;
&lt;p&gt;Moreso, Said uses Frued, and his ideas about Jewish identity, and
himself as an example of late a certain phenotype of 19th century
Jewishness, to help contextualize (roughly) contemporary thinking
about jewish identity and Israeli culture and statehood.&lt;/p&gt;
&lt;p&gt;It&#39;s roughly brilliant.&lt;/p&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;I&#39;ve long struggled with any kind of theory that engages seriously
with Freud or his intellectual successors: there&#39;s so much &lt;a class=&#34;reference external&#34; href=&#34;https://twitter.com/tychoish/status/639590377226420224&#34;&gt;crap&lt;/a&gt; around
Freud, and it sort of feels like good energy after bad to try and
justify or resuscitate the tradition. And hurts when Freudian are used
to support what are otherwise really interesting intellectual
projects.&lt;/p&gt;
&lt;p&gt;If nothing else Said gives a good example of a successful intellectual
interaction with Freud can occur, and what kinds of parameters and
context promote that kind of successful and productive interaction.&lt;/p&gt;
&lt;p&gt;Maybe someday, I&#39;ll learn how to be a quarter the reader that Said
was. If I&#39;m lucky.&lt;/p&gt;
&lt;p&gt;In the mean time, I&#39;m just going to keep reading things on the train.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Have a Gimlet: A Go JSON/HTTP API Toolkit</title>
      <link>http://tychoish.com/post/have-a-gimlet-a-go-json-http-api-toolkit/</link>
      <pubDate>Sun, 26 Jul 2015 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/post/have-a-gimlet-a-go-json-http-api-toolkit/</guid>
      <description>&lt;p&gt;Look folks, I made a thing!&lt;/p&gt;
&lt;p&gt;It&#39;s called &lt;a class=&#34;reference external&#34; href=&#34;https://github.com/tychoish/gimlet&#34;&gt;gimlet&lt;/a&gt;, and it&#39;s a
Go(lang) tool for making JSON/HTTP APIs (i.e. REST with JSON). Give it
a whirl!&lt;/p&gt;
&lt;p&gt;It&#39;s actually even less a tool, and more of a toolkit or just &amp;quot;a place
to put all of the annoying infrastructure that you&#39;ll inevitably need
when you want to build an JSON/HTTP interface, but that have nothing
to do what &lt;em&gt;whatever&lt;/em&gt; your API/application does: routing, serializing
and serializing JSON.&lt;/p&gt;
&lt;p&gt;Nothing hard, nothing terribly interesting, and certainly not anything
you couldn&#39;t do another way, but, it&#39;s almost certainly true that this
layer of application infrastructure is totally orthogonal to whatever
you application is actually doing, so you should focus on that, and
probaly use something like Gimliet.&lt;/p&gt;
&lt;div class=&#34;section&#34; id=&#34;background&#34;&gt;
&lt;h1&gt;Background&lt;/h1&gt;
&lt;p&gt;I&#39;m using the term HTTP/JSON APIs for services where you send and
recive JSON data over HTTP. Sometimes people call these REST APIs, and
that&#39;s not inaccurate, but I think REST is a bit more complicated, and
not exactly the core paradigm that I&#39;m pursuing with Gimlet.&lt;/p&gt;
&lt;p&gt;Sending and reviving JSON over HTTP makes a lot of sense: there are
great tools for parsing JSON and HTTP is a decent high level protocol
for interprocess communication between simple data applications. Look
up &amp;quot;microservices&amp;quot; at your leisure.&lt;/p&gt;
&lt;p&gt;Go is a great language for this it has a lot of tooling that
anticipates these kinds of applications, and the deployment model is
really friendly to operations teams and systems. Also the static&lt;/p&gt;
&lt;p&gt;typing and reasonable separation of private and public interfaces is
particularly lovely.&lt;/p&gt;
&lt;p&gt;So it should be no surprise that there are a lot tools for building
stweb applications, frameworks even. They&#39;re great, things like &lt;a class=&#34;reference external&#34; href=&#34;http://www.gorillatoolkit.org/&#34;&gt;gorilla&lt;/a&gt; and &lt;a class=&#34;reference external&#34; href=&#34;https://github.com/codegangsta/negroni&#34;&gt;negroni&lt;/a&gt; are great and provide a
very useful set of tools for building Go web apps. Indeed even Gimlet
uses components of each of these tools.&lt;/p&gt;
&lt;p&gt;The issue, and reason for Gimlet, is that all of these tools assume
that you&#39;re building a web application, with web pages, static
resources, form handling, session state handling, and other things
that are totally irrelevant to writing JSON/HTTP interfaces.&lt;/p&gt;
&lt;p&gt;So  then, Gimlet is a tool to build these kinds of APIs: simple, uses
Negroni and Gorilla&#39;s &lt;tt class=&#34;docutils literal&#34;&gt;mux&lt;/tt&gt;, and does pretty much everything you
need except actually write your code.&lt;/p&gt;
&lt;/div&gt;
&lt;div class=&#34;section&#34; id=&#34;example&#34;&gt;
&lt;h1&gt;Example&lt;/h1&gt;
&lt;p&gt;Set up the app with some basic configuration:&lt;/p&gt;
&lt;pre class=&#34;literal-block&#34;&gt;
import &amp;quot;github.com/tychoish/gimlet&amp;quot;

app := gimlet.NewApp()
app.SetPort(9001)
app.SetDefaultVersion(1)
&lt;/pre&gt;
&lt;p&gt;This sets which port the HTTP server is going to listen for requests
and configures the default version of the API. You do want all of your
endpoints prefixed with &amp;quot;&lt;tt class=&#34;docutils literal&#34;&gt;/v&amp;lt;number&amp;gt;&lt;/tt&gt;&amp;quot;  right? The default version
of the API is also avalible without the prefix, or if the version of
the route is &lt;tt class=&#34;docutils literal&#34;&gt;0&lt;/tt&gt;. If you don&#39;t set it to &lt;tt class=&#34;docutils literal&#34;&gt;0&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Then register some routes:&lt;/p&gt;
&lt;pre class=&#34;literal-block&#34;&gt;
app.AddRoute(&amp;quot;/&amp;lt;path&amp;gt;&amp;quot;).Version(&amp;lt;int&amp;gt;).Get().Handler(http.HandlerFunc)
app.AddRoute(&amp;quot;/&amp;lt;path&amp;gt;&amp;quot;).Version(&amp;lt;int&amp;gt;).Post().Handler(http.HandlerFunc)
&lt;/pre&gt;
&lt;p&gt;&lt;tt class=&#34;docutils literal&#34;&gt;app.AddRoute&lt;/tt&gt; returns an API route object with a set of chainable
methods for defining the routes. If you add multiple HTTP methods
(&lt;tt class=&#34;docutils literal&#34;&gt;GET&lt;/tt&gt; &lt;tt class=&#34;docutils literal&#34;&gt;POST&lt;/tt&gt; and the like,) then Gimlet automatically defines
multiple routes with the same handler for each method.&lt;/p&gt;
&lt;p&gt;For handlers, I typically just write functions that take arguments
from the top level context (database connections, application
configuration, etc) and return``http.HandlerFunc`` objects. For
example:&lt;/p&gt;
&lt;pre class=&#34;literal-block&#34;&gt;
func helloWorld(config *Configuration) http.HandlerFunc {
     return func(w http.ResponseWriter, r *http.Request) {
          input := make(map[string]interface{})
          response := make(map[string]interface{})

          err := gimlet.GetJSON(input)

          // do stuff here

          gimlet.WriteJSON(w, response)
     }
}
&lt;/pre&gt;
&lt;p&gt;Gimlet has the following functions that parse JSON out of the body of
a request, or add JSON output to the body of a response, they are:&lt;/p&gt;
&lt;ul class=&#34;simple&#34;&gt;
&lt;li&gt;&lt;tt class=&#34;docutils literal&#34;&gt;WriteJSONResponse(w http.ResponseWrite, code int, data &lt;span class=&#34;pre&#34;&gt;interface{})&lt;/span&gt;&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class=&#34;docutils literal&#34;&gt;GetJSON(r *http.Request, data interface)&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Which read or write data into the &lt;tt class=&#34;docutils literal&#34;&gt;interface{}&lt;/tt&gt; object (typically a
&lt;tt class=&#34;docutils literal&#34;&gt;struct&lt;/tt&gt;.) The following three provide consistent response writers
for common exit codes:&lt;/p&gt;
&lt;ul class=&#34;simple&#34;&gt;
&lt;li&gt;&lt;tt class=&#34;docutils literal&#34;&gt;WriteJSON(w http.ResponseWriter, data &lt;span class=&#34;pre&#34;&gt;interface{})&lt;/span&gt; // 200&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class=&#34;docutils literal&#34;&gt;WriteErrorJSON(w http.ResponseWriter, data &lt;span class=&#34;pre&#34;&gt;interface{})&lt;/span&gt; // 400&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt class=&#34;docutils literal&#34;&gt;WriteInternalErrorJSON(w http.ResponseWriter, data &lt;span class=&#34;pre&#34;&gt;interface{})&lt;/span&gt; // 500&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, when you&#39;ve written your app, kick it all off, with the
following:&lt;/p&gt;
&lt;pre class=&#34;literal-block&#34;&gt;
err := app.Run()
if err != nil {
   fmt.Println(err)
   os.Exit(1)
}
&lt;/pre&gt;
&lt;p&gt;And that&#39;s it. Enjoy, tell me in the comments or on the &lt;a class=&#34;reference external&#34; href=&#34;https://github.com/tychoish/gimlet/issues&#34;&gt;issues feed&lt;/a&gt; if you find something
broken or confusing. Contribution welcome, of course.&lt;/p&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>A New Era</title>
      <link>http://tychoish.com/post/a-new-era/</link>
      <pubDate>Thu, 26 Feb 2015 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/post/a-new-era/</guid>
      <description>&lt;p&gt;I&#39;m writing the draft of this from an airplane bound for Ireland for a
week of singing. I travel often: taking weekend jaunts to go to folk
festivals, singing conventions, Morris dancing tours, &lt;em&gt;and&lt;/em&gt; so forth,
I don&#39;t really vacation often. I find travel and managing the
logistics of being in unfamiliar places stressful,
and my idea of a good time has a lot to do with sipping a cup of
coffee &lt;a class=&#34;footnote-reference&#34; href=&#34;#coffee&#34; id=&#34;id1&#34;&gt;[1]&lt;/a&gt; writing something, and reading a book.&lt;/p&gt;
&lt;p&gt;Even though I love spending time at home, it&#39;s still important to
(sometimes) leave, try new things, and &lt;em&gt;exist&lt;/em&gt; somewhere differently
for a little while to reset and reflect a bit. With luck, this
vacation thing will become something I feel comfortable doing, at
least occasionally.&lt;/p&gt;
&lt;p&gt;While it certainly wasn&#39;t part of the initial plan, it turns out that
this trip is pretty well timed both as denotes a relatively
significant change in my life, and I think is a fitting celebration of
a period of large changes in my life.&lt;/p&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;I am no longer a technical writer.&lt;/p&gt;
&lt;p&gt;When I return to work, I&#39;m joining the core engineering team to work
on build infrastructure and systems projects. I&#39;ll be working on
automating our release process, maintaining continuous integration
systems, along with an eclectic set of other projects (some of which
may involve some of technical writing. There are somethings
that you can never escape.)&lt;/p&gt;
&lt;p&gt;The truth though, is that this change has been a long time coming: it
feels pretty natural. I&#39;ve been working on the documentation build
system for a while, and that&#39;s increasingly been the most &lt;em&gt;fun&lt;/em&gt; part
of my job, so it&#39;ll be good to spend more time doing that kind of work
and learn from folks who know more about this kind of thing. Also,
build infrastructure and packaging is incredibly important to how
people use software and how engineers work, which have been consistent
interests of mine for years.&lt;/p&gt;
&lt;p&gt;Also, through the last release process, I&#39;ve also found that I&#39;m
burning out on writing documentation. I can do it, and I&#39;m not bad at
it. After writing, editing and shepherding, more than a million
words of documentation (over several thousand pages,) I sometimes feel
like I&#39;ve seen it all. I&#39;m interested in seeing the new ideas and
perspectives that will prosper in my absence. I&#39;m also eager to see
how the foundation I&#39;ve built stands up without me around. &lt;em&gt;It was
time&lt;/em&gt;.&lt;/p&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;The decision to change jobs happened rather suddenly. While I&#39;ve built
a narrative (see above), in reality, something clicked and I realized
it was time. Ten days later there was a plan. I said to myself, &amp;quot;&lt;em&gt;Shit
I thought I was done with major life changes for a while.&lt;/em&gt;&amp;quot;&lt;/p&gt;
&lt;p&gt;In the last year, I&#39;ve bought an apartment and moved to Brooklyn and
reorganized my local family grouping: &lt;a class=&#34;footnote-reference&#34; href=&#34;#euphemism&#34; id=&#34;id2&#34;&gt;[2]&lt;/a&gt; The good news is
that I find my self in a good state, and &#39;there&#39;s nothing left to
change. &lt;a class=&#34;footnote-reference&#34; href=&#34;#parts&#34; id=&#34;id3&#34;&gt;[3]&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It&#39;s been a rocky year, nothing is going to change that. Even if in
retrospect I find myself satisfied with my actions and decisions, and
even if I come out the other end better for my struggle, this is a
year I wouldn&#39;t care to repeat.&lt;/p&gt;
&lt;p&gt;And even so, I&#39;m excited about the future, about continuing to do
interesting work professionally, about enjoying my city and local
geography, to surround myself with top notch humans, and to make cool
things.&lt;/p&gt;
&lt;p&gt;These are early days, and there&#39;s work to do.&lt;/p&gt;
&lt;hr class=&#34;docutils&#34; /&gt;
&lt;p&gt;In the mean time, I&#39;ll be over here, enjoying something different for
a little while.&lt;/p&gt;
&lt;table class=&#34;docutils footnote&#34; frame=&#34;void&#34; id=&#34;coffee&#34; rules=&#34;none&#34;&gt;
&lt;colgroup&gt;&lt;col class=&#34;label&#34; /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign=&#34;top&#34;&gt;
&lt;tr&gt;&lt;td class=&#34;label&#34;&gt;&lt;a class=&#34;fn-backref&#34; href=&#34;#id1&#34;&gt;[1]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Astute readers of the blog will note that I am
historically a tea drinker. I changed to coffee in late June 2014:
I discovered that I didn&#39;t mind the taste as much as I thought, and
I like a slightly more potent caffeine delivery system.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class=&#34;docutils footnote&#34; frame=&#34;void&#34; id=&#34;euphemism&#34; rules=&#34;none&#34;&gt;
&lt;colgroup&gt;&lt;col class=&#34;label&#34; /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign=&#34;top&#34;&gt;
&lt;tr&gt;&lt;td class=&#34;label&#34;&gt;&lt;a class=&#34;fn-backref&#34; href=&#34;#id2&#34;&gt;[2]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;Break ups suck, each in its own special fucked up
way.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;table class=&#34;docutils footnote&#34; frame=&#34;void&#34; id=&#34;parts&#34; rules=&#34;none&#34;&gt;
&lt;colgroup&gt;&lt;col class=&#34;label&#34; /&gt;&lt;col /&gt;&lt;/colgroup&gt;
&lt;tbody valign=&#34;top&#34;&gt;
&lt;tr&gt;&lt;td class=&#34;label&#34;&gt;&lt;a class=&#34;fn-backref&#34; href=&#34;#id3&#34;&gt;[3]&lt;/a&gt;&lt;/td&gt;&lt;td&gt;I&#39;ve started singing more tenor, I guess, so maybe there&#39;s
more to change after all.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description>
    </item>
    
    <item>
      <title>Style Chameleon</title>
      <link>http://tychoish.com/post/style-chameleon/</link>
      <pubDate>Wed, 25 Feb 2015 00:00:00 +0000</pubDate>
      
      <guid>http://tychoish.com/post/style-chameleon/</guid>
      <description>&lt;p&gt;When I started my current job there were three major problems with the
documentation:&lt;/p&gt;
&lt;ul class=&#34;simple&#34;&gt;
&lt;li&gt;There was too much duplicated content, so it was difficult to know
where to point people.&lt;/li&gt;
&lt;li&gt;Given that there were always multiple versions of the product in
use, it was hard to figure out which paragraph refereed to which
version, particularly as the product changed.&lt;/li&gt;
&lt;li&gt;Each page felt like it was written by someone else (it was!) and the
reading experience could be quite jarring.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first two were huge tasks, but the  solutions were pretty straight
forward: build system for documentation that was structured such that
it could theoretically hold all the information (replace lots of
information repositories with a single information repository) and
then use maintenance branches in a version control system to snapshot
and fork off old branches as they&#39;re released.&lt;/p&gt;
&lt;p&gt;Done.&lt;/p&gt;
&lt;p&gt;The last problem is harder. Much harder.&lt;/p&gt;
&lt;p&gt;I did a pretty good job, at first, of just writing everything myself,
which meant that the first drafts all sounded like they were written
by one person: because they were. This doesn&#39;t scale. The next step
was to edit the hell out of all contributions that weren&#39;t by me.&lt;/p&gt;
&lt;p&gt;This also doesn&#39;t scale.&lt;/p&gt;
&lt;p&gt;There are some canonical solutions: write a long style guide and try
to get people to comply with it; use templates and standard formats
for documents so that everything uses common structure and forms. It&#39;s
still hard to enforce, but it&#39;s something.&lt;/p&gt;
&lt;p&gt;I put a lot of time into content reuse systems that had
additional structure. It helps, and reduces some editorial overhead,
but has the same weak points as the conventional solution.&lt;/p&gt;
&lt;p&gt;At some point, you need actual humans to edit and make sure things are
clear and consistent across the entire corpus. If you don&#39;t have the
resources for good editors, then either writers have to spend a
significant amount of time editing, which is a huge time suck (and
slows progress,) or you start to get drift.&lt;/p&gt;
&lt;p&gt;I&#39;m not sure that we have a good answer yet. In the mean time&lt;/p&gt;
&lt;div class=&#34;section&#34; id=&#34;appendices&#34;&gt;
&lt;h1&gt;Appendices&lt;/h1&gt;
&lt;div class=&#34;section&#34; id=&#34;style-in-group-processes&#34;&gt;
&lt;h2&gt;Style in Group Processes&lt;/h2&gt;
&lt;ol class=&#34;arabic simple&#34;&gt;
&lt;li&gt;As you innovate and improve it&#39;s &lt;em&gt;really&lt;/em&gt; hard to resist the
impulse to go back to older pieces to revise them. You should make
passes through all your content on some sort of schedule, but you
have to give yourself permission and allowance to go back and fix
style later.&lt;/li&gt;
&lt;li&gt;Common style is less about &amp;quot;being right,&amp;quot; and more about figuring
out the kind of communication that&#39;s appropriate for the target
audience(s) and using effective structure to support them. In
short: compromise.&lt;/li&gt;
&lt;li&gt;Style is about the entire reading expenses, not just the syntax, or
the typesetting: it is both of these things as well as others. For
some kinds of texts, the trick is to often to write as few words as
possible, and to make it so that people can scan through documents
as quickly as possible while only reading the sections that are
relevant to them.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div class=&#34;section&#34; id=&#34;personal-observations&#34;&gt;
&lt;h2&gt;Personal Observations&lt;/h2&gt;
&lt;p&gt;It&#39;s actually interesting to write blogs again, as I&#39;m
(re?)discovering a style of writing that I have been very comfortable
with in the past but haven&#39;t really exercised recently. It&#39;s also
interesting to see how my own writing and writing process has changed
as a result of writing so much technical material.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;</description>
    </item>
    
  </channel>
</rss>