Interestingly (or … maybe not? I’ve used the same technique in my comment above with one and two processes, depending on what I was trying to achieve…
Two processes to make sync work async (as you noted), but the same pattern but called directly to turn an async job into a sync one. I noted in one of my comments that one can use Node.spawn_link to run jobs across a cluster … I had one project where some of the code was already async but needed to make a (possibly) remote call somewhere on the cluster. It made the most sense to block on a remote call before continuing, and the “call the function, drop into a receive with a timeout” approach turned the remote call into a local syncronous function.
It’s a neat symmetry imho that the same function can be used to modify both sync->async and async->sync all depending on what process it is called from!