1
0
Fork 0

added recursive watches and structured get

This commit is contained in:
Jan Steemann 2013-12-12 11:16:41 +01:00
parent 7409f87a73
commit 5b0713af9c
5 changed files with 146 additions and 18 deletions

View File

@ -812,15 +812,19 @@ AgencyCommResult AgencyComm::casValue (std::string const& key,
AgencyCommResult AgencyComm::watchValue (std::string const& key,
uint64_t waitIndex,
double timeout) {
double timeout,
bool recursive) {
std::string url(buildUrl(key));
url += "?wait=true";
std::string url(buildUrl(key) + "?wait=true");
if (waitIndex > 0) {
url += "&waitIndex=" + triagens::basics::StringUtils::itoa(waitIndex);
}
if (recursive) {
url += "&recursive=true";
}
AgencyCommResult result;
sendWithFailover(triagens::rest::HttpRequest::HTTP_REQUEST_GET,

View File

@ -360,7 +360,8 @@ namespace triagens {
AgencyCommResult watchValue (std::string const&,
uint64_t,
double);
double,
bool);
// -----------------------------------------------------------------------------
// --SECTION-- private methods

View File

@ -107,7 +107,8 @@ void HeartbeatThread::run () {
// TODO: check if this is CPU-intensive and whether we need to sleep
AgencyCommResult result = _agency.watchValue("Commands/" + _myId,
lastCommandIndex + 1,
interval);
interval,
false);
if (_stop) {
break;

View File

@ -2290,15 +2290,19 @@ static v8::Handle<v8::Value> JS_GetAgency (v8::Arguments const& argv) {
v8::HandleScope scope;
if (argv.Length() < 1) {
TRI_V8_EXCEPTION_USAGE(scope, "get(<key>, <recursive>)");
TRI_V8_EXCEPTION_USAGE(scope, "get(<key>, <recursive>, <withIndexes>)");
}
const std::string key = TRI_ObjectToString(argv[0]);
bool recursive = false;
bool withIndexes = false;
if (argv.Length() > 1) {
recursive = TRI_ObjectToBoolean(argv[1]);
}
if (argv.Length() > 2) {
withIndexes = TRI_ObjectToBoolean(argv[2]);
}
AgencyComm comm;
AgencyCommResult result = comm.getValues(key, recursive);
@ -2308,20 +2312,52 @@ static v8::Handle<v8::Value> JS_GetAgency (v8::Arguments const& argv) {
v8::Handle<v8::Value> err = v8::String::New(errorDetails.c_str(), errorDetails.size());
return scope.Close(v8::ThrowException(err));
}
std::map<std::string, std::string> out;
result.flattenJson(out, "", false);
std::map<std::string, std::string>::const_iterator it = out.begin();
v8::Handle<v8::Object> l = v8::Object::New();
while (it != out.end()) {
const std::string key = (*it).first;
const std::string value = (*it).second;
if (withIndexes) {
// return an object for each key
std::map<std::string, std::string> outValues;
std::map<std::string, std::string> outIndexes;
result.flattenJson(outValues, "", false);
result.flattenJson(outIndexes, "", true);
assert(outValues.size() == outIndexes.size());
l->Set(v8::String::New(key.c_str(), key.size()), v8::String::New(value.c_str(), value.size()));
++it;
std::map<std::string, std::string>::const_iterator it = outValues.begin();
std::map<std::string, std::string>::const_iterator it2 = outIndexes.begin();
while (it != outValues.end()) {
const std::string key = (*it).first;
const std::string value = (*it).second;
const std::string idx = (*it2).second;
v8::Handle<v8::Object> sub = v8::Object::New();
sub->Set(v8::String::New("value"), v8::String::New(value.c_str(), value.size()));
sub->Set(v8::String::New("index"), v8::String::New(idx.c_str(), idx.size()));
l->Set(v8::String::New(key.c_str(), key.size()), sub);
++it;
++it2;
}
}
else {
// return just the value for each key
std::map<std::string, std::string> out;
result.flattenJson(out, "", false);
std::map<std::string, std::string>::const_iterator it = out.begin();
while (it != out.end()) {
const std::string key = (*it).first;
const std::string value = (*it).second;
l->Set(v8::String::New(key.c_str(), key.size()), v8::String::New(value.c_str(), value.size()));
++it;
}
}
return scope.Close(l);
@ -2400,12 +2436,13 @@ static v8::Handle<v8::Value> JS_WatchAgency (v8::Arguments const& argv) {
v8::HandleScope scope;
if (argv.Length() < 1) {
TRI_V8_EXCEPTION_USAGE(scope, "watch(<key>, <waitIndex>, <timeout)");
TRI_V8_EXCEPTION_USAGE(scope, "watch(<key>, <waitIndex>, <timeout>, <recursive>)");
}
const std::string key = TRI_ObjectToString(argv[0]);
double timeout = 1.0;
uint64_t waitIndex = 0;
bool recursive = false;
if (argv.Length() > 1) {
waitIndex = TRI_ObjectToUInt64(argv[1], true);
@ -2413,9 +2450,12 @@ static v8::Handle<v8::Value> JS_WatchAgency (v8::Arguments const& argv) {
if (argv.Length() > 2) {
timeout = TRI_ObjectToDouble(argv[2]);
}
if (argv.Length() > 3) {
recursive = TRI_ObjectToBoolean(argv[3]);
}
AgencyComm comm;
AgencyCommResult result = comm.watchValue(key, waitIndex, timeout);
AgencyCommResult result = comm.watchValue(key, waitIndex, timeout, recursive);
if (result._statusCode == 0) {
// watch timed out

View File

@ -92,10 +92,37 @@ function AgencySuite () {
assertTrue(agency.set("UnitTestsAgency/foo", "baz"));
assertTrue(agency.set("UnitTestsAgency/foo", "bart"));
start = require("internal").time();
var result = agency.watch("UnitTestsAgency/foo", "1", wait);
end = require("internal").time();
assertEqual(0, Math.round(end - start));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test recursive watch
////////////////////////////////////////////////////////////////////////////////
testWatchRecursive : function () {
assertTrue(agency.set("UnitTestsAgency/foo/1", "bar"));
assertTrue(agency.set("UnitTestsAgency/foo/2", "baz"));
var wait = 1;
var start = require("internal").time();
assertFalse(agency.watch("UnitTestsAgency/foo", 0, wait));
var end = require("internal").time();
assertEqual(wait, Math.round(end - start));
assertTrue(agency.set("UnitTestsAgency/foo/3", "bart"));
start = require("internal").time();
var result = agency.watch("UnitTestsAgency/foo", 1, wait);
end = require("internal").time();
assertEqual(0, Math.round(end - start));
start = require("internal").time();
result = agency.watch("UnitTestsAgency/foo", 1, wait, true);
end = require("internal").time();
assertEqual(0, Math.round(end - start));
},
////////////////////////////////////////////////////////////////////////////////
@ -301,6 +328,61 @@ function AgencySuite () {
assertEqual(values["UnitTestsAgency/someDir/foo"], "bar");
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test get recursive
////////////////////////////////////////////////////////////////////////////////
testGetRecursive : function () {
assertTrue(agency.createDirectory("UnitTestsAgency/someDir"));
agency.set("UnitTestsAgency/someDir/foo/1/1/1", "bar1");
agency.set("UnitTestsAgency/someDir/foo/1/1/2", "bar2");
agency.set("UnitTestsAgency/someDir/foo/1/2/1", "bar3");
agency.set("UnitTestsAgency/someDir/foo/1/2/2", "bar4");
agency.set("UnitTestsAgency/someDir/foo/2/1/1", "bar5");
agency.set("UnitTestsAgency/someDir/foo/2/1/2", "bar6");
var values = agency.get("UnitTestsAgency/someDir");
assertEqual({ }, values);
values = agency.get("UnitTestsAgency/someDir/foo");
assertEqual({ }, values);
values = agency.get("UnitTestsAgency/someDir", true);
assertTrue(values.hasOwnProperty("UnitTestsAgency/someDir/foo/1/1/1"));
assertEqual("bar1", values["UnitTestsAgency/someDir/foo/1/1/1"]);
assertTrue(values.hasOwnProperty("UnitTestsAgency/someDir/foo/1/1/2"));
assertEqual("bar2", values["UnitTestsAgency/someDir/foo/1/1/2"]);
assertTrue(values.hasOwnProperty("UnitTestsAgency/someDir/foo/1/2/1"));
assertEqual("bar3", values["UnitTestsAgency/someDir/foo/1/2/1"]);
assertTrue(values.hasOwnProperty("UnitTestsAgency/someDir/foo/1/2/2"));
assertEqual("bar4", values["UnitTestsAgency/someDir/foo/1/2/2"]);
assertTrue(values.hasOwnProperty("UnitTestsAgency/someDir/foo/2/1/1"));
assertEqual("bar5", values["UnitTestsAgency/someDir/foo/2/1/1"]);
assertTrue(values.hasOwnProperty("UnitTestsAgency/someDir/foo/2/1/2"));
assertEqual("bar6", values["UnitTestsAgency/someDir/foo/2/1/2"]);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test get w/ indexes
////////////////////////////////////////////////////////////////////////////////
testGetIndexes : function () {
assertTrue(agency.createDirectory("UnitTestsAgency/someDir"));
agency.set("UnitTestsAgency/someDir/foo", "bar");
agency.set("UnitTestsAgency/someDir/bar", "baz");
var values = agency.get("UnitTestsAgency/someDir", true, true);
assertTrue(values.hasOwnProperty("UnitTestsAgency/someDir/foo"));
assertTrue(values.hasOwnProperty("UnitTestsAgency/someDir/bar"));
assertEqual(values["UnitTestsAgency/someDir/foo"].value, "bar");
assertEqual(values["UnitTestsAgency/someDir/bar"].value, "baz");
assertTrue(values["UnitTestsAgency/someDir/foo"].hasOwnProperty("index"));
assertTrue(values["UnitTestsAgency/someDir/bar"].hasOwnProperty("index"));
assertNotEqual(values["UnitTestsAgency/someDir/foo"].index, values["UnitTestsAgency/someDir/bar"].index);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test set / get directory
////////////////////////////////////////////////////////////////////////////////