Request for Guide: LiveView latency triangulation

This project has been claimed! But we want more, if you have ideas you can pitch them here.

Hello! We’re looking for good Phoenix content that teaches folks how to solve interesting problems with LiveView.

One example we’ve wanted to build, but have not had time for, is latency triangulation. The idea is: run Phoenix processes in multiple regions, connect visitors to 3+ regions, get LiveView latency for each and then use those numbers to guess their location on a map.

We don’t actually know how well this will work! But we’d like you to build it and see. We’ll pay you a flat $1,000 for:

  1. A github repository with example code and a README that explains how to deploy it on Fly
  2. A separate article/blog post that talks about why this is interesting what you had to figure out to build it.

@brainlid’s turn based game example and article are a great example of this combo working well. The project is small and easy to understand, the article is interesting and developers enjoy reading it.

If you are interested, just reply here with any questions. If this is your first time writing for Fly, share a link to some of your previous work. When we say go, start buildin’. We’ll give you a $500 credit before you even start.


I may be interested. I need to contemplate the actual triangulation, since I haven’t messed with anything like that since high school.

I think the math might actually be pretty simple, getting latency through 3 IPs and then displaying it on a map (maybe a three.js globe) seems like the trickiest part. :slight_smile:

Think about it and if you want to give it a shot, it’s all yours.

I’d be interested, in case it’s not already assigned.

I think the main challenges for me would be:

  • clustering in Elixir
    I’m very interested in this topic, but so far I’ve been manually connecting nodes for my own experiments and doing client projects that aren’t Erlang distributed (even if they’re running separately in more than one datacentre).
  • maths and JavaScript for triangulation and map presentation
    I’m not a maths or a big JavaScript person (one reason for my being keen on LiveView!). Still, I expect I’d manage; I have a maths teacher friend and have used a client hook.

As well as a couple of client projects in Elixir/Phoenix that make use of LiveView – a window cleaning pricing estimator and, in a private admin area, providing for the connecting to and live connection status of the QuickBooks Online API) – I have a little personal LiveView project called LiveCue (hoho) that my brother and I use to play our shared, local file-based music collection in sync with each other. The next step is to introduce clustering and auto-discovery of other nodes on the same network. (My brother will be improving the UI, and I’m hoping that I can drag him into doing a little Elixir, too. :smiling_imp:)

@doliver I think this one might but assigned be I’m really interested in LiveCue. How do you feel about extracting the smallest possible version of “play an mp3 multiple places at once” into a repo with a corresponding article? If you’re into it, I’ll make another topic with your name on it. :wink:

The clustering is surprisingly simple, we can help with that.

A post was merged into an existing topic: Request for Guide: synchronized music streaming with Phoenix

Hey @kurt, I have a few questions about this project. Shall I post here? Email you directly?

Post here if you’re comfy with it! We’re most responsive on these forums lately.

The biggest mental block I have right now is how LiveView would apply to this project. While I suppose it could be used to drive most of the UI, much of the actual work needs to run in the clients browser. Not sure if you have something in mind that I don’t, but it seems like Elixir/Phoenix and maybe Channels is all that’s needed from the back end. I can measure the latency in the browser, then send that to LiveView for the UI work, but it doesn’t feel necessary other than to show off LiveView, and there are probably clearer examples of LiveView UIs.

On a similar note, the backend is basically three or more ping servers, with no real need to cluster them or do anything fancy or Elixir specific. In fact, some kind of serverless function might be preferable from a simplicity standpoint. I don’t mind doing it in Elixir, but I also don’t feel like the example is something that really highlights the power of Elixir.

Given all of that, do you have anything specific to LiveView that I didn’t consider? Should I drop LiveView and just focus on making the latency triangulation work with the browser and Elixir/Phoenix on the backend?

It doesn’t have to be LiveView, the simplest possible thing that works makes sense. It’s pretty easy to measure ping in LiveView, though, and I did think the three elements globe was interesting!

For actual ping endpoints, it’s simplest to make it one app and run it in 3-4 places. We can add region specific IPs to the app.

You’re right that doing everything client side would make sense, but I have a suspicion the servers will need to do a little work to make it accurate. One way you might implement this would be to do the “pings” from the server side, possible do a traceroute to find some intermediate places to ping, etc.

It’s definitely a little contrived do the most basic possible example in Elixir but that’s ok. It’s powerful to have the clustering available, people will be able to extrapolate from the basics to do something more interesting/useful.

I do think (time permitting) it’s worth showing other locations on the visualization. It’s so easy!

@scott did you get anywhere on this? I have a feeling I made it over complicated :smiley:

@kurt Assuming this wasn’t meant for me. :slight_smile:

Whoops! I meant @scottswezey :wink:

Haha yeah, I figured. No worries. :slight_smile:

@kurt Thanks for checking in. I haven’t been able to get anything working that I would be comfortable putting my name on. I am questioning if it’s possible do this with better than continent-level accuracy.

Going into the project I made a few assumptions:

  • Data travels at the speed of light. That means 1ms of ping time represents roughly 186.28 miles. For reference, 140ms of light speed is about the circumference of the earth.
  • The internet doesn’t travel in a straight line, but with no good way to overcome that issue, I’d just code like it did.
  • Similarly, nothing can be done about the speed of last mile connections, so I’ll pretend they don’t exist. (Cable, Cellular, Satellite, etc. introduce more delay and/or don’t move at the speed of light.)
  • Undersea transit would be problematic, so 3+ POPs would be needed per continent if this were ever deployed to production.
  • Latency should only be measured in one direction, server → client OR client → server, which ever is fastest after several tests.
  • The system must account for differences in clock time.

Still, this doesn’t seem to be enough to overcome server load, cellular connections, WiFi, last mile ISP connections, server response times, or whatever else is happening. The fastest I could ever ping my own router was .91ms, but regularly saw ping times of 3-10ms. My router is ~3 feet from my computer, not 169.4 miles away.

Similarly, trying to test against CloudFlare and Google, both probably having multiple datacenters within the SoCal region my house is in, resulted in pings of about 15ms at best. Assuming one direction is 7.5ms, that puts them over 1300 miles away. That’s represents a huge chunk of the continental US, when it should be about 100 miles.

The only way I see this maybe working is going outside of real world use cases. Hard wire a computer to a fiber ISP, ensure the system firewall is disabled, remove any system local processes that might add latency or processing delay, connect to a nearby bare metal machine without any kind of virtualization/load balancing/CDN/firewall/etc.

Alternatively, with enough testing, perhaps a better metric than the speed of light can be found for host fast data moves on the internet.

If someone else has other ideas to make this work, I’m happy to yield the project to them. Our AC broke last week, it’s been 90+ outside, and we’re going into another heat wave, so I don’t see myself spending much time on this or making any progress.

I never got started on front end code for this project, but did find an interesting multilateration javascript library that I think will handle locating a point on the map given the triangulation data. From there, the three js globe should be simpler to implement.

This is good info! Seems like maybe we should do more testing before we jump in with both feet.

One interesting thing we could do is setup a bunch of VMs on Fly and have them ping each other. There’s probably a good article in here even if it’s not a good guide for Elixir.

I’ll let this sit just because it’s interesting, but you’re off the hook. :wink:

If we were to forget the triangulation, it might be interesting just to make a “modern” ping utility that shows a globe, various POPs, and the ping time to each. It’s somewhat frivolous, but would work better with Elixir, Fly, and multiple regions.

(The same UX could probably be applied to my prior project.)

That said, I think the UX would be the hardest part to do well, so someone who is better at Javascript than me should probably take that on if you want to move forward on that idea.