Jan 16

The Time Travel Telephone

Your phone is a time travel device. It’s kinda mediocre as far as time travel goes; it only goes one direction (to the future) and it only lets you skip ahead a few minutes at a time. Maybe an hour if you really push it. Oh, and you still age while your using it. So, I guess it’s actually a crappy time travel device. But it is one we all use every day to skip forward in time.

I first realized what I was doing while living in Queens a few years ago. I had a commute from Astoria into Midtown and I took the train like any non-insane New Yorker would. If I was even a little off with my timing (or the weather was bad), I would end up commuting during the morning or evening rush hours. What is rush hour like on a subway train you ask? Well, in the summer it’s like taking the mosh pit from a metal concert and packing all the hot sweaty people into a subway car so that they are all touching me somehow. In the winter it’s the same thing, but with puffy jackets.

My point is that is sucks. And the way to escape the suckiness is to pull out your phone and lose yourself in whatever game/app/book/hacker news comment thread can capture your interest for 15 minutes until you get to your stop. When your attention is fully captured, it is magical. It really can feel like time travel.

I probably always inherently knew about this phenomenon, but that commute really drove it home for me. I quickly found myself applying phone based time travel in lots of other aspects of big city life. Long line at the grocery store? Pull out the phone and skip the wait. Arrive at the DOL 30 minutes before it opens only to see 40 people in line already? Skip it! 45 minute wait to get seated at a popular restaurant? Skip! Same restaurant is too loud to talk and takes 45 minutes to bring our orders out? Skip!

Walking around the city, you will notice that everyone is doing this all the time.

“So what?” You are probably saying, “Sounds like you skipped a lot of boring and low value moments.” Yes, yes I did. And I don’t want them back. But all this skipping has taken a toll. It has eroded my ability to just be alone in my own head with my own thoughts.

My wife and I had a child and decided to leave big city for a small one with a much (much, much) slower pace. We did this specifically so we could make sure we were able to maximize the time we had with our little girl while she’s actually a little girl. And I love every minute around her. But sometimes she’s doing something that maybe is not the most mentally stimulating to me (it is hard to be “there” when you’ve watched her make the same little block tower 50 times in a row and knock it over)… And I look down at my hands to find that my phone has jumped out of my pocket, unlocked itself and opened my twitter feed.

A year in a half into the parenting “journey”, I already can see how fleeting these moments with your kids are and phone time traveling through any of it seems unthinkable. Now when I’m around my family, I’m leaving the phone out of reach and on vibrate.

I’m not here to advocate that we stop using smart phones and I don’t intend to stop using mine. I’m just worried that people don’t realize what they’re doing. I want them to use their time traveling devices responsibly.

Remember, they don’t go back.

Jan 16

tabletable: a different approach to React grids

We recently added performance profiling1 to Candid (Zeroarc’s first product) and began testing performance with an estimated five years of generated fake data. Unsurprisingly, we had some hot spots that needed improvement. One of these hot spots was a table that ended up with thousands of rows.

In a traditional web app, you would only display a subset of the data in a grid and handle paging on the server to deliver the remaining data when requested. Modern users are more discerning and demanding. They want paging to happen instantly and most certainly without a page load. They probably want to filter it quickly and maybe even sort (though lets be honest, nobody sorts).

They want all the things.

At Zeroarc, we aim to delight our customers, so server side paging was a non-starter. Instead, we started out with the DataTables jQuery plugin and rendering all of our data on the server. DataTables reads the DOM and sets up paging, searching, and sorting for you automatically. The issue with this approach is that it starts to slow down pretty quick as the number of elements in the table grows. The normal solution to this problem is to go back to having the server manage paging, searching, and sorting and use asynchronous requests to grab the data from the back-end.

The downside to using “AJAX” queries is that any operations on the table are going to feel slower than if all the data was loaded into the browser’s memory. So we started playing around with the idea having the server render embedded JSON in the page and then passing that to DataTables instead of making server queries. This is totally possible with DataTables. But in the process of getting this going, it started to feel like we were fighting against the software.

Our app had grown and we wanted more control over the table experience. Not just the look and feel, but other traits, like the ability to render on the server to avoid page re-flows when the JavaScript initializes. DataTables is pretty complex and it does way more than we need. It felt too heavy.

Being quite invested in the React ecosystem, we took a look around at other React tables, such as Griddle, Facebook’s Fixed Data Tables, and a few others. All the ones we tried either were too hard to configure, too hard to style, or just had weird behavior.

So we created tabletable. Since this was just for “us”, we only needed to implement the features we wanted. The whole thing currently weighs in at a svelte 304 lines of code, including spaces!

tabletable only does a few things compared to some of the other tables out there, but it does them well. It intentionally ignores the whole concept of asynchronous requests to the back-end and only focuses on displaying results that are in memory. Developers are free to load additional data as they wish in the parent component or flux store. Since tabletable only inserts DOM elements for the rows that are currently displayed, our performance issues on the n * 1000 rows scale were gone. Paging is super fast (everything is in memory) and since the developer has to write their own filtering code, they have full control over how the filtering occurs (and how fast it is).

My favorite part of tabletable is how it handles data and column display. tabletable requires data to be structured as an Immutable sequence2. But thats the only requirement. The schema of that data can be anything the developer wants it to be. This is because the column definitions are functions that take a row of the data (YOUR data) and return React elements.

The code ends up looking like this:

let someRandomData = [
  [{"name":"Richard Watkins","skill":"Culture Change","color":"Indigo"},
  {"name":"Dorothy Bennett","skill":"GFSI","color":"Red"},
  {"name":"Steve Clark","skill":"Urinalysis","color":"Turquoise"},
  {"name":"Matthew Perkins","skill":"ODM","color":"Yellow"}

let immutableData = Immutable.fromJS(someRandomData).toSeq();

let columnDefs = {
  index: {
    display: 'Index',
    headerCssClass: 'col-sm-1',
    visible: true,
    data: (row,index,context) => <div>{index}</div>,
  name: {
    display: 'Name',
    headerCssClass: 'col-sm-4',
    data: row => <div>{row.get('name')}</div>,
  skill: {
    display: 'Skill',
    headerCssClass: 'col-sm-4',
    data: row => <div>{row.get('skill')}</div>,
  color: {
    display: 'Favorite Color',
    headerCssClass: 'col-sm-3',
    data: row => <div>{row.get('color')}</div>,


With a little more effort, you can add filtering. We haven’t yet added sorting and won’t until we have a customer demand it, but it will be fairly straightforward if we need it.

The final result looks something like this:

Read more about it on the tabletable landing page or on Github. We always love feedback. Let us know what you think using the comments link at the bottom of the page.

  1. We are using MiniProfiler for server and client profiling. It is excellent.
  2. At some point we may get rid of this requirement if there is interest. PRs always welcome!
Jan 16

Introducing Carbon Dream, a document annotator

Last summer (can you believe it is almost next summer?), Chris and I began working on a document review system that forms a core part of our startup’s first product, Candid. One of the key features of the product is enabling users to provide feedback on a document by adding comments and graphical annotations. Initially we used Annotator for the annotations. Getting it going is fairly straight forward, but we quickly ran into issues when we tried to annotate anything other than selectable text, specifically images. We hacked out a plugin that managed this, but it was quickly apparent that for something so core to our experience, we needed more control. So we rolled our own React component to do the same.

We call it Carbon Dream, a document and image annotator (the name refers to my never ending lust for expensive carbon fiber mountain bikes).

With Carbon Dream, we forgo text based annotation and use 100% coordinate based annotation. Of course, this means Carbon Dream is not well suited to annotating reflowing documents, like html, as the coordinates of document text can change within the browser window. But for fixed position documents (like PDFs) and images that scale in size, Carbon Dream works great. Out of the box it can handle multiple types of annotations, such as pins, circles, squares, and highlights.

Circle Annotation

This is open source and free to use under the MIT license. We will keep making it better as our review system evolves and we hope other people may find it useful in their software as well.

Checkout the Demo and the code and let us know what you think! Pull requests always welcome!

Sep 15

NLog Quick Hit – Using netcat as a remote log viewer

I was looking for an easy way to get access to NLog output remotely. Specifically, I wanted to view the logs coming from a virtual machine running on Parallels (with our app running on it) on my Macbook Pro. Our new app has great log coverage and often checking the log output is quicker than firing up the debugger to diagnose development issues. I was pretty unhappy with all the options I found for remotely viewing the log output. Then I remembered Netcat.

Netcat is an old unix program that, amongst other things, can open a raw TCP connection on a port and dump the contents to the screen. Turns out that you can use netcat (nc on OSX) to make an ad-hoc remote log viewer.

First set up NLog with a Network target:

  <target xsi:type="Network"
      layout="${uppercase:${level}} ${callsite} ${message} ${exception:innerFormat=Message,Type,Method:maxInnerExceptionLevel=5:innerExceptionSeparator=->:separator=|:format=Message,Type,Method}"
      address="tcp://" />
  <logger name="*" minlevel="Trace" writeTo="osxnc" />

Then, on the computer you want to use to view the log output, start netcat (l means listen and k keeps the connection open even after a client disconnects):

nc -lk 12121

And your logs dump to the screen in real time!

DEBUG Zeroarc.Candid.Service.WorkflowService`1+<ChangeScheduleDate>d__30.MoveNext ChangeScheduleDate succeeded: result=1, objectId=53, userId=2, stateId=19, date=10/20/2015 12:00:00 AM
DEBUG Zeroarc.Candid.Service.WorkflowService`1+<ChangeScheduleDate>d__30.MoveNext ChangeScheduleDate succeeded: result=1, objectId=53, userId=2, stateId=19, date=11/20/2015 12:00:00 AM
DEBUG Zeroarc.Candid.Service.WorkflowService`1+<ChangeScheduleDate>d__30.MoveNext ChangeScheduleDate succeeded: result=1, objectId=53, userId=2, stateId=19, date=11/17/2015 12:00:00 AM

Netcat has a ton of other helpful uses as well, especially when debugging opaque and poorly logged software.

Aug 14

AWS quick hit – configure Elastic Beanstalk with cross zone load load balancing and connection draining

I spent a long time trying to find the exact syntax for this yesterday. Hope it helps save someone else some time.

If you are using Amazon’s Elastic Beanstalk and want to get your Elastic Load Balancers using cross zone load balancing and/or connection draining, you will need to create an .ebextensions folder with a file with a .config extension that has the following content:


    Type: AWS::ElasticLoadBalancing::LoadBalancer
      CrossZone: True
      ConnectionDrainingPolicy: {"Enabled" : True, "Timeout" : 300 }

In other news, I intend to start posting here regularly again. Most of my recent posts have been on my team’s blog: Soccer & Code, but I’ll start giving fzysqr some more love, promise!

Aug 13

Technical Overview of Golazo

Yesterday, I released a post on the MLS Dev Blog detailing our newest product, Golazo:

The idea was basically this: ingest stats, news, social content, chat, photos, videos, and live streams and create a single place for our fans to park their computers or tablets or phones during a match that they were already watching on television or MLS Live. The goal was to create the best second screen experience in sports.

Check it out! and let me know what you think. @jdslatts

Jul 13

Introducing stacklog for Node.js

Hey! I just released a cool little Node.js utility called stacklog. It makes it easier to add helpful logging prefixes through your debug statements in your apps.

Your truly, writing for MLS Dev Blog:

I am currently laid up from a recent hand injury, involving a bottle of wine and and a bad idea. Ironically, despite only having 1.2 hands to use for typing (pinky on right hand), being stuck at home has actually made it easier to get through some of my hacking todo list. The first item on that list is to release a little utility I have been using lately: stacklog.

Read the whole article at the MLS Dev blog or go straight to the good stuff on npm or github. As always, let me know what you think! @jdslatts on twitter or using the comments link below.

May 13

Taking SaltStack to The Next Level With Pillars and Python States

This is a cross post from a post I wrote for the MLS Digital Dev Blog. -Justin


For those of us who come from traditional sysops backgrounds, learning Salt means un-learning many of our shell scripting habits. Continue reading →

Jan 13

Be The Master Of Your Minions (An Introduction To Salt)

Happy new year fzysqr readers! What better way could we possibly celebrate the new year than by trying a new infrastructure automation system? Late last year, I began rolling out Salt a.k.a. SaltStack (for SEO help I’m told).

Continue reading →

Aug 12

Quick Tip – Wrong SSH Key Cached With Github After Changing Users and Keys

If you find that you are unable to access Github after switching out your private keys, you may have a key cached with ssh agent. To diagnose:

ssh git@github.com -v

Look for something along the lines of “debug1: Remote: Forced command: gerve someuser”. If you see this, you have a cached key. To fix:

killall ssh-agent
exec ssh-agent bash
ssh-key -D

You should see “All identifies removed” followed by “Identity added: //.ssh/id_rsa”. Now you should be able to successfully do:

ssh git@github.com