#include "rpc/event_hub.hpp" #include #include "check.hpp" using velox::daemon::rpc::EventHub; namespace proto = velox::proto; void run() { EventHub hub; // --- no subscribers: publish is a no-op, not an error -------------------------- hub.publish(proto::Event::TaskAdded, nlohmann::json{{"x", 1}}); // --- a subscription with no filter set receives nothing ------------------- std::vector a; const auto sub_a = hub.subscribe([&](const nlohmann::json& n) { a.push_back(n); }); hub.publish(proto::Event::TaskAdded, nlohmann::json{{"n", 1}}); CHECK_EQ(a.size(), 0u); // --- filtering by event kind ------------------------------------------------ hub.set_filter(sub_a, {proto::Event::TaskAdded}, std::nullopt); hub.publish(proto::Event::TaskAdded, nlohmann::json{{"n", 2}}); hub.publish(proto::Event::TaskRemoved, nlohmann::json{{"n", 3}}); // not subscribed CHECK_EQ(a.size(), 1u); CHECK_EQ(a[0]["n"].get(), 2); // --- two subscribers, independent filters ----------------------------------- std::vector b; const auto sub_b = hub.subscribe([&](const nlohmann::json& n) { b.push_back(n); }); hub.set_filter(sub_b, {proto::Event::TaskRemoved}, std::nullopt); hub.publish(proto::Event::TaskAdded, nlohmann::json{{"n", 4}}); hub.publish(proto::Event::TaskRemoved, nlohmann::json{{"n", 5}}); CHECK_EQ(a.size(), 2u); // got the TaskAdded CHECK_EQ(b.size(), 1u); // got the TaskRemoved CHECK_EQ(b[0]["n"].get(), 5); // --- per-task filter: only the named ids reach the subscriber --------------- std::vector c; const auto sub_c = hub.subscribe([&](const nlohmann::json& n) { c.push_back(n); }); hub.set_filter(sub_c, {proto::Event::TaskState}, std::vector{"t1", "t2"}); hub.publish(proto::Event::TaskState, nlohmann::json{{"n", 6}}, "t1"); hub.publish(proto::Event::TaskState, nlohmann::json{{"n", 7}}, "t9"); // filtered out hub.publish(proto::Event::TaskState, nlohmann::json{{"n", 8}}, "t2"); CHECK_EQ(c.size(), 2u); CHECK_EQ(c[0]["n"].get(), 6); CHECK_EQ(c[1]["n"].get(), 8); // --- a non-task-scoped publish (no task_id) reaches a task-filtered sub too -- // (matches "session.subscribe narrows task events" — a global event isn't one) hub.publish(proto::Event::TaskState, nlohmann::json{{"n", 9}}); CHECK_EQ(c.size(), 3u); // --- set_filter replaces, it does not add ----------------------------------- hub.set_filter(sub_a, {proto::Event::TaskRemoved}, std::nullopt); hub.publish(proto::Event::TaskAdded, nlohmann::json{{"n", 10}}); CHECK_EQ(a.size(), 2u); // still 2 -- TaskAdded no longer reaches sub_a // --- unsubscribe stops delivery ------------------------------------------ hub.unsubscribe(sub_b); hub.publish(proto::Event::TaskRemoved, nlohmann::json{{"n", 11}}); CHECK_EQ(b.size(), 1u); // unchanged CHECK_EQ(a.size(), 3u); // sub_a still gets TaskRemoved } TEST_MAIN()