return f;
}
+template <class T>
+template <class F>
+Future<T> Future<T>::onTimeout(Duration dur, F&& func, Timekeeper* tk) {
+ auto funcw = folly::makeMoveWrapper(std::forward<F>(func));
+ return within(dur, tk)
+ .onError([funcw](TimedOut const&) { return (*funcw)(); });
+}
+
template <class T>
typename std::add_lvalue_reference<T>::type Future<T>::value() {
throwIfInvalid();
Future<T>>::type
onError(F&& func);
+ /// Like onError, but for timeouts. example:
+ ///
+ /// Future<int> f = makeFuture<int>(42)
+ /// .delayed(long_time)
+ /// .onTimeout(short_time,
+ /// []() -> int{ return -1; });
+ ///
+ /// or perhaps
+ ///
+ /// Future<int> f = makeFuture<int>(42)
+ /// .delayed(long_time)
+ /// .onTimeout(short_time,
+ /// []() { return makeFuture<int>(some_exception); });
+ template <class F>
+ Future<T> onTimeout(Duration, F&& func, Timekeeper* = nullptr);
+
/// This is not the method you're looking for.
///
/// This needs to be public because it's used by make* and when*, and it's
auto f = p.getFuture().within(awhile, std::runtime_error("expected"));
EXPECT_THROW(f.get(), std::runtime_error);
}
+
+TEST(Timekeeper, onTimeout) {
+ bool flag = false;
+ makeFuture(42).delayed(one_ms)
+ .onTimeout(Duration(0), [&]{ flag = true; return -1; })
+ .get();
+ EXPECT_TRUE(flag);
+}
+
+TEST(Timekeeper, onTimeoutReturnsFuture) {
+ bool flag = false;
+ makeFuture(42).delayed(one_ms)
+ .onTimeout(Duration(0), [&]{ flag = true; return makeFuture(-1); })
+ .get();
+ EXPECT_TRUE(flag);
+}
+
+TEST(Timekeeper, onTimeoutVoid) {
+ makeFuture().delayed(one_ms)
+ .onTimeout(Duration(0), [&]{
+ });
+ makeFuture().delayed(one_ms)
+ .onTimeout(Duration(0), [&]{
+ return makeFuture<void>(std::runtime_error("expected"));
+ });
+ // just testing compilation here
+}
+
+// TODO(5921764)
+/*
+TEST(Timekeeper, onTimeoutPropagates) {
+ bool flag = false;
+ EXPECT_THROW(
+ makeFuture(42).delayed(one_ms)
+ .onTimeout(Duration(0), [&]{ flag = true; })
+ .get(),
+ TimedOut);
+ EXPECT_TRUE(flag);
+}
+*/