How should Duplicate Uplinks behave?

Initially, when two running Uplink programs offered the same function to the same app, the winner was always the program that registered last. All calls would be routed to the second Uplink program.

This is great for a scheduled server update scenario, as it allows an updated Uplink program, on a second PC, to take over for the one that needs to be updated. There’s no hurry in shutting down the first server, as the second one will be receiving all the traffic.

Except, today, it wasn’t. Both Uplink programs were receiving calls from Anvil. When we discovered that, we shut down the older version of our Uplink program immediately.

Is this part of some new “load-balancing” feature? What behavior should we expect when multiple Uplink programs supply the same callable function? How should we shut down an Uplink program to make sure that an incoming call does not get lost?

Hi @p.colbert,

Uplink programs are essentially 'load-balanced. With multiple Uplink programs supplying the same callable function, you can expect calls to go to both programs (we can’t guarantee a particular distribution of requests).

We don’t have a best practice for shutting down Uplink programs at the moment. I’ve added a feature request to our list to be able to deregister all of an Uplink programs server functions, while finishing its currently-executing calls.

Thank you for clearing that up. That explains some of the surprising behavior we’ve seen lately. And suggests explanations for others, including some timed-out function-calls.

How are individual Uplink programs identified? Where are these behaviors documented? I need to be able to plan accordingly. With these more-complex behaviors, our existing Uplink management/maintenance techniques are too simplistic. There will be situations where they don’t work.

Hi @p.colbert,

We don’t distinguish between uplink programs – calls are answered by whichever program is available. I’ve updated the documentation to make it clear that connecting multiple uplink programs with the same function name means that calls can go to either.

If an uplink goes down/crashes/loses connectivity, the work will be sent to the uplink(s) that are still alive. With regards updating uplink programs, at the moment the best way to manage this is with scheduled downtime while you connect the new version.

As mentioned in my previous post, I’ve added a feature request for a more controlled uplink disconnect/shutdown operation.

Hi, @ryan.

I appreciate your efforts, and look forward to seeing the updated documentation.

Anvil does not seem to be broadcasting to all of my Uplink programs. I may have 5 “Listeners” running, but each call is routed to exactly one of them. So something is making that distinction. Something has that list of 5. Something is maintaining that list. The list entries are distinguished by more than just their position; each corresponds to a different “Listener” instance.

How fine-grained are those distinctions? Are two different “Listeners” running simultaneously on the same PC (hence, the same local IP address) considered distinct, for load-balancing purposes?

Edit: Forgive my enthusiasm, but if I know the rules, I can try to work within them. I might not have to build my own overrides.

Hi @p.colbert,

Every Uplink script has its own connection to Anvil. When you mark a function as @anvil.server.callable in an Uplink script, it is registered on that script’s connection. When you anvil.server.call from your app, Anvil finds all of your app’s available Uplink connections where that function is registered, picks one of them, and sends the call there. There’s no guarantee which of your connected Uplinks will receive the function call, but we do guarantee that it will be exactly one of them.

Yes, but how is that list maintained? For example, when one of my Uplink programs becomes inaccessible (e.g., shut down, network disconnect, computer reboot, etc.), how much time does it take for that to be reflected in the list? Is there any way for my App (or Uplink code) to inspect or correct that list?

Or do I have to build my own, more-rigorously-monitored-and-updated list?