Commit 428f1313 authored by Kenton Varda's avatar Kenton Varda Committed by Kenton Varda

Timeouts: Add convenience helpers to kj::Timer interface for adding a timeout to any Promise.

parent 8175968f
......@@ -221,7 +221,8 @@ libkj_async_la_LDFLAGS = -release $(VERSION) -no-undefined
libkj_async_la_SOURCES= \
src/kj/async.c++ \
src/kj/async-unix.c++ \
src/kj/async-io.c++
src/kj/async-io.c++ \
src/kj/time.c++
endif !LITE_MODE
if !LITE_MODE
......
......@@ -38,7 +38,6 @@ set(kj_headers
mutex.h
thread.h
threadlocal.h
time.h
main.h
windows-sanity.h
)
......@@ -59,6 +58,7 @@ set(kj-async_sources
async.c++
async-unix.c++
async-io.c++
time.c++
)
set(kj-async_headers
async-prelude.h
......@@ -66,6 +66,7 @@ set(kj-async_headers
async-inl.h
async-unix.h
async-io.h
time.h
)
if(NOT CAPNP_LITE)
add_library(kj-async ${kj-async_sources})
......
......@@ -204,5 +204,17 @@ TEST(AsyncIo, PipeThreadDisconnects) {
EXPECT_EQ(0, pipeThread.pipe->tryRead(buf, 1, 1).wait(ioContext.waitScope));
}
TEST(AsyncIo, Timeouts) {
auto ioContext = setupAsyncIo();
Timer& timer = ioContext.provider->getTimer();
auto promise1 = timer.timeoutAfter(1 * MILLISECONDS, kj::Promise<int>(kj::NEVER_DONE));
auto promise2 = timer.timeoutAfter(1 * MILLISECONDS, kj::Promise<int>(123));
EXPECT_TRUE(kj::runCatchingExceptions([&]() { promise1.wait(ioContext.waitScope); }) != nullptr);
EXPECT_EQ(123, promise2.wait(ioContext.waitScope));
}
} // namespace
} // namespace kj
// Copyright (c) 2014 Google Inc. (contributed by Remy Blank <rblank@google.com>)
// Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
// Licensed under the MIT License:
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#include "time.h"
#include "debug.h"
namespace kj {
kj::Exception Timer::makeTimeoutException() {
return kj::Exception(
kj::Exception::Nature::LOCAL_BUG, kj::Exception::Durability::OVERLOADED,
__FILE__, __LINE__, kj::heapString("operation timed out"));
}
} // namespace kj
......@@ -80,8 +80,38 @@ public:
virtual Promise<void> afterDelay(Duration delay) = 0;
// Equivalent to atTime(now() + delay).
template <typename T>
Promise<T> timeoutAt(TimePoint time, Promise<T>&& promise);
// Return a promise equivalent to `promise` but which throws an exception (and cancels the
// original promise) if it hasn't completed by `time`.
template <typename T>
Promise<T> timeoutAfter(Duration delay, Promise<T>&& promise);
// Return a promise equivalent to `promise` but which throws an exception (and cancels the
// original promise) if it hasn't completed after `delay` from now.
private:
static kj::Exception makeTimeoutException();
};
// =======================================================================================
// inline implementation details
template <typename T>
Promise<T> Timer::timeoutAt(TimePoint time, Promise<T>&& promise) {
return promise.exclusiveJoin(atTime(time).then([]() -> kj::Promise<T> {
return makeTimeoutException();
}));
}
template <typename T>
Promise<T> Timer::timeoutAfter(Duration delay, Promise<T>&& promise) {
return promise.exclusiveJoin(afterDelay(delay).then([]() -> kj::Promise<T> {
return makeTimeoutException();
}));
}
} // namespace kj
#endif // KJ_TIME_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment