Opens a cursor and reads data. Takes action 'operation' every 'numRows' rows of data. Increments the 'counter' for each successfully read row.
| 177 | |
| 178 | // Opens a cursor and reads data. Takes action 'operation' every 'numRows' |
| 179 | // rows of data. Increments the 'counter' for each successfully read row. |
| 180 | void readResults( |
| 181 | CursorParameters& params, |
| 182 | ResultOperation operation, |
| 183 | int32_t numRows, |
| 184 | int32_t* counter, |
| 185 | int32_t threadId = 0) { |
| 186 | auto cursor = std::make_unique<RowCursor>(params); |
| 187 | { |
| 188 | std::lock_guard<std::mutex> l(mutex_); |
| 189 | tasks_.push_back(cursor->task()); |
| 190 | // To be realized either after 1s wall time or when the corresponding Task |
| 191 | // is no longer running. |
| 192 | auto& executor = folly::QueuedImmediateExecutor::instance(); |
| 193 | auto future = tasks_.back() |
| 194 | ->taskCompletionFuture() |
| 195 | .within(std::chrono::microseconds(1'000'000)) |
| 196 | .via(&executor); |
| 197 | stateFutures_.emplace(threadId, std::move(future)); |
| 198 | |
| 199 | EXPECT_FALSE(stateFutures_.at(threadId).isReady()); |
| 200 | } |
| 201 | bool paused = false; |
| 202 | for (;;) { |
| 203 | if (operation == ResultOperation::kPause && paused) { |
| 204 | if (!cursor->hasNext()) { |
| 205 | paused = false; |
| 206 | Task::resume(cursor->task()); |
| 207 | } |
| 208 | } |
| 209 | if (!cursor->next()) { |
| 210 | break; |
| 211 | } |
| 212 | ++*counter; |
| 213 | if (*counter % numRows == 0) { |
| 214 | if (operation == ResultOperation::kDrop) { |
| 215 | return; |
| 216 | } |
| 217 | if (operation == ResultOperation::kReadSlow) { |
| 218 | std::this_thread::sleep_for(std::chrono::milliseconds(100)); |
| 219 | // If this is an EXPECT this is flaky when running on a |
| 220 | // noisy test cloud. |
| 221 | LOG(INFO) << "Task::toString() while probably blocked: " |
| 222 | << tasks_[0]->toString(); |
| 223 | } else if (operation == ResultOperation::kCancel) { |
| 224 | cancelFuture_ = cursor->task()->requestCancel(); |
| 225 | } else if (operation == ResultOperation::kTerminate) { |
| 226 | cancelFuture_ = cursor->task()->requestAbort(); |
| 227 | } else if (operation == ResultOperation::kYield) { |
| 228 | if (*counter % 2 == 0) { |
| 229 | auto time = getCurrentTimeMicro(); |
| 230 | cursor->task()->yieldIfDue(time - 10); |
| 231 | } else { |
| 232 | cursor->task()->requestYield(); |
| 233 | } |
| 234 | } else if (operation == ResultOperation::kPause) { |
| 235 | auto& executor = folly::QueuedImmediateExecutor::instance(); |
| 236 | auto future = cursor->task()->requestPause().via(&executor); |
nothing calls this directly
no test coverage detected