# Asynchronous operations in REPL

**URL:** <https://forums.swift.org/t/asynchronous-operations-in-repl/29874>\
**Category:** Using Swift\
**Tags:** repl, combine\
**Created:** [October 16, 2019, 10:07pm UTC](https://forums.swift.org/t/asynchronous-operations-in-repl/29874 "2019-10-16T22:07:43Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![dehesa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dehesa/32/10911_2.png) [@dehesa](https://forums.swift.org/u/dehesa)\
**Post date:** [October 16, 2019, 10:07pm UTC](https://forums.swift.org/t/asynchronous-operations-in-repl/29874/1 "2019-10-16T22:07:43Z")

</div>

I am trying to use the REPL to perform some asynchronous operations (i.e. communicate with some servers, connect and retrieve data from databases, use "web-socket" like protocols, etc.).

I seem to be unable to get any simple asynchronous operation going. For example:

```swift
> var counter = 0
> DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) { counter += 1 }
// counter is always 0

```

I am not sure whether the problem is any of the following:

- The REPL (as command-line programs) doesn't have a `RunLoop`.
- The REPL stops execution completely and waits for more input lines.

I would appreciate if someone knows whether asynchronous operations are actually possible and if so, how.

---

<div class="post-metadata">

**Author:** ![mayoff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mayoff/32/613_2.png) [@mayoff](https://forums.swift.org/u/mayoff)\
**Post date:** [October 16, 2019, 10:48pm UTC](https://forums.swift.org/t/asynchronous-operations-in-repl/29874/2 "2019-10-16T22:48:35Z")

</div>

You can run the main `RunLoop` for a short time (thus letting it drain the main queue):

```
RunLoop.main.run(until: Date(timeIntervalSinceNow: 2))

```

---

<div class="post-metadata">

**Author:** ![dehesa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dehesa/32/10911_2.png) [@dehesa](https://forums.swift.org/u/dehesa)\
**Post date:** [October 16, 2019, 11:01pm UTC](https://forums.swift.org/t/asynchronous-operations-in-repl/29874/3 "2019-10-16T23:01:10Z")

</div>

This does work, thank you @mayoff.  
I find it a bit _inconvenient_ to call `runloop.run(until:)` after any asynchronous operation, though. Is there any other possible option?

---

<div class="post-metadata">

**Author:** ![mayoff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mayoff/32/613_2.png) [@mayoff](https://forums.swift.org/u/mayoff)\
**Post date:** [October 16, 2019, 11:12pm UTC](https://forums.swift.org/t/asynchronous-operations-in-repl/29874/4 "2019-10-16T23:12:59Z")

</div>

Use a playground in Xcode.

---

<div class="post-metadata">

**Author:** ![clayellis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/clayellis/32/43646_2.png) [@clayellis](https://forums.swift.org/u/clayellis)\
**Post date:** [October 17, 2019, 3:28am UTC](https://forums.swift.org/t/asynchronous-operations-in-repl/29874/5 "2019-10-17T03:28:07Z")

</div>

You could use a `DispatchGroup`

---

<div class="post-metadata">

**Author:** ![dehesa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dehesa/32/10911_2.png) [@dehesa](https://forums.swift.org/u/dehesa)\
**Post date:** [October 17, 2019, 6:35am UTC](https://forums.swift.org/t/asynchronous-operations-in-repl/29874/6 "2019-10-17T06:35:20Z")

</div>

@clayellis Could you put an example?

The main problem I am facing is that it is impossible to have a long-running task, while still be able to use the REPL. The usage I have in mind is receiving continuous data from a server (e.g. every minute) while letting the user run swift commands on the stored data (e.g. filter and process rows in a SQLite database).

The solution propose by @mayoff for the REPL freezes the REPL; while playgrounds are not a good match since every time you add new code, the whole thing recompiles.

---

<div class="post-metadata">

**Author:** ![mayoff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/mayoff/32/613_2.png) [@mayoff](https://forums.swift.org/u/mayoff)\
**Post date:** [October 17, 2019, 8:20am UTC](https://forums.swift.org/t/asynchronous-operations-in-repl/29874/7 "2019-10-17T08:20:05Z")

</div>

> [@dehesa](#):
>
> while playgrounds are not a good match since every time you add new code, the whole thing recompiles.

“The whole thing recompiles” only if you modify code that has already executed. If you only add more code at the end of the playground, then it incrementally executes the new code without re-executing the older code.

---

<div class="post-metadata">

**Author:** ![dehesa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dehesa/32/10911_2.png) [@dehesa](https://forums.swift.org/u/dehesa)\
**Post date:** [October 17, 2019, 10:39am UTC](https://forums.swift.org/t/asynchronous-operations-in-repl/29874/8 "2019-10-17T10:39:38Z")

</div>

Oh great, I was not aware of that. I will try to get a playground running for long time and see how it works. In any case, thank you for the information @mayoff.

I am a bit disappointed, though that I cannot use the REPL for such purposes. The REPL and `swift -F` flag for custom frameworks have a great potential as an interactive command-line app.

---

<div class="post-metadata">

**Author:** ![afarnham](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/afarnham/32/10969_2.png) [@afarnham](https://forums.swift.org/u/afarnham)\
**Post date:** [October 17, 2019, 2:18pm UTC](https://forums.swift.org/t/asynchronous-operations-in-repl/29874/9 "2019-10-17T14:18:07Z")

</div>

Also, if you click and hold on the small triangle "play" button in the divider between the console and the editor you can switch to Manually Run.

---

<div class="post-metadata">

**Author:** ![clayellis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/clayellis/32/43646_2.png) [@clayellis](https://forums.swift.org/u/clayellis)\
**Post date:** [October 17, 2019, 4:24pm UTC](https://forums.swift.org/t/asynchronous-operations-in-repl/29874/10 "2019-10-17T16:24:07Z")

</div>

I'd recommend writing a Command Line app instead of just using the REPL (based on what you've shared you're trying to accomplish.)

Here's a really simple example of using a `DispatchGroup` to wait for an async method to finish before exiting the program.

```swift
import Foundation

let group = DispatchGroup()

func someAsyncMethod() {
    group.enter()
    DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
        print("done")
        group.leave()
    }
}

print("calling")
someAsyncMethod()
print("waiting")

group.notify(queue: .main) {
    print("exit")
    exit(EXIT_SUCCESS)
}

dispatchMain()

```

This will print:

```swift
calling
waiting
done
exit
Program ended with exit code: 0

```

I'd recommend reading up on `DispatchGroup`. It's not a terribly complex API but can be misused and frustrating if you aren't careful.

---

<div class="post-metadata">

**Author:** ![dehesa](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dehesa/32/10911_2.png) [@dehesa](https://forums.swift.org/u/dehesa)\
**Post date:** [October 18, 2019, 4:23am UTC](https://forums.swift.org/t/asynchronous-operations-in-repl/29874/11 "2019-10-18T04:23:45Z")

</div>

Great, thank you @clayellis; it is quite simple. I will keep it on my snippets. And yes, command-line will probably be the following steps.

---

<div class="post-metadata">

**Author:** ![clayellis](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/clayellis/32/43646_2.png) [@clayellis](https://forums.swift.org/u/clayellis)\
**Post date:** [October 18, 2019, 4:24am UTC](https://forums.swift.org/t/asynchronous-operations-in-repl/29874/12 "2019-10-18T04:24:42Z")

</div>

Happy to help
