Back in 2015, I had just started at CANVAS Technology and my task was clear: to create a web application that can service many operations concurrently from users, robots, and other integration services. Prior to this new venture, I had spent my last few years doing Ruby on Rails, Node.js JavaScript, mobile applications (cordova, minimal Objective-C, Java/Android). Only a few months before joining CANVAS had I just started playing with Elixir and Phoenix. I was so excited and relieved to find something that was geared exactly for what we were embarking on.
What I want to outline in this post is the lessons I’ve learned using Elixir these last 3+ years and help others learn quickly.
Upgrade sooner than later
Discuss pains of upgrading Elixir 1.3 –> 1.6, Ecto 1.0 –> 2.0, Phoenix 0.9 –> 1.3. It definitely hasn’t been easy to update, this is mitigated by staying abreast of Elixir / phoenix changes and trying to implement early.
GenServers are your friend – but use them only if you must
Abstract away the API and the Server – link to post by Dave Thomas explaining splitting the APIs, Servers, and Implementations in Elixir.
Testing pains with GenServers and Ecto’s concurrency model
Make sure to restart genservers / supervisors. Having a connection time out be longer for longer running genservers that aren’t started every setup fixture.
Using docker for team / testing scenarios
Docker-compose for stack, testing with diff vars. Preload any databases by putting them in the postgres container root in /tmp
.
Testing browsers with Hound / ChromeDriver
Use Hound and chromedriver.
Do not code everything to the Repo
itself
It’s not as easy to cut off your database addiction. Having an intermediate context API that cache is a good first step.
PubSub is your friend, use structs to pass messages
When using cast/gproc, pass the Structs, don’t use tuples. Resist the simple solutiuons. Pass structs defined.
Learn ETS
Don’t use a cache when the Erlang VM has one built in.
Use behaviours
Take a look how crowdfundr app. Code to interfaces, not the implementations. Use the impl
approach.
Nginx as a front-end for SSL termination
Links/discussion to the post, security wise, leave Nginx to handle the vulns and your app to handle the impl.
Releases with Distillery
Ship those tarballs, let it fly. Easier/safer than shiping your code. Should probably post about the replacing of ENV vars. Use a Config module for system set env variables instead of them getting baked into your sys.config
file.
Clustering – using epmd / GenServers for node communication message passing
Link to swarm and libcluster – knowing that clustering comes out of the box with Erlang/Elixir.