Distributed Timer With Phoenix LiveView

3J:o3s1e3:3C0hris3:30Zach

I recently had the pleasure of implementing a distributed timer in a Phoenix LiveView application. In particular, one user can start a timer, and the other users in their group will see the same timer with roughly the same time. The timer can be paused, restarted, stopped, and have time added to it. This post will outline the timer’s implementation, explaining my thought process with some code snippets along the way. I assume the reader has some understanding of the architecture of a LiveView application.

Gift list dev diary: deployment

All development for this project is shared on github at https://github.com/codonnell/mygiftlist-blog. I will endeavor to focus on the most relevant snippets of code rather than go over all of them on this blog. For interested parties, the github repo is available to survey all of the minor details.

In this post we’ll deploy the application to dokku. Dokku is a self-hosted PaaS solution which is great for small personal projects. Its API is very similar to Heroku’s, but allows hosting memory-hungry applications more cheaply. To package up our app into an uberjar, we’ll use depstar.

Gift list dev diary: gift list navigation

All development for this project is shared on github at https://github.com/codonnell/mygiftlist-blog. I will endeavor to focus on the most relevant snippets of code rather than go over all of them on this blog. For interested parties, the github repo is available to survey all of the minor details.

In this post we’ll implement a navbar that enables navigation to placeholder gift list pages. The main novelty required is loading gift list data so we can render the navbar on load and the use of a parameterized route. The full changeset can be found in this commit.

Gift list dev diary: gift list form and listing

All development for this project is shared on github at https://github.com/codonnell/mygiftlist-blog. I will endeavor to focus on the most relevant snippets of code rather than go over all of them on this blog. For interested parties, the github repo is available to survey all of the minor details.

In this post we’ll give users the ability to create gift lists and add a temporary listing of a user’s gift lists. The post will focus on the form management aspect of this work rather than the backend implementation, which is similar to the user creation implementation from this post. The form we will build is relatively simple; we’re only scratching the surface of the capabilities of fulcro’s form helpers. The excellent documentation in the fulcro book explains the capabilities more fully. We will also discuss the implementation of a listing of the gift lists created by the user. We won’t cover all the changes, but you can find them in this commit. Edit (2020/07/03): The original gift list UX was incorrect, and was fixed by this commit.

Gift list dev diary: API auth

All development for this project is shared on github at https://github.com/codonnell/mygiftlist-blog. I will endeavor to focus on the most relevant snippets of code rather than go over all of them on this blog. For interested parties, the github repo is available to survey all of the minor details.

In this post we’ll add authentication and authorization to our API endpoint. Using the client-side authentication work from this post, we have access to a signed JWT in the client when a user is logged in. We will take the classic approach of sending the JWT as a bearer token in a request header. The implementation work can be split into the the server-side work of validating and unpacking the JWT, the implementation of authorization rules, and the client-side work of adding the JWT to request headers. We’ll cover most of the changes in this post, but you can find the full changeset in this git commit.

Gift list dev diary: parser tests

All development for this project is shared on github at https://github.com/codonnell/mygiftlist-blog. I will endeavor to focus on the most relevant snippets of code rather than go over all of them on this blog. For interested parties, the github repo is available to survey all of the minor details.

In this post we’ll write a couple of unit tests for our resolvers. The core business logic of our backend application lives in the resolvers, and they change rapidly. This makes them the most important part of our application to test. We’re using docker to host our test database and a Makefile for a bit of convenience, but I won’t cover how that works here. The git commit has the full changeset.

Gift list dev diary: backend persistence

All development for this project is shared on github at https://github.com/codonnell/mygiftlist-blog. I will endeavor to focus on the most relevant snippets of code rather than go over all of them on this blog. For interested parties, the github repo is available to survey all of the minor details.

In this post we’ll use postgres to add a persistence layer to our web server, update our user resolvers to interact with postgres, and add transit handlers to allow us to send dates and timestamps over the network. The git commit for this post’s work has more novelty I won’t cover here including the configuration necessary to host postgres in docker, database migration tooling using flyway, and some postgres configuration for handling dates and timestamps.

Gift list dev diary: initial backend

All development for this project is shared on github at https://github.com/codonnell/mygiftlist-blog. I will endeavor to focus on the most relevant snippets of code rather than go over all of them on this blog. For interested parties, the github repo is available to survey all of the minor details.

In this post we’ll implement a clojure web server that serves our static assets and exposes an API endpoint. The API endpoint accepts EQL requests and responds with a server-side pathom parser’s resolution of that EQL query. Our pathom parser will have a couple of example resolvers so we can test the API endpoint. Much of the code we introduce comes from the fulcro template.

Gift list dev diary: routing

All development for this project is shared on github at https://github.com/codonnell/mygiftlist-blog. I will endeavor to focus on the most relevant snippets of code rather than go over all of them on this blog. For interested parties, the github repo is available to survey all of the minor details.

There are a number of ways to accomplish routing in a single page application. My personal preference on new projects is to use HTML5 routing with “normal” URLs rather than hash-prefixed ones. This allows us to serve different routes as separate HTML pages if we need to and is less confusing for users. I think it is important that a user be able to refresh the page as well as use the forward and back buttons without unexpected behavior, and so we will build our routing solution with those goals in mind.

Gift list dev diary: authentication

All development for this project is shared on github at https://github.com/codonnell/mygiftlist-blog. I will endeavor to focus on the most relevant snippets of code rather than go over all of them on this blog. For interested parties, the github repo is available to survey all of the minor details.

In this post, we’ll create a skeleton project and implement authentication in the client using Auth0. Users will be able to register, log in, and log out. Because we’ll be using Auth0 hosted login, they’ll also be able to reset their password and verify their email address.

Gift list dev diary: introduction

Most holidays my family shares gift lists with each other, offering up ideas for gifts we would like to receive. A year and a half ago, we suffered a bit of a communication breakdown, and some items were gifted twice to the same person. This was understandibly upsetting, and I spoke with family members about setting up a little web app to help us manage sharing gift lists without duplicating gifts–much like a wedding or baby registry. There are existing sites that solve this problem, but I wanted to build something relatively small that wasn’t in it to sell user data to advertisers.