Naios / continuable

C++14 asynchronous allocation aware futures (supporting then, exception handling, coroutines and connections)
https://naios.github.io/continuable/
MIT License
815 stars 44 forks source link

Simple example does not execute THEN block on Linux #35

Closed zhensydow closed 3 years ago

zhensydow commented 3 years ago

@Naios I have tried a simple test but the continuation block is not executed (the part inside then()).


Actual Code

auto my_sleep(int millisecs) {
    return cti::make_continuable<std::string>(
    [millisecs](auto&& promise){
        printf("-- running my_sleep(%d)\n", millisecs);
        std::this_thread::sleep_for(std::chrono::milliseconds(millisecs));
        printf("-- end of my_sleep(%d)\n", millisecs);
        return "time goes on";
    });
}

int main(){
    printf("Start\n");

    my_sleep(2000)
    .then(
        []( std::string result ){
        printf( "then %s\n", result.data() );
        });

    printf("End\n");
}

Compiler Options

g++ -std=c++14 -Wall -Og -I. -g -pthread main.cpp

Actual Output

Start
-- running my_sleep(2000)
-- end of my_sleep(2000)
End

My Environment

Naios commented 3 years ago

You always need to resolve the promise with a result or exception in order to continue.

auto my_sleep(int millisecs) {
    return cti::make_continuable<std::string>(
    [millisecs](auto&& promise){
        printf("-- running my_sleep(%d)\n", millisecs);
        std::this_thread::sleep_for(std::chrono::milliseconds(millisecs));
        printf("-- end of my_sleep(%d)\n", millisecs);
            promise.set_value("time goes on");
            // ^^^^^^^^^^^^^^^^^^^^^
    });
}

or

auto my_sleep(int millisecs) {
    return cti::async(
    [millisecs] {
        printf("-- running my_sleep(%d)\n", millisecs);
        std::this_thread::sleep_for(std::chrono::milliseconds(millisecs));
        printf("-- end of my_sleep(%d)\n", millisecs);
        return "time goes on";
    });
}

Probably you also want to run the blocking wait on a dedicated thread, otherwise you block the main thread and then you don't need to use the continuation anyway. The promises are mostly designed for asynchronous APIs such as boost::asio that accept a callback and resolve it later.

zhensydow commented 3 years ago

Thanks. Now it works. I was confused because my first test was a continuation without parameter as:

auto my_sleep(int millisecs) {
    return cti::make_continuable<void>(
    [millisecs](auto&& promise){
        std::this_thread::sleep_for(std::chrono::milliseconds(millisecs));
        // promise.set_value();  Missing step
    });
}

int main(){
    my_sleep(2000)
    .then(
        [](){
        printf( "then nothing\n");
        });

    return EXIT_SUCCESS;
}

But calling seT_value without parameters also works.