ApiTester: Address concurrency issues in the workload management

This commit is contained in:
Vaidas Gasiunas 2022-03-09 14:38:07 +01:00
parent 8d2c3a4773
commit bd0bf1cfc2
3 changed files with 18 additions and 13 deletions

View File

@ -228,7 +228,7 @@ public:
FDBDatabase* db; FDBDatabase* db;
fdb_error_t err = fdb_create_database(clusterFile, &db); fdb_error_t err = fdb_create_database(clusterFile, &db);
if (err != error_code_success) { if (err != error_code_success) {
throw TesterError(fmt::format("Failed create database with the culster file '{}'. Error: {}({})", throw TesterError(fmt::format("Failed create database with the cluster file '{}'. Error: {}({})",
clusterFile, clusterFile,
err, err,
fdb_get_error(err))); fdb_get_error(err)));

View File

@ -20,9 +20,11 @@
#include "TesterWorkload.h" #include "TesterWorkload.h"
#include "TesterUtil.h" #include "TesterUtil.h"
#include "test/apitester/TesterScheduler.h"
#include <cstdlib> #include <cstdlib>
#include <memory> #include <memory>
#include <fmt/format.h> #include <fmt/format.h>
#include <vector>
namespace FdbApiTester { namespace FdbApiTester {
@ -74,8 +76,7 @@ void WorkloadBase::schedule(TTaskFct task) {
tasksScheduled++; tasksScheduled++;
manager->scheduler->schedule([this, task]() { manager->scheduler->schedule([this, task]() {
task(); task();
tasksScheduled--; scheduledTaskDone();
checkIfDone();
}); });
} }
@ -98,8 +99,7 @@ void WorkloadBase::execTransaction(std::shared_ptr<ITransactionActor> tx, TTaskF
cont(); cont();
} }
} }
tasksScheduled--; scheduledTaskDone();
checkIfDone();
}); });
} }
@ -116,8 +116,8 @@ void WorkloadBase::error(const std::string& msg) {
} }
} }
void WorkloadBase::checkIfDone() { void WorkloadBase::scheduledTaskDone() {
if (tasksScheduled == 0) { if (--tasksScheduled == 0) {
if (numErrors > 0) { if (numErrors > 0) {
error(fmt::format("Workload failed with {} errors", numErrors.load())); error(fmt::format("Workload failed with {} errors", numErrors.load()));
} else { } else {
@ -133,14 +133,18 @@ void WorkloadManager::add(std::shared_ptr<IWorkload> workload, TTaskFct cont) {
} }
void WorkloadManager::run() { void WorkloadManager::run() {
std::vector<std::shared_ptr<IWorkload>> initialWorkloads;
for (auto iter : workloads) { for (auto iter : workloads) {
iter.first->init(this); initialWorkloads.push_back(iter.second.ref);
} }
for (auto iter : workloads) { for (auto iter : initialWorkloads) {
iter.first->start(); iter->init(this);
}
for (auto iter : initialWorkloads) {
iter->start();
} }
scheduler->join(); scheduler->join();
if (numWorkloadsFailed > 0) { if (failed()) {
fmt::print(stderr, "{} workloads failed", numWorkloadsFailed); fmt::print(stderr, "{} workloads failed", numWorkloadsFailed);
} else { } else {
fprintf(stderr, "All workloads succesfully completed"); fprintf(stderr, "All workloads succesfully completed");

View File

@ -95,8 +95,9 @@ protected:
private: private:
WorkloadManager* manager; WorkloadManager* manager;
// Check if workload is done and notify the workload manager // Decrease scheduled task counter, notify the workload manager
void checkIfDone(); // that the task is done if no more tasks schedule
void scheduledTaskDone();
// Keep track of tasks scheduled by the workload // Keep track of tasks scheduled by the workload
// End workload when this number falls to 0 // End workload when this number falls to 0