mirror of
https://github.com/mongodb/mongo.git
synced 2024-11-30 09:06:21 +01:00
SERVER-19359 implement setAlarm() for NetworkInterfaceASIO
This commit is contained in:
parent
a925e2622b
commit
f075019a1d
@ -40,6 +40,8 @@
|
||||
#include "mongo/stdx/memory.h"
|
||||
#include "mongo/util/log.h"
|
||||
#include "mongo/util/net/sock.h"
|
||||
#include "mongo/util/net/ssl_manager.h"
|
||||
#include "mongo/util/time_support.h"
|
||||
|
||||
namespace mongo {
|
||||
namespace executor {
|
||||
@ -141,7 +143,17 @@ void NetworkInterfaceASIO::cancelCommand(const TaskExecutor::CallbackHandle& cbH
|
||||
}
|
||||
|
||||
void NetworkInterfaceASIO::setAlarm(Date_t when, const stdx::function<void()>& action) {
|
||||
MONGO_UNREACHABLE;
|
||||
// "alarm" must stay alive until it expires, hence the shared_ptr.
|
||||
auto alarm = std::make_shared<asio::steady_timer>(_io_service, when - now());
|
||||
alarm->async_wait([alarm, this, action](std::error_code ec) {
|
||||
if (!ec) {
|
||||
return action();
|
||||
} else if (ec != asio::error::operation_aborted) {
|
||||
// When the network interface is shut down, it will cancel all pending
|
||||
// alarms, raising an "operation_aborted" error here, which we ignore.
|
||||
warning() << "setAlarm() received an error: " << ec.message();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
bool NetworkInterfaceASIO::inShutdown() const {
|
||||
|
@ -60,7 +60,9 @@ public:
|
||||
}
|
||||
|
||||
void tearDown() override {
|
||||
_net->shutdown();
|
||||
if (!_net->inShutdown()) {
|
||||
_net->shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
NetworkInterface& net() {
|
||||
@ -222,6 +224,36 @@ TEST_F(NetworkInterfaceASIOTest, StartCommand) {
|
||||
ASSERT_EQ(res.metadata, expectedMetadata);
|
||||
}
|
||||
|
||||
TEST_F(NetworkInterfaceASIOTest, setAlarm) {
|
||||
stdx::promise<bool> nearFuture;
|
||||
stdx::future<bool> executed = nearFuture.get_future();
|
||||
|
||||
// set a first alarm, to execute after "expiration"
|
||||
Date_t expiration = net().now() + Milliseconds(100);
|
||||
net().setAlarm(
|
||||
expiration,
|
||||
[this, expiration, &nearFuture]() { nearFuture.set_value(net().now() >= expiration); });
|
||||
|
||||
// wait enough time for first alarm to execute
|
||||
auto status = executed.wait_for(Milliseconds(5000));
|
||||
|
||||
// assert that not only did it execute, but executed after "expiration"
|
||||
ASSERT(status == stdx::future_status::ready);
|
||||
ASSERT(executed.get());
|
||||
|
||||
// set an alarm for the future, kill interface, ensure it didn't execute
|
||||
stdx::promise<bool> farFuture;
|
||||
stdx::future<bool> executed2 = farFuture.get_future();
|
||||
|
||||
expiration = net().now() + Milliseconds(99999999);
|
||||
net().setAlarm(expiration, [this, &farFuture]() { farFuture.set_value(true); });
|
||||
|
||||
net().shutdown();
|
||||
|
||||
status = executed2.wait_for(Milliseconds(0));
|
||||
ASSERT(status == stdx::future_status::timeout);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace executor
|
||||
} // namespace mongo
|
||||
|
Loading…
Reference in New Issue
Block a user