Published in


How Dockup tracks online status of remote agents using Phoenix Presence

“Is our agent online? Let’s ask Phoenix Presence!”

Dockup is a tool that helps engineering teams spin up on-demand environments. We have a UI that talks to several agents which are installed on remote servers. The UI sends commands to these agents over WebSocket connections using Phoenix channels.

What if agent went down?

The commands to spin up and manage environments are sent over to agents running on remote servers. For this to work, we need to make sure our agents are online and ready to receive the commands. In order to do this, we need to keep track of agents assigned to our users and also show the agent’s online status in the UI.

Our first implementation

In the UI, we show if the agent for the organization is online and ready to receive the commands. It is an old school synchronous “ping” to agent behind a Retry module, where we ask for “pong” from agent to relay that back to our UI. This has a problem.

Consider the agent went down due to some unexpected error in the remote server, or suppose the organization has not yet been configured with a proper agent. If the user now opens the page that shows the agent status, the request would be blocked until the “ping” to the agent times out. Unfortunately this would take some time and would be terrible UX. No user would want to see an empty loading screen, only to find out that their agent is actually down!

Using Phoenix Presence

Phoenix Presence is a feature which allows you to register process information on a topic and replicate it transparently across a cluster. It’s a combination of both a server-side and client-side library which makes it simple to implement. A simple use-case would be showing which users are currently online in an application.

If we can track online statuses of users in chat-rooms, it should be possible to track online statuses of our agents too. That’s exactly what we did and here’s a step-by-step guide on how to do it

Firstly, we need to add Phoenix Presence under the App supervision tree as explained in the official docs.

We then configure our agents channel to use Presence to track the agents that connect with Dockup. After this, we can then simply ask Presence if there is a presence of an agent in our app!

Let’s add the lines that tells the user if their Agent is up. Now we’ll call the function

in our template to render the status in the UI.

Why this is great

By the time user actually visits the settings page, Presence would already have the info whether that specific agent has already joined the topic or not. Since this is a very basic key-value lookup, it is going to be super quick. We no longer need to play ping-pong with the agent to know the presence!

Earlier, this page would, in worst case scenario, take around 30–50 seconds to render, simply because the agent was down.

[info] Received GET /settings
[info] Sent 200 response in 40255.44ms

Using Presence, the response time came down to around 40–50ms, or even lower.

[info] Received GET /settings
[info] Sent 200 response in 17.86ms
[info] Received GET /settings
[info] Sent 200 response in 49.65ms
[info] Received GET /settings
[info] Sent 200 response in 65.62ms
[info] Received GET /settings
[info] Sent 200 response in 31.12ms
[info] Received GET /settings
[info] Sent 200 response in 51.73ms

The most interesting thing about solving this issue for us was that the PR that went in was tiny (just +40/-1), but the impact it had was significant, something we’ve seen time and again with Elixir!




On-demand environments for engineering teams

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Sreenadh T C

Sreenadh T C

photographer | coder | tech enthusiast | love to travel | gamer | elixir guy

More from Medium

Jest testing, Node modules and Reflect

Using Elm pipelines with andThen to decode a multi-object type

Listing Modules under a Namespace in Elixir

Checking the Ogre3D framework with the PVS-Studio static analyzer