We’re developing an App that requests lengthy calculations. Calcs are performed in-house. To handle multiple simultaneous incoming requests, we have an in-house “pipeline”, with 3 programs: Listener, Calc, and Shipper. Calc, the slow one, has an input queue, so jobs can pile up without being lost. Once Calc finishes a result, it moves it to Shipper’s in-queue. Shipper connects to Anvil, and waits for these results, ultimately packaging and uploading each result to its destination (database row).
At least, when things are working as planned.
We’ve noticed that on some days, our connections to Anvil get interrupted or lost. We see this when running the App in a browser. (No big deal; re-trying the operation almost always works.)
At about the same time, Shipper has been observed to terminate, for no apparent reason. It occurred to me that it might be getting disconnected, too.
Listener can call
anvil.server.wait_forever(), so the Anvil library is in control, and can re-connect at will. In fact, it does, as can easily be seen in Listener’s own console window.
Shipper, however, can’t use
anvil.server.wait_forever(), to automatically re-connect. It is waiting not for Anvil’s Remote Procedure Calls, but for local events (e.g., arrival of a file). Therefore, until such an event happens, its Anvil connection remains unused. If, in the meantime, it loses its connection, for whatever reason, then Shipper won’t know – until it tries to use it, i.e., to update a table row, or call a Server Module function. If that raises an Exception, then that would explain why Shipper terminates.
Whether this is actually the problem, it’s hard to tell. But it’s certainly one we’d want to address anyway. Shipper should be able to
- Detect when it has disconnected
- Attempt to re-connect
- Confirm the connection
- Determine whether the operation failed, and
- if so, then re-try it.
This looks an awful lot like
@anvil.tables.in_transaction. Is that the prescribed solution? If not, what is?