dermesser / uvco

C++20 Coroutines running on libuv for intuitive async I/O
https://borgac.net/~lbo/doc/uvco/
Other
15 stars 0 forks source link

Promise inside non-promise callback function #2

Open indyo opened 1 month ago

indyo commented 1 month ago

Hi. This is great work you're doing. Thank you for sharing!

I am trying uvco out with an embedded javascript engine. Is it possible to do something like the following pseudocode? Basically I'm trying to extend uvco's concurrency capability to the script engine.

VM_FN(App, longTask, [](Vm& vm, const Value args[]) {
    Function resolve, reject;
    auto promise = vm.makePromise(resolve, reject);

    uvco::Loop::run([resolve, reject](const uvco::Loop& loop) -> uvco::Promise<void> {
        try {
            // do long task...

            vm.call(resolve, ...);
        }
        catch (const VmException& e) {
            vm.call(reject, ...)
        }
    });

    return promise;
})

int main()
{
    uvco::runMain<void>([](const uvco::Loop& loop) -> uvco::Promise<void> {
        vm::init();
        runScript("await App.longTask()");

        co_return;
    });

    return 0;
}
dermesser commented 1 month ago

Hi @indyo, thank you for the kind words! I don't fully understand your use case, but it might be that the thread pool functionality (submitWork()) is something that could help here?

int main()
{
    uvco::runMain<void>([](const uvco::Loop& loop) -> uvco::Promise<void> {
        vm::init();
        Promise<void> longTaskDone = submitWork(loop, []() { runScript("await App.longTask()"); });

                // In the meantime, do whatever other work there is to do

                co_await longTaskDone;
                fmt::println("long task has finished");

        co_return;
    });

    return 0;
}

This assumes that within the VM you're CPU-bound and won't have long waiting times for I/O (which would be fine, just maybe not what you want).

You can run tasks like this from everywhere within runMain() and wait for the results asynchronously.