Can an app connect to more than one server?

HI!

So I made my wife an “anvil widow”. basically I am spending so much time on anvil that she never sees me!!

In reality she knows I am happy :slight_smile: and she knows I am passionate about Anvil so we have a happy house!

Anyway… I have a question about connecting more than one server - namely, can I? is it possible to connect more than one server and if so, how do I distinguish commands to make them run on different servers and not on them all?

thanks in advance for your help!!!

Michael

Hi Michael,

Good to hear your wife is happy! Marital bliss is not among the design goals of Anvil but it’s a nice bonus.

You can connect multiple Uplink scripts on different machines to your app with no problems. To select which one to call into, you can register the functions with different names. You can pass an argument to anvil.server.callable to register a function with any name you choose:

# On the server
@anvil.server.callable('custom_function_name')
def get_data():
  return [1, 2, 3, 4, 5]

# On the client
anvil.server.call('custom_function_name')

If you want to connect multiple Uplink scripts, you can generate an ID in each script and append it to each function name. If you store the IDs of each connected Upink script in a Data Table, your app knows what IDs to append to the function names when it calls them:

MY_ID = #...something..

if not app_tables.hosts.get(id=MY_ID):
  app_tables.hosts.add_row(id=MY_ID)

@anvil.server.callable("func_" + MY_ID)
def f():
  print "Hello from host %s" % MY_ID

Then in client code:

# Call function f on all hosts
for host in app_tables.hosts.search():
  anvil.server.call('func_' + host['id'])

I recommend using a UUID for the IDs - they are designed to ensure you never accidentally get the same UUID twice.

import uuid
MY_ID = str(uuid.uuid4())

For historical interest, here’s a related thread (which also shows how to use the machine name to construct the ID. This is another good way to get a unique ID, as people have said below):

4 Likes

I use the machine name as MY_ID, so the scripts on all the servers are identical. Each server has two shortcuts, one that pulls from the git repository and one that runs the uplink script.

I also have 3 uplink servers intended to manage long running (hours) processes responding to the same function call. In this case the 3 servers register the function with the same name, and the last one that registers the function responds to the call. The callable function creates a file on a network drive and returns the control to the Anvil server immediately. Then all the three servers keep polling the network file every half second, and the first that finds the file starts the process.

I could have done the Anvil server adding a row to a queue table and the three servers polling the table every half second, but it felt like too much traffic.

The three scripts do poll the table once a minute, just in case the registered callable function is not responding, and if they find there is a pending row on the queue table when the network drive file does not exist, they send me an email so I can stop and restart one of them.

This solution is easily scalable: I can add uplink servers without changing anything.

3 Likes

Me too. This is from that link Shaun posted :

import anvil.server
import socket

host=socket.gethostname().replace("-","_")
...

@anvil.server.callable("remote_" + host)
...etc...

(edit note this is for Linux)

3 Likes

Sorry, I was lazy and didn’t follow the link (I was on my cell).

I do the same, but since I’m on Windows I do COMPUTER_NAME = os.environ['COMPUTERNAME'].replace("-","_")

1 Like

wow! thank you so much for all the support! Now I can control the planet from one app! To prove my powers… I will get that movie featuring my arch nemesis to be delayed by 7 months…

Thanks everyone. My Anvil brothers!! :slight_smile:

2 Likes