1
0
Fork 0

Added dedicated startup phase

This commit is contained in:
Simon Grätzer 2016-11-08 14:42:13 +01:00
parent 99b39b9c1e
commit cb98f3ab04
9 changed files with 72 additions and 44 deletions

View File

@ -168,7 +168,7 @@ void Conductor::start() {
auto body = std::make_shared<std::string const>(b.toJson());
requests.emplace_back("server:" + it.first, rest::RequestType::POST,
baseUrl + Utils::nextGSSPath, body);
baseUrl + Utils::startExecutionPath, body);
}
size_t nrDone = 0;
cc->performRequests(requests, 120.0, nrDone, LogTopic("Pregel Conductor"));
@ -176,6 +176,34 @@ void Conductor::start() {
<< _vertexCollections[0]->name();
// look at results
printResults(requests);
if (nrDone == requests.size()) {
startGlobalStep();
} else {
LOG(ERR) << "Not all DBServers started the execution";
}
}
void Conductor::startGlobalStep() {
VPackBuilder b;
b.openObject();
b.add(Utils::executionNumberKey, VPackValue(_executionNumber));
b.add(Utils::globalSuperstepKey, VPackValue(_globalSuperstep));
b.add(Utils::aggregatorValuesKey, VPackValue(VPackValueType::Object));
for (std::unique_ptr<Aggregator>& aggregator : _aggregators) {
aggregator->serializeValue(b);
}
b.close();
b.close();
std::string baseUrl = Utils::baseUrl(_vocbaseGuard.vocbase()->name());
sendToAllDBServers(baseUrl + Utils::startGSSPath, b.slice());
for (std::unique_ptr<Aggregator>& aggregator : _aggregators) {
aggregator->reset();
}
LOG(INFO) << "Conductor started new gss " << _globalSuperstep;
}
void Conductor::finishedGlobalStep(VPackSlice& data) {
@ -207,8 +235,8 @@ void Conductor::finishedGlobalStep(VPackSlice& data) {
LOG(INFO) << "Finished gss " << _globalSuperstep;
_globalSuperstep++;
std::string baseUrl = Utils::baseUrl(_vocbaseGuard.vocbase()->name());
if (_doneCount == _dbServerCount || _globalSuperstep == 101) {
std::string baseUrl = Utils::baseUrl(_vocbaseGuard.vocbase()->name());
LOG(INFO) << "Done. We did " << _globalSuperstep - 1 << " rounds";
VPackBuilder b;
b.openObject();
@ -217,24 +245,8 @@ void Conductor::finishedGlobalStep(VPackSlice& data) {
b.close();
sendToAllDBServers(baseUrl + Utils::finalizeExecutionPath, b.slice());
_state = ExecutionState::FINISHED;
} else { // trigger next superstep
VPackBuilder b;
b.openObject();
b.add(Utils::executionNumberKey, VPackValue(_executionNumber));
b.add(Utils::globalSuperstepKey, VPackValue(_globalSuperstep));
b.add(Utils::aggregatorValuesKey, VPackValue(VPackValueType::Object));
for (std::unique_ptr<Aggregator>& aggregator : _aggregators) {
aggregator->serializeValue(b);
}
b.close();
b.close();
sendToAllDBServers(baseUrl + Utils::nextGSSPath, b.slice());
for (std::unique_ptr<Aggregator>& aggregator : _aggregators) {
aggregator->reset();
}
LOG(INFO) << "Conductor started new gss " << _globalSuperstep;
startGlobalStep();
}
}
}
@ -248,7 +260,7 @@ int Conductor::sendToAllDBServers(std::string path, VPackSlice const& config) {
_doneCount = 0;
if (_dbServerCount == 0) {
LOG(WARN) << "No shards registered for " << _vertexCollections[0]->name();
LOG(WARN) << "No servers registered";
return TRI_ERROR_FAILED;
}
@ -261,8 +273,7 @@ int Conductor::sendToAllDBServers(std::string path, VPackSlice const& config) {
size_t nrDone = 0;
cc->performRequests(requests, 120.0, nrDone, LogTopic("Pregel Conductor"));
LOG(INFO) << "Send messages to " << nrDone << " shards of "
<< _vertexCollections[0]->name();
LOG(INFO) << "Send messages to " << nrDone << " servers";
printResults(requests);
return TRI_ERROR_NO_ERROR;

View File

@ -53,10 +53,10 @@ class Conductor {
private:
Mutex _finishedGSSMutex; // prevents concurrent calls to finishedGlobalStep
VocbaseGuard _vocbaseGuard;
const unsigned int _executionNumber;
std::string _algorithm;
ExecutionState _state = ExecutionState::RUNNING;
std::vector<std::unique_ptr<Aggregator>> _aggregators;
@ -69,7 +69,7 @@ class Conductor {
int32_t _responseCount = 0;
int32_t _doneCount = 0;
// convenience method
void startGlobalStep();
int sendToAllDBServers(std::string url, VPackSlice const& body);
};
}

View File

@ -134,7 +134,7 @@ void OutgoingCache<V, E, M>::sendMessageTo(std::string const& toValue,
template <typename V, typename E, typename M>
void OutgoingCache<V, E, M>::sendMessages() {
LOG(INFO) << "Beggining to send messages to other machines";
LOG(INFO) << "Beginning to send messages to other machines";
std::vector<ClusterCommRequest> requests;
for (auto const& it : _map) {

View File

@ -23,13 +23,13 @@
#include "PregelFeature.h"
#include "Conductor.h"
#include "Worker.h"
#include "Cluster/ClusterInfo.h"
using namespace arangodb::pregel;
static PregelFeature* Instance;
static unsigned int _exeI = 0;
unsigned int PregelFeature::createExecutionNumber() { return ++_exeI; }
unsigned int PregelFeature::createExecutionNumber() { return ClusterInfo::instance()->uniqid(); }
PregelFeature::PregelFeature(application_features::ApplicationServer* server)
: ApplicationFeature(server, "Pregel") {

View File

@ -33,7 +33,8 @@ using namespace arangodb::pregel;
std::string const Utils::apiPrefix = "/_api/pregel/";
std::string const Utils::nextGSSPath = "nextGSS";
std::string const Utils::startExecutionPath = "startExecution";
std::string const Utils::startGSSPath = "startGSS";
std::string const Utils::finishedGSSPath = "finishedGSS";
std::string const Utils::messagesPath = "messages";
std::string const Utils::finalizeExecutionPath = "finalizeExecution";

View File

@ -38,7 +38,8 @@ class Utils {
// constants
static std::string const apiPrefix;
static std::string const nextGSSPath;
static std::string const startExecutionPath;
static std::string const startGSSPath;
static std::string const finishedGSSPath;
static std::string const messagesPath;
static std::string const finalizeExecutionPath;

View File

@ -100,7 +100,7 @@ Worker<V, E, M>::~Worker() {
/// @brief Setup next superstep
template <typename V, typename E, typename M>
void Worker<V, E, M>::nextGlobalStep(VPackSlice data) {
void Worker<V, E, M>::startGlobalStep(VPackSlice data) {
LOG(INFO) << "Called next global step: " << data.toJson();
// TODO do some work?
@ -121,10 +121,12 @@ void Worker<V, E, M>::nextGlobalStep(VPackSlice data) {
// parse aggregated values
VPackSlice aggregatedValues = data.get(Utils::aggregatorValuesKey);
for (auto const& pair : _aggregators) {
VPackSlice val = aggregatedValues.get(pair.second->name());
if (!val.isNone()) {
pair.second->setAggregatedValue(val);
if (aggregatedValues.isObject()) {
for (auto const& pair : _aggregators) {
VPackSlice val = aggregatedValues.get(pair.second->name());
if (!val.isNone()) {
pair.second->setAggregatedValue(val);
}
}
}

View File

@ -34,7 +34,7 @@ namespace pregel {
class IWorker {
public:
virtual ~IWorker(){};
virtual void nextGlobalStep(VPackSlice data) = 0; // called by coordinator
virtual void startGlobalStep(VPackSlice data) = 0; // called by coordinator
virtual void receivedMessages(VPackSlice data) = 0;
virtual void finalizeExecution(VPackSlice data) = 0;
@ -51,7 +51,7 @@ class Worker : public IWorker {
std::shared_ptr<WorkerState<V, E, M>> context);
~Worker();
void nextGlobalStep(VPackSlice data) override; // called by coordinator
void startGlobalStep(VPackSlice data) override; // called by coordinator
void receivedMessages(VPackSlice data) override;
void finalizeExecution(VPackSlice data) override;

View File

@ -68,6 +68,27 @@ RestStatus RestPregelHandler::execute() {
generateError(rest::ResponseCode::NOT_FOUND,
TRI_ERROR_HTTP_NOT_FOUND);
return RestStatus::DONE;
} else if (suffix[0] == Utils::startExecutionPath) {
IWorker *w = PregelFeature::instance()->worker(executionNumber);
if (w) {
LOG(ERR) << "Worker with this execution number already exists.";
generateError(rest::ResponseCode::BAD,
TRI_ERROR_HTTP_FORBIDDEN);
return RestStatus::DONE;
}
LOG(INFO) << "creating worker";
w = IWorker::createWorker(_vocbase, body);
PregelFeature::instance()->addWorker(w, executionNumber);
} else if (suffix[0] == Utils::startGSSPath) {
IWorker *w = PregelFeature::instance()->worker(executionNumber);
if (w) {
w->startGlobalStep(body);
} else {
LOG(ERR) << "Invalid execution number, worker does not exist.";
generateError(rest::ResponseCode::NOT_FOUND,
TRI_ERROR_HTTP_NOT_FOUND);
return RestStatus::DONE;
}
} else if (suffix[0] == Utils::finishedGSSPath) {
Conductor *exe = PregelFeature::instance()->conductor(executionNumber);
if (exe) {
@ -75,14 +96,6 @@ RestStatus RestPregelHandler::execute() {
} else {
LOG(ERR) << "Conductor not found: " << executionNumber;
}
} else if (suffix[0] == Utils::nextGSSPath) {
IWorker *w = PregelFeature::instance()->worker(executionNumber);
if (!w) {// can happen if gss == 0
LOG(INFO) << "creating worker";
w = IWorker::createWorker(_vocbase, body);
PregelFeature::instance()->addWorker(w, executionNumber);
}
w->nextGlobalStep(body);
} else if (suffix[0] == Utils::messagesPath) {
LOG(INFO) << "messages";
IWorker *exe = PregelFeature::instance()->worker(executionNumber);