About suspend functions that spawn coroutines that persist

Well that would be similar to connectAsync and then calling the returned Deferred’s await() function, right?

However, I do admit that passing a coroutinescope to a connect function for a keepalive coroutine still is a little weird as far as structural concurrency is concerned, since it may be confusing to the user to know just what scope they should pass to, what scope would make sense. So perhaps in this case it would then make sense to really set up a completely internal coroutinescope in the connect function, like this:

internalScopeMainJob = SupervisorJob()
internalScope = CoroutineScope(Dispatchers.Default + internalScopeMainJob)

Since the lifecycle of the keepalive coroutine would anyway be tied to the connect and disconnect calls, it would be straightforward to do this in connect and then call internalScopeMainJob.cancelAndJoin in disconnect. This would set up a separate coroutine hierarchy, but would be purely internal. Thoughts?