HACKER Q&A
📣 llimos

Does any programming language have inline offline async calls?


I've recently been using Microsoft Power Automate no-code environment. One of the things it can do is start an action that might take a few days to complete (e.g. ask someone for an approval). The flow is in a running state for days without anything happening, and it carries on where it left off once the action completes.

It got me wondering if there is any way to do that in actual code. I would want to write something like

  doSomething();
  const result = await offline someVeryVeryLongRunningThing();
  doSomethingElse();
Then behind the scenes someVeryVeryLongRunningThing launches its own process for doing its thing, using polling, events, whatever it wants. (It's a specially written function that supports async offline.) The main process saves its state to disk somewhere and terminates. Then when someVeryVeryLongRunningThing finishes (or fails), the original process is relaunched with the state and call stack that were there before, and carries on where it left off.

Obviously things like open sockets and file handles will be lost. But if it could at least retrieve those parts of state that are just data that would still leave a lot of useful use cases. And this is something a compiler could catch.

Now of course you can implement it yourself in all sorts of ways, but there would be a lot of boilerplate and the code would not look anything like the above. My question is if there's anything available for any mainstream language today that abstracts the complexity away to look remotely like the code snippet above (which is also what the no-code solution would look like it it was code).


  👤 gus_massa Accepted Answer ✓
Something like the "Arc Challenge"?

http://www.paulgraham.com/arcchallenge.html (HN discussion https://news.ycombinator.com/item?id=108433 (51 points | Feb 2, 2008 | 34 comments) (That was a lot of points and comments at that time.)

This method was used for many years, but it was usual to get a nasty error when the closure was garbage collected after some time. Now in most places the mods replaced it with some additional parameters in the URL.

Somewhat related: Racket has "Stateless Servlets" https://docs.racket-lang.org/web-server/stateless.html that are somewhat similar.


👤 btrask
Very interesting question!

I don't think there is any language/environment that does that natively.

What you seem to be asking for is an abstraction of processes. However the process itself is ultimately an abstraction that is made-up by operating systems.

For example, let's say you call getpid(2) in your program. Then you do some "async offline" work, during which the process exits and is restarted. Now you have a new PID, which is not what you expected.

That means you need to introduce "virtual PIDs" that don't change across async calls. Before long you've reimplemented all of libc (or equivalent).

Golang has had a lot of problems just making green (non-OS) threads work correctly. Any time you stray from the OS, you will have problems interfacing with it.

As an OS feature, I can imagine a kernel that aggressively pages out programs while they're blocking, etc. Before long you get into philosophical questions like "what does it mean for a process to be running?" Usually it's something that the OS defines, and we leave it at that. But you don't have to, if you don't want to.