Building a Rack::Attack Dashboard

At BackerKit, we occasionally see high volumes of traffic from malicious clients. (Kickstarter has faced a similar problem.) These DDoS attacks result in degraded performance and frustrate our customers. Not cool! We implemented Kickstarter’s Rack::Attack and configured constraints on the number of requests allowed in a time period based on IP address on our troublesome endpoints. Yay, problem solved! Like most tools, Rack::Attack requires tuning; our initial stab at configuration led to customers being blocked. Read On →

Configuring a Static Website on AWS with Terraform

I recently migrated this blog (built using Hugo) from a manually configured setup with S3 and CloudFront to the same infrastructure managed via Terraform. While it’s relatively trivial to host a static site on AWS these days, migrating this simple application to be managed with Terraform was a great way to get started with HashiCorp’s infrastructure automation tools. This post will lay out the steps for deploying a static site on AWS via Terraform and some of the gotchas of migrating an existing site. Read On →

Refactoring Towards Repositories

I’ve been working on projects recently that make heavy use of the repository pattern. I frequently wonder if the added layer of abstraction is worth the indirection and I’ve found there is a large continuum between writing large queries in controllers and abstracting all the way to repositories. What is a repository anyway? Martin Fowler defines a repository as [a layer of abstraction that] mediates between the domain and the data mapping layers Data mappers are an additional layer of abstraction one can use to put room between the data store and the domain models. Read On →

Tuning AWS SQS Job Queues

On a project recently, we were debugging a slow user experience during file upload and after investigating, found that the culprit was mainly our queue configuration. We were using Amazon’s Simple Queue Service (SQS) for queueing and this post goes over our debugging process and the lessons learned for tuning SQS along with some more general take aways about background jobs and queue design. Our use case The user flow in question here is a contract signing flow where the user uploads a file to be prepared for signing. Read On →

Find and Replace in Vim Without Plugins

Find and replace across files is one of those features I frequently see Vim users reverting back to something like Sublime or another more GUI driven editor. This apparent weakness in Vim bothered me so I went in search of how to find and replace across multiple files or directories in a project without leaving Vim. It turns out there are built in building blocks we can use to build up this command. Read On →

Adding a Boolean Column to an Existing Table with Alembic and SQLAlchemy

Ever find yourself needing to add a new boolean column to an existing table? I do! Recently I’ve been using SQLAlchemy and Alembic to manage migrations and I frequently find myself looking up how to achieve this task. Below is a recipe for adding a boolean column to an existing table. We want to avoid the three state boolean problem so we’ll be making this column null: false. Since we’re adding this column to an existing table we have existing rows that will have empty values for this new column. Read On →

HATEOAS with Ember Data

This post was originally published on thoughtbot’s blog. Ember Data introduced strong conventions around how to structure API responses. While these conventions allow us to move quickly, there are additional steps we can take to minimize the coupling between the front end and back end. Using concepts from HATEOAS (Hypermedia as the Engine of Application State) we can make our Ember applications more flexible and resilient to changes on the server. Read On →

Datetime Parsing with Go

While working on a side project recently ( I wrote a CSV parsing script in Go and I realized I did not understand how to parse a non-standard string into a time.Time type. Here’s what I learned. My date data looked like the following: 12/18/2014 07:00:00 but the Go reference time is in the following format: Mon Jan 2 15:04:05 -0700 MST 2006. So, how do we go from my format to the required format? Read On →

Speed Up JavaScript Capybara Specs by Blacklisting URLs

This post was originally published on thoughtbot’s blog. On a project recently, our full test suite began to crawl (taking ~9 minutes instead of less than 1) on our local machines running OS X but ran normally on CI. This slowdown took our productivity to near zero. We discovered our Capybara specs with js: true set were the culprit but we couldn’t figure out why. read more…

Postgres Window Functions

This post was originally published on thoughtbot’s blog. We recently ran into a case where a join was getting out of hand and we were struggling with how to rein in the size of it. Then we found window functions. Window functions (Oracle calls them analytic functions) are a part of the SQL standard and this post will explore how to use them in Postgres. Let’s see how they work and what kind of problems they can help us solve. Read On →