0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-30 17:10:48 +01:00

SERVER-19359 implement setAlarm() for NetworkInterfaceASIO

This commit is contained in:
samantharitter 2015-08-04 15:52:38 -04:00
parent a925e2622b
commit f075019a1d
2 changed files with 46 additions and 2 deletions

View File

@ -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 {

View File

@ -60,8 +60,10 @@ public:
}
void tearDown() override {
if (!_net->inShutdown()) {
_net->shutdown();
}
}
NetworkInterface& net() {
return *_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