How things (don't) get made.

Post by Saul Shanabrook

Here is a little backstory/example.

I started work today on adding a feature to the website I develop,
CANADA. I wanted to make the deploy workflow more seamless. When I was testing
this feature, I ran into a bug on another one of my projects,
django-dumper.

2014-04-22T16:05:02.829678+00:00 app[web.1]: dumper.middleware DEBUG found path "/" with method "HEAD" as key "dumper.cached_path.6666cd76f96956469e7be39d750cc7d9.HEAD"
2014-04-22T16:05:02.829684+00:00 app[web.1]: dumper.middleware DEBUG cached path "/" with method "HEAD" as key "dumper.cached_path.6666cd76f96956469e7be39d750cc7d9.HEAD"
2014-04-22T16:05:08.944079+00:00 heroku[router]: at=info method=HEAD path=/ host=www.canadanewyork.com request_id=cf642b49-2f6e-45d3-b9e0-43cc5da0289f fwd="54.248.250.232, 103.22.200.215" dyno=web.1 connect=1ms service=54ms status=200 bytes=254
2014-04-22T16:05:08.933222+00:00 app[web.1]: dumper.middleware DEBUG found path "/" with method "HEAD" as key "dumper.cached_path.6666cd76f96956469e7be39d750cc7d9.HEAD"
2014-04-22T16:05:08.933859+00:00 app[web.1]: dumper.middleware DEBUG cached path "/" with method "HEAD" as key "dumper.cached_path.6666cd76f96956469e7be39d750cc7d9.HEAD"
2014-04-22T16:05:15.390393+00:00 heroku[router]: at=info method=GET path=/ host=www.canadanewyork.com request_id=e94015fc-8528-4197-925e-376d959089a6 fwd="54.196.52.65, 173.245.54.116" dyno=web.1 connect=22ms service=58ms status=200 bytes=1470
2014-04-22T16:05:15.378238+00:00 app[web.1]: dumper.middleware DEBUG found path "/" with method "GET" as key "dumper.cached_path.6666cd76f96956469e7be39d750cc7d9.GET"
2014-04-22T16:05:15.379213+00:00 app[web.1]: dumper.middleware DEBUG cached path "/" with method "GET" as key "dumper.cached_path.6666cd76f96956469e7be39d750cc7d9.GET"

When it returned a cached version of a page, it was re-saving that
cached version with the same key, which is useless and time consuming. I
quickly typed up an
issue
for
that project and set about trying to solve it. I decided I should write
a failing test first, to not only verify the bug but also verify my
solution to it. This is now my goto strategy when I am writing code
changes that can be tested.

I realized that the only way to test if django-dumper was in fact
saving a cache key when it returned a cached version would be to check
the logs to see if it had printed anything about returning the key.

    def process_response(self, request, response):
        if self.should_cache(request, response):
            key = dumper.utils.cache_key_from_request(request)
            MiddlewareLogger.save(key, request)
            dumper.utils.cache.set(key, response)
        else:
            MiddlewareLogger.not_save(request)
        return response

At first I considered adding a signal to the middleware to send whenever
a cache key was sent, but figured I should just stick to the simplest
for now, and if I wanted to refactor it later I could.

So then I went about looking for a way to test for logging. I found
Python issue #18937, which adds
this functionality, which has been merged into Python core, but hasn’t
been releases yet.

I looked at the diff
and realized I could just package this up and release it for anyone who
wanted python logging asserts backported.

But before I started this new python project, I wanted to finish my
cookiecutter python package project,
which is basically a template I modifying to set up the tools and
structure for a new python package. I had already created
issues for all the big items that I wanted to change on my cookiecutter, so at
this point I am crossing off those one by one.

So that I can create a backported logging python testing verification.
So that I can write tests for cached a page even if it already cached in
djagno-dumper. So that I can fix that error. So that I can get back to
writing my deployment script for CANADA.

I can see that my work this morning has been very fractured. I am not
sure exactly what to take away from this. Maybe I am not focused enough,
I should try to solve one problem before getting distracted. Maybe I
don’t have enough pressure to solve a problem fast, so I take my time
and get diverted by other, only partially related, projects. On the
other hand, it seems good that I have the abilities and the confidence
to go out and try to solve many of these issues “the right way”.

I think part of my own confusion comes from the intersection between
“rightness”, distraction (procrastination), and GTD. On some level, I have internalized the internet telling me that I shouldn’t sacrifice
good tests, documentation, blah blah blah for a rushed project. I love
making tooling to improve my own workflow. On the other hand, I know
that a strong consistent drive is vital to achieving anything. I am not
working on any one huge project right now, but skipping between a
variety of things. I am not entrenched in one beautiful idea. I also
know that in terms of workplace productivity, the only thing that really
matters is how satisfied the client/boss is of the work. And maybe I
have some higher level artistic ideals that I try to follow when writing
code, but they take the back seat.

Anyway, I find this whole open source contribution thing absolutely
enthralling. I honestly do feel part of some sort of community, everyone
working separately, but coming together to share knowledge and raise us
up.