Sharing: Ephemeral Data Sync

June 9, 2017

I’ve finally seriously dipped my toes into the waters of Go, and I’m impressed. It’s a delightful tool.

It’s simple, predictable, has good IDE support, but most importantly, it has dead simple and crazy fast compiles, and lets me deploy software much more quickly.

Note: I didn’t say it lets me write software much more quickly. I’d say it’s similar to a lot of other tools in that respect, with the exception of seeming to have mediocre database support, which is a bit of a bummer.

But boy is deploying new software straight-forward. This is the first time I have a no-worries swap-out-the-server deploy shell script for something that needs a server (I’ve always had that for things backed by static files – scp is also very straight-forward).

For some reason, Elixir/Phoenix just never got there for me. The standard deploy toolkits are unreliable or simply broken if you follow the documentation. The elixir processes, once they begin, are a tad hard to find (I ended up using lsof and looking for the process binding to the local port for the service), and the prospect of hotswapping and late-attaching shell access was too alluring to completely abandon in favor of simple deploys. Getting mix (the build tool for Elixir) to produce .beam files with the static assets compiled in like a .jar file was seemingly impossible, at least for off-the-shelf Phoenix projects. So in the end I just had a normal checklist instead of a shell script.

But Go is a breeze. My concerns about e.g. lack of good containers did come up (I lost type safety and needed a library for a concurrent map), even in the small amount of code I wrote. But it simply isn’t nearly enough of a hassle compared to the nonsense I was dealing with from every other non-native compiling language.

The actual service is pretty nice – I wanted a general purpose ephemeral data store I could use for games made in Elm, and I like the JS api I made for sharing the data. I also like that long-polling was very easy to handle, considering websockets are a little brittle with Nginx as a reverse proxy (although this might have more to do with Phoenix than Nginx, in hindsight).

The API I went with is pretty simple (I’m not sure if there is a commonly accepted way to annotate JS types that isn’t miserable, but I’ve chosen this hopefully comprehensible psuedocode):

Sharing.subscribe(itemName : String,
    password : String,
    onNewData : (data : string) => () )
  => stopSubscription : (() => void)

Sharing.set(itemName : String,
    password : String,
    data : String)

Sharing.create(itemName : String,
    password : String,
    data : String,
    onNewData : (data : string) => void)
  => stopSubscription : (() => void)

Obviously create is just shorthand for setting an item and then subscribing to changes, but I thought the order of those was sufficiently confusing, and intent so specific in most use-cases, that it was worth providing the helper.

At the end of the day, I’m having a hard time imagining Go won’t become my language of choice for all future server-side code. And expect to see more online games on the sister-blog for User-Interface-Having projects, Gen517.