Commit 05c139d1 authored by Kenton Varda's avatar Kenton Varda

Make async ordering test better using TaskSet.

parent 25e31297
...@@ -379,69 +379,73 @@ TEST(Async, Ordering) { ...@@ -379,69 +379,73 @@ TEST(Async, Ordering) {
EventLoop loop; EventLoop loop;
WaitScope waitScope(loop); WaitScope waitScope(loop);
int counter = 0; class ErrorHandlerImpl: public TaskSet::ErrorHandler {
Promise<void> promises[10] = { public:
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr void taskFailed(kj::Exception&& exception) override {
KJ_FAIL_EXPECT(exception);
}
}; };
promises[1] = evalLater([&]() { int counter = 0;
ErrorHandlerImpl errorHandler;
kj::TaskSet tasks(errorHandler);
tasks.add(evalLater([&]() {
EXPECT_EQ(0, counter++); EXPECT_EQ(0, counter++);
{ {
// Use a promise and fulfiller so that we can fulfill the promise after waiting on it in // Use a promise and fulfiller so that we can fulfill the promise after waiting on it in
// order to induce depth-first scheduling. // order to induce depth-first scheduling.
auto paf = kj::newPromiseAndFulfiller<void>(); auto paf = kj::newPromiseAndFulfiller<void>();
promises[2] = paf.promise.then([&]() { tasks.add(paf.promise.then([&]() {
EXPECT_EQ(1, counter++); EXPECT_EQ(1, counter++);
}).eagerlyEvaluate(nullptr); }));
paf.fulfiller->fulfill(); paf.fulfiller->fulfill();
} }
// .then() is scheduled breadth-first if the promise has already resolved, but depth-first // .then() is scheduled breadth-first if the promise has already resolved, but depth-first
// if the promise resolves later. // if the promise resolves later.
promises[3] = Promise<void>(READY_NOW).then([&]() { tasks.add(Promise<void>(READY_NOW).then([&]() {
EXPECT_EQ(4, counter++); EXPECT_EQ(4, counter++);
}).then([&]() { }).then([&]() {
EXPECT_EQ(5, counter++); EXPECT_EQ(5, counter++);
promises[8] = kj::evalLast([&]() { tasks.add(kj::evalLast([&]() {
EXPECT_EQ(7, counter++); EXPECT_EQ(7, counter++);
promises[9] = kj::evalLater([&]() { tasks.add(kj::evalLater([&]() {
EXPECT_EQ(8, counter++); EXPECT_EQ(8, counter++);
}).eagerlyEvaluate(nullptr); }));
}).eagerlyEvaluate(nullptr); }));
}).eagerlyEvaluate(nullptr); }));
{ {
auto paf = kj::newPromiseAndFulfiller<void>(); auto paf = kj::newPromiseAndFulfiller<void>();
promises[4] = paf.promise.then([&]() { tasks.add(paf.promise.then([&]() {
EXPECT_EQ(2, counter++); EXPECT_EQ(2, counter++);
promises[6] = kj::evalLast([&]() { tasks.add(kj::evalLast([&]() {
EXPECT_EQ(9, counter++); EXPECT_EQ(9, counter++);
promises[7] = kj::evalLater([&]() { tasks.add(kj::evalLater([&]() {
EXPECT_EQ(10, counter++); EXPECT_EQ(10, counter++);
}).eagerlyEvaluate(nullptr); }));
}).eagerlyEvaluate(nullptr); }));
}).eagerlyEvaluate(nullptr); }));
paf.fulfiller->fulfill(); paf.fulfiller->fulfill();
} }
// evalLater() is like READY_NOW.then(). // evalLater() is like READY_NOW.then().
promises[5] = evalLater([&]() { tasks.add(evalLater([&]() {
EXPECT_EQ(6, counter++); EXPECT_EQ(6, counter++);
}).eagerlyEvaluate(nullptr); }));
}).eagerlyEvaluate(nullptr); }));
promises[0] = evalLater([&]() { tasks.add(evalLater([&]() {
EXPECT_EQ(3, counter++); EXPECT_EQ(3, counter++);
// Making this a chain should NOT cause it to preempt promises[1]. (This was a problem at one // Making this a chain should NOT cause it to preempt the first promise. (This was a problem
// point.) // at one point.)
return Promise<void>(READY_NOW); return Promise<void>(READY_NOW);
}).eagerlyEvaluate(nullptr); }));
for (auto i: indices(promises)) { tasks.onEmpty().wait(waitScope);
kj::mv(promises[i]).wait(waitScope);
}
EXPECT_EQ(11, counter); EXPECT_EQ(11, counter);
} }
......
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