[coll] Improve event loop. (#10199)

- Add a test for blocking calls.
- Do not require the queue to be empty after waking up; this frees up the thread to answer blocking calls.
- Handle EOF in read.
- Improve the error message in the result. Allow concatenation of multiple results.
This commit is contained in:
Jiaming Yuan
2024-04-18 03:29:52 +08:00
committed by GitHub
parent 7c0c9677a9
commit 4b10200456
11 changed files with 312 additions and 111 deletions

View File

@@ -1,5 +1,5 @@
/**
* Copyright 2023, XGBoost Contributors
* Copyright 2023-2024, XGBoost Contributors
*/
#include <gtest/gtest.h> // for ASSERT_TRUE, ASSERT_EQ
#include <xgboost/collective/socket.h> // for TCPSocket, Connect, SocketFinalize, SocketStartup
@@ -28,18 +28,25 @@ class LoopTest : public ::testing::Test {
auto domain = SockDomain::kV4;
pair_.first = TCPSocket::Create(domain);
auto port = pair_.first.BindHost();
pair_.first.Listen();
in_port_t port{0};
auto rc = Success() << [&] {
port = pair_.first.BindHost();
return Success();
} << [&] {
pair_.first.Listen();
return Success();
};
SafeColl(rc);
auto const& addr = SockAddrV4::Loopback().Addr();
auto rc = Connect(StringView{addr}, port, 1, timeout, &pair_.second);
ASSERT_TRUE(rc.OK());
rc = Connect(StringView{addr}, port, 1, timeout, &pair_.second);
SafeColl(rc);
rc = pair_.second.NonBlocking(true);
ASSERT_TRUE(rc.OK());
SafeColl(rc);
pair_.first = pair_.first.Accept();
rc = pair_.first.NonBlocking(true);
ASSERT_TRUE(rc.OK());
SafeColl(rc);
loop_ = std::shared_ptr<Loop>{new Loop{timeout}};
}
@@ -74,8 +81,26 @@ TEST_F(LoopTest, Op) {
loop_->Submit(rop);
auto rc = loop_->Block();
ASSERT_TRUE(rc.OK()) << rc.Report();
SafeColl(rc);
ASSERT_EQ(rbuf[0], wbuf[0]);
}
TEST_F(LoopTest, Block) {
// We need to ensure that a blocking call doesn't go unanswered.
auto op = Loop::Op::Sleep(2);
common::Timer t;
t.Start();
loop_->Submit(op);
t.Stop();
// submit is non-blocking
ASSERT_LT(t.ElapsedSeconds(), 1);
t.Start();
auto rc = loop_->Block();
t.Stop();
SafeColl(rc);
ASSERT_GE(t.ElapsedSeconds(), 1);
}
} // namespace xgboost::collective

View File

@@ -0,0 +1,31 @@
/**
* Copyright 2024, XGBoost Contributors
*/
#include <gtest/gtest.h>
#include <xgboost/collective/result.h>
namespace xgboost::collective {
TEST(Result, Concat) {
auto rc0 = Fail("foo");
auto rc1 = Fail("bar");
auto rc = std::move(rc0) + std::move(rc1);
ASSERT_NE(rc.Report().find("foo"), std::string::npos);
ASSERT_NE(rc.Report().find("bar"), std::string::npos);
auto rc2 = Fail("Another", std::move(rc));
auto assert_that = [](Result const& rc) {
ASSERT_NE(rc.Report().find("Another"), std::string::npos);
ASSERT_NE(rc.Report().find("foo"), std::string::npos);
ASSERT_NE(rc.Report().find("bar"), std::string::npos);
};
assert_that(rc2);
auto empty = Success();
auto rc3 = std::move(empty) + std::move(rc2);
assert_that(rc3);
empty = Success();
auto rc4 = std::move(rc3) + std::move(empty);
assert_that(rc4);
}
} // namespace xgboost::collective