[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:
@@ -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
|
||||
|
||||
31
tests/cpp/collective/test_result.cc
Normal file
31
tests/cpp/collective/test_result.cc
Normal 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
|
||||
Reference in New Issue
Block a user