scylladb / seastar

High performance server-side application framework
http://seastar.io
Apache License 2.0
8.4k stars 1.56k forks source link

smp::invoke_on_others stricter than smp::invoke_on_all #1829

Open andijcr opened 1 year ago

andijcr commented 1 year ago

Consider this unit test:

#include <seastar/testing/thread_test_case.hh>

#include <seastar/core/sharded.hh>

#include <seastar/core/smp.hh>

struct mydata {
    future<> stop() {  return make_ready_future<>(); }
};

SEASTAR_THREAD_TEST_CASE(invoke_on_all_others_sharded_arg) {
    // capturing lambda, compiles
    seastar::smp::invoke_on_all([b=seastar::sstring{"b"}]{ std::ignore = b; }).get();

    // does not compile, !std::is_nothrow_move_constructible
    // seastar::smp::invoke_on_others([b=seastar::sstring{"b"}]{ std::ignore = b; }).get();

    seastar::sharded<mydata> srv;
    srv.start().get();
    // sharded doesn't have this asymmetry
    srv.invoke_on_all([b=seastar::sstring{"b"}](auto &){ std::ignore = b; }).get();
    srv.invoke_on_others([b=seastar::sstring{"b"}](auto &){ std::ignore = b; }).get();

    srv.stop().get();
}

this compiles

seastar::smp::invoke_on_all([b=seastar::sstring{"b"}]{ std::ignore = b; }).get();

but this one does not, due to the requirement std::is_nothrow_move_constuctible seastar::smp::invoke_on_others([b=seastar::sstring{"b"}]{ std::ignore = b; }).get();

note that this asymmetry is not present with a sharded service.

I understand that the proper solution would be to use a foreign_ptr, but it seems strange that invoke_on_others is stricter.

dotnwat commented 1 year ago

I think it's actually failing because std::is_nothrow_copy_constructible is not satisfied. And it seems to me that invoke_on_all should also require std::is_nothrow_copy_constructible, which it doesn't.