Sneaking an asynchronous operation past the user

Hi guys, I'm trying to build a module that has some kind of function like this:

public func doStuff() {
    DispatchQueue.global().asyncAfter(deadline: .now() + 10) {
        print("ok!")
    }
}

And then the user calls that function after importing the module, and afterwards call some other functions or just do whatever else they need to do.

Of course, if this is in a script, it will probably be done and exit before the 10 seconds are over – but I want it to stay alive until then!

Now I can use a dispatch group to fix this issue, BUT it requires the user to call some function at the end of their script and that is unacceptable.

So, how can I extend the scripts lifetime without requiring any code to be inserted at the end of the main function / implicitly created main function of the script?

Best regards, V.

So, how can I extend the scripts lifetime without requiring any code
to be inserted at the end of the main function / implicitly created
main function of the script?

There isn’t a good way to do this. The script model of programming is inherently synchronous, so when execution falls off the end of main the process terminates, taking your async work with it. You have various options here, but nothing that meets all of your requirements:

  • You can do the work synchronously. This is the traditional approach used by scripts.

  • You could move the async work into a separate process, which will survive the end of the initial process.

  • You can force the client to add code that waits at the end of main.

Finally, you could probably come up with some hacky solution that works in most cases — for example, using atexit — but I recommend against that because it’s not going to scale.

ps None of this is Swift-specific — you’d have exactly the same problem in C — so you might consider bouncing over to Core OS > Concurrency on DevForums.

Share and Enjoy

Quinn “The Eskimo!” @ DTS @ Apple