1
0
Fork 0

added timestamps

This commit is contained in:
Jan Steemann 2013-07-17 14:06:40 +02:00
parent 4a4c3d75e4
commit 781514f78d
4 changed files with 268 additions and 97 deletions

View File

@ -86,6 +86,7 @@ ReplicationFetcher::ReplicationFetcher (TRI_vocbase_t* vocbase,
TRI_replication_apply_configuration_t const* configuration,
bool forceFullSynchronisation) :
_vocbase(vocbase),
_applier(vocbase->_replicationApplier),
_configuration(),
_masterInfo(),
_applyState(),
@ -102,7 +103,8 @@ ReplicationFetcher::ReplicationFetcher (TRI_vocbase_t* vocbase,
TRI_CopyApplyConfigurationReplicationApplier(configuration, &_configuration);
TRI_InitMasterInfoReplication(&_masterInfo, configuration->_endpoint);
TRI_InitApplyStateReplicationApplier(&_applyState);
_applyState._trx = 0;
_applyState._externalTid = 0;
_endpoint = Endpoint::clientFactory(_configuration._endpoint);
@ -114,6 +116,21 @@ ReplicationFetcher::ReplicationFetcher (TRI_vocbase_t* vocbase,
if (_connection != 0) {
_client = new SimpleHttpClient(_connection, _configuration._requestTimeout, false);
if (_client != 0) {
string username;
string password;
if (_configuration._username != 0) {
username = string(_configuration._username);
}
if (_configuration._password != 0) {
password = string(_configuration._password);
}
_client->setUserNamePassword("/", username, password);
}
}
}
}
@ -138,7 +155,6 @@ ReplicationFetcher::~ReplicationFetcher () {
delete _endpoint;
}
TRI_DestroyApplyStateReplicationApplier(&_applyState);
TRI_DestroyMasterInfoReplication(&_masterInfo);
TRI_DestroyApplyConfigurationReplicationApplier(&_configuration);
}
@ -170,17 +186,20 @@ int ReplicationFetcher::run () {
int res = getMasterState(errorMsg);
if (res == TRI_ERROR_NO_ERROR) {
TRI_WriteLockReadWriteLock(&_applier->_statusLock);
res = getLocalState(errorMsg);
TRI_WriteUnlockReadWriteLock(&_applier->_statusLock);
}
if (res != TRI_ERROR_NO_ERROR) {
return TRI_SetErrorReplicationApplier(_vocbase->_replicationApplier, res, errorMsg.c_str());
return TRI_SetErrorReplicationApplier(_applier, res, errorMsg.c_str());
}
if (_applyState._lastAppliedInitialTick == 0) {
// we had never sychronised anything
TRI_ReadLockReadWriteLock(&_applier->_statusLock);
if (_applier->_state._lastAppliedInitialTick == 0) {
_forceFullSynchronisation = true;
}
TRI_ReadUnlockReadWriteLock(&_applier->_statusLock);
// TODO:
// if we have synchronised something before, but that point was
@ -192,15 +211,15 @@ int ReplicationFetcher::run () {
res = performInitialSync(errorMsg);
}
if (res != TRI_ERROR_NO_ERROR) {
if (res == TRI_ERROR_NO_ERROR) {
res = performContinuousSync(errorMsg);
}
if (res != TRI_ERROR_NO_ERROR) {
TRI_SetErrorReplicationApplier(_vocbase->_replicationApplier, res, errorMsg.c_str());
TRI_SetErrorReplicationApplier(_applier, res, errorMsg.c_str());
// stop ourselves
TRI_StopReplicationApplier(_vocbase->_replicationApplier);
TRI_StopReplicationApplier(_applier);
return res;
}
@ -250,9 +269,9 @@ int ReplicationFetcher::sortCollections (const void* l, const void* r) {
int ReplicationFetcher::saveApplyState () {
LOGGER_TRACE("saving replication apply state. "
"last applied continuous tick: " << _applyState._lastAppliedContinuousTick);
"last applied continuous tick: " << _applier->_state._lastAppliedContinuousTick);
int res = TRI_SaveStateFileReplicationApplier(_vocbase, &_applyState, false);
int res = TRI_SaveStateFileReplicationApplier(_vocbase, &_applier->_state, false);
if (res != TRI_ERROR_NO_ERROR) {
LOGGER_WARNING("unable to save replication apply state: " << TRI_errno_string(res));
@ -276,7 +295,7 @@ uint64_t ReplicationFetcher::getChunkSize () const {
////////////////////////////////////////////////////////////////////////////////
void ReplicationFetcher::setProgress (char const* msg) {
TRI_SetProgressReplicationApplier(_vocbase->_replicationApplier, msg);
TRI_SetProgressReplicationApplier(_applier, msg, true);
}
////////////////////////////////////////////////////////////////////////////////
@ -284,7 +303,7 @@ void ReplicationFetcher::setProgress (char const* msg) {
////////////////////////////////////////////////////////////////////////////////
void ReplicationFetcher::setPhase (TRI_replication_apply_phase_e phase) {
TRI_SetPhaseReplicationApplier(_vocbase->_replicationApplier, phase);
TRI_SetPhaseReplicationApplier(_applier, phase);
}
////////////////////////////////////////////////////////////////////////////////
@ -1032,14 +1051,16 @@ int ReplicationFetcher::applyLogMarker (TRI_json_t const* json,
if (! tick.empty()) {
TRI_voc_tick_t newTick = (TRI_voc_tick_t) StringUtils::uint64(tick.c_str(), tick.size());
if (newTick > _applyState._lastProcessedContinuousTick) {
_applyState._lastProcessedContinuousTick = newTick;
TRI_WriteLockReadWriteLock(&_applier->_statusLock);
if (newTick > _applier->_state._lastProcessedContinuousTick) {
_applier->_state._lastProcessedContinuousTick = newTick;
}
else {
LOGGER_WARNING("replication marker tick value " << newTick <<
" is lower than last processed tick value " <<
_applyState._lastProcessedContinuousTick);
_applier->_state._lastProcessedContinuousTick);
}
TRI_WriteUnlockReadWriteLock(&_applier->_statusLock);
}
// handle marker type
@ -1171,9 +1192,11 @@ int ReplicationFetcher::applyLog (SimpleHttpResult* response,
if (updateTick) {
// update tick value
if (_applyState._lastProcessedContinuousTick > _applyState._lastAppliedContinuousTick) {
_applyState._lastAppliedContinuousTick = _applyState._lastProcessedContinuousTick;
TRI_WriteLockReadWriteLock(&_applier->_statusLock);
if (_applier->_state._lastProcessedContinuousTick > _applier->_state._lastAppliedContinuousTick) {
_applier->_state._lastAppliedContinuousTick = _applier->_state._lastProcessedContinuousTick;
}
TRI_WriteUnlockReadWriteLock(&_applier->_statusLock);
}
}
}
@ -1185,25 +1208,26 @@ int ReplicationFetcher::applyLog (SimpleHttpResult* response,
int ReplicationFetcher::getLocalState (string& errorMsg) {
int res;
res = TRI_LoadStateFileReplicationApplier(_vocbase, &_applyState);
res = TRI_LoadStateFileReplicationApplier(_vocbase, &_applier->_state);
_applier->_state._active = true;
if (res == TRI_ERROR_FILE_NOT_FOUND) {
// no state file found, so this is the initialisation
_applyState._serverId = _masterInfo._serverId;
_applier->_state._serverId = _masterInfo._serverId;
res = TRI_SaveStateFileReplicationApplier(_vocbase, &_applyState, true);
res = TRI_SaveStateFileReplicationApplier(_vocbase, &_applier->_state, true);
if (res != TRI_ERROR_NO_ERROR) {
errorMsg = "could not save replication state information";
}
}
else if (res == TRI_ERROR_NO_ERROR) {
if (_masterInfo._serverId != _applyState._serverId &&
_applyState._serverId != 0) {
if (_masterInfo._serverId != _applier->_state._serverId &&
_applier->_state._serverId != 0) {
res = TRI_ERROR_REPLICATION_MASTER_CHANGE;
errorMsg = "encountered wrong master id in replication state file. "
"found: " + StringUtils::itoa(_masterInfo._serverId) + ", "
"expected: " + StringUtils::itoa(_applyState._serverId);
"expected: " + StringUtils::itoa(_applier->_state._serverId);
}
}
else {
@ -1410,7 +1434,7 @@ int ReplicationFetcher::performContinuousSync (string& errorMsg) {
// this will make the applier thread sleep if there is nothing to do,
// but will also check for cancellation
if (! TRI_WaitReplicationApplier(_vocbase->_replicationApplier, sleepTime)) {
if (! TRI_WaitReplicationApplier(_applier, sleepTime)) {
return TRI_ERROR_REPLICATION_STOPPED;
}
}
@ -1528,7 +1552,7 @@ int ReplicationFetcher::handleCollectionDump (TRI_transaction_collection_t* trxC
batch++;
// check for cancellation
if (! TRI_WaitReplicationApplier(_vocbase->_replicationApplier, 0)) {
if (! TRI_WaitReplicationApplier(_applier, 0)) {
return TRI_ERROR_REPLICATION_STOPPED;
}
}
@ -1579,7 +1603,7 @@ int ReplicationFetcher::handleCollectionInitial (TRI_json_t const* parameters,
// phase handling
if (phase == PHASE_INIT) {
if (phase == PHASE_VALIDATE) {
// validation phase just returns ok if we got here (aborts above if data is invalid)
return TRI_ERROR_NO_ERROR;
}
@ -1856,7 +1880,7 @@ int ReplicationFetcher::handleInventoryResponse (TRI_json_t const* json,
// ----------------------------------------------------------------------------------
// iterate over all collections from the master...
res = iterateCollections(collections, errorMsg, PHASE_INIT);
res = iterateCollections(collections, errorMsg, PHASE_VALIDATE);
if (res != TRI_ERROR_NO_ERROR) {
return res;
@ -1898,8 +1922,11 @@ int ReplicationFetcher::handleInventoryResponse (TRI_json_t const* json,
return res;
}
_applyState._lastAppliedInitialTick = _masterInfo._state._lastLogTick;
res = TRI_SaveStateFileReplicationApplier(_vocbase, &_applyState, true);
TRI_WriteLockReadWriteLock(&_applier->_statusLock);
_applier->_state._lastAppliedInitialTick = _masterInfo._state._lastLogTick;
res = TRI_SaveStateFileReplicationApplier(_vocbase, &_applier->_state, true);
TRI_WriteUnlockReadWriteLock(&_applier->_statusLock);
if (res != TRI_ERROR_NO_ERROR) {
errorMsg = "could not save replication state information";
@ -1949,7 +1976,7 @@ int ReplicationFetcher::iterateCollections (TRI_json_t const* collections,
}
// check for cancellation
if (! TRI_WaitReplicationApplier(_vocbase->_replicationApplier, 0)) {
if (! TRI_WaitReplicationApplier(_applier, 0)) {
return TRI_ERROR_REPLICATION_STOPPED;
}
}
@ -1974,12 +2001,15 @@ int ReplicationFetcher::followMasterLog (string& errorMsg,
// ---------------------------------------
// use tick from initial dump
TRI_voc_tick_t fromTick = _applyState._lastAppliedInitialTick;
TRI_ReadLockReadWriteLock(&_applier->_statusLock);
TRI_voc_tick_t fromTick = _applier->_state._lastAppliedInitialTick;
// if we already transferred some data, we'll use the last applied tick
if (_applyState._lastAppliedContinuousTick > fromTick) {
fromTick = _applyState._lastAppliedContinuousTick;
if (_applier->_state._lastAppliedContinuousTick > fromTick) {
fromTick = _applier->_state._lastAppliedContinuousTick;
}
TRI_ReadUnlockReadWriteLock(&_applier->_statusLock);
LOGGER_TRACE("starting continuous replication with tick " << fromTick);
@ -2053,7 +2083,10 @@ int ReplicationFetcher::followMasterLog (string& errorMsg,
header = response->getHeaderField(TRI_REPLICATION_HEADER_LASTTICK, found);
if (found) {
tick = StringUtils::uint64(header);
_applyState._lastAvailableContinuousTick = tick;
TRI_WriteLockReadWriteLock(&_applier->_statusLock);
_applier->_state._lastAvailableContinuousTick = tick;
TRI_WriteUnlockReadWriteLock(&_applier->_statusLock);
}
}
}
@ -2066,13 +2099,17 @@ int ReplicationFetcher::followMasterLog (string& errorMsg,
if (res == TRI_ERROR_NO_ERROR) {
TRI_voc_tick_t lastAppliedTick = _applyState._lastAppliedContinuousTick;
TRI_ReadLockReadWriteLock(&_applier->_statusLock);
TRI_voc_tick_t lastAppliedTick = _applier->_state._lastAppliedContinuousTick;
TRI_ReadUnlockReadWriteLock(&_applier->_statusLock);
res = applyLog(response, errorMsg, ignoreCount);
if (_applyState._lastAppliedContinuousTick != lastAppliedTick) {
TRI_WriteLockReadWriteLock(&_applier->_statusLock);
if (_applier->_state._lastAppliedContinuousTick != lastAppliedTick) {
saveApplyState();
}
TRI_WriteUnlockReadWriteLock(&_applier->_statusLock);
}
delete response;

View File

@ -41,6 +41,7 @@
// -----------------------------------------------------------------------------
struct TRI_json_s;
struct TRI_replication_applier_s;
struct TRI_replication_apply_configuration_s;
struct TRI_transaction_collection_s;
struct TRI_vocbase_s;
@ -357,6 +358,12 @@ namespace triagens {
struct TRI_vocbase_s* _vocbase;
////////////////////////////////////////////////////////////////////////////////
/// @brief pointer to the apply state
////////////////////////////////////////////////////////////////////////////////
struct TRI_replication_applier_s* _applier;
////////////////////////////////////////////////////////////////////////////////
/// @brief apply configuration;
////////////////////////////////////////////////////////////////////////////////
@ -373,7 +380,11 @@ namespace triagens {
/// @brief information about the local apply state
////////////////////////////////////////////////////////////////////////////////
TRI_replication_apply_state_t _applyState;
struct {
struct TRI_transaction_s* _trx;
TRI_voc_tid_t _externalTid;
}
_applyState;
////////////////////////////////////////////////////////////////////////////////
/// @brief whether or not a full sync was requested

View File

@ -56,6 +56,18 @@
/// @{
////////////////////////////////////////////////////////////////////////////////
static void GetTime (char* dst,
size_t maxSize) {
time_t tt;
struct tm tb;
tt = time(0);
TRI_gmtime(tt, &tb);
strftime(dst, maxSize - 1, "%Y-%m-%dT%H:%M:%SZ", &tb);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief set flag to terminate the apply start
////////////////////////////////////////////////////////////////////////////////
@ -90,6 +102,8 @@ static const char* StringifyPhase (TRI_replication_apply_phase_e phase) {
case PHASE_NONE:
return "not running";
case PHASE_INIT:
return "initialising";
case PHASE_VALIDATE:
return "initial dump - validating";
case PHASE_DROP:
return "initial dump - dropping collections";
@ -156,6 +170,13 @@ static TRI_json_t* JsonApplyConfiguration (TRI_replication_apply_configuration_t
"endpoint",
TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, config->_endpoint));
if (config->_username != NULL) {
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE,
json,
"username",
TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, config->_username));
}
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE,
json,
"requestTimeout",
@ -252,7 +273,7 @@ static int SetError (TRI_replication_applier_t* applier,
TRI_replication_apply_state_t* state;
char const* realMsg;
if (msg == NULL) {
if (msg == NULL || strlen(msg) == 0) {
realMsg = TRI_errno_string(errorCode);
}
else {
@ -260,12 +281,14 @@ static int SetError (TRI_replication_applier_t* applier,
}
// log error message
if (errorCode != TRI_ERROR_REPLICATION_NO_RESPONSE) {
if (errorCode != TRI_ERROR_REPLICATION_NO_RESPONSE &&
errorCode != TRI_ERROR_REPLICATION_STOPPED) {
LOG_WARNING("replication error: %s", realMsg);
}
state = &applier->_state;
state->_lastError._code = errorCode;
GetTime(state->_lastError._time, sizeof(state->_lastError._time));
if (state->_lastError._msg != NULL) {
TRI_FreeString(TRI_CORE_MEM_ZONE, state->_lastError._msg);
@ -281,9 +304,8 @@ static int SetError (TRI_replication_applier_t* applier,
////////////////////////////////////////////////////////////////////////////////
void ApplyThread (void* data) {
TRI_replication_applier_t* applier = (TRI_replication_applier_t*) data;
TRI_RunFetcherReplication(applier->_fetcher);
TRI_RunFetcherReplication(data);
TRI_DeleteFetcherReplication(data);
}
////////////////////////////////////////////////////////////////////////////////
@ -294,6 +316,7 @@ void ApplyThread (void* data) {
static int StartApplier (TRI_replication_applier_t* applier,
bool fullSync) {
TRI_replication_apply_state_t* state;
void* fetcher;
state = &applier->_state;
@ -305,25 +328,45 @@ static int StartApplier (TRI_replication_applier_t* applier,
return SetError(applier, TRI_ERROR_REPLICATION_INVALID_CONFIGURATION, "no endpoint configured");
}
assert(applier->_fetcher == NULL);
if (fullSync) {
state->_lastProcessedContinuousTick = 0;
state->_lastAppliedContinuousTick = 0;
state->_lastAvailableContinuousTick = 0;
state->_lastAppliedInitialTick = 0;
state->_lastError._code = 0;
state->_lastError._time[0] = '\0';
applier->_fetcher = (void*) TRI_CreateFetcherReplication(applier->_vocbase, &applier->_configuration, fullSync);
if (state->_lastError._msg != NULL) {
TRI_FreeString(TRI_CORE_MEM_ZONE, state->_lastError._msg);
}
state->_lastError._msg = NULL;
if (applier->_fetcher == NULL) {
return TRI_ERROR_OUT_OF_MEMORY;
if (state->_progressMsg != NULL) {
TRI_FreeString(TRI_CORE_MEM_ZONE, state->_progressMsg);
}
state->_progressMsg = NULL;
state->_progressTime[0] = '\0';
}
assert(applier->_fetcher != NULL);
fetcher = (void*) TRI_CreateFetcherReplication(applier->_vocbase, &applier->_configuration, fullSync);
if (fetcher == NULL) {
return TRI_ERROR_OUT_OF_MEMORY;
}
SetTerminateFlag(applier, false);
state->_active = true;
TRI_InitThread(&applier->_thread);
if (! TRI_StartThread(&applier->_thread, "[applier]", ApplyThread, applier)) {
if (! TRI_StartThread(&applier->_thread, "[applier]", ApplyThread, fetcher)) {
TRI_DeleteFetcherReplication(fetcher);
return TRI_ERROR_INTERNAL;
}
applier->_state._phase = PHASE_INIT;
LOG_INFO("started replication applier for database '%s'",
applier->_databaseName);
@ -350,11 +393,7 @@ static int StopApplier (TRI_replication_applier_t* applier) {
state->_phase = PHASE_NONE;
if (state->_progress != NULL) {
TRI_FreeString(TRI_CORE_MEM_ZONE, state->_progress);
}
state->_progress = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, "applier stopped");
TRI_SetProgressReplicationApplier(applier, "applier stopped", false);
if (state->_lastError._msg != NULL) {
TRI_FreeString(TRI_CORE_MEM_ZONE, state->_lastError._msg);
@ -362,6 +401,7 @@ static int StopApplier (TRI_replication_applier_t* applier) {
}
state->_lastError._code = TRI_ERROR_NO_ERROR;
GetTime(state->_lastError._time, sizeof(state->_lastError._time));
TRI_LockCondition(&applier->_runStateChangeCondition);
TRI_SignalCondition(&applier->_runStateChangeCondition);
@ -429,7 +469,6 @@ TRI_replication_applier_t* TRI_CreateReplicationApplier (TRI_vocbase_t* vocbase)
TRI_InitCondition(&applier->_runStateChangeCondition);
applier->_vocbase = vocbase;
applier->_fetcher = NULL;
applier->_databaseName = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, vocbase->_name);
SetTerminateFlag(applier, false);
@ -509,6 +548,7 @@ int TRI_StartReplicationApplier (TRI_replication_applier_t* applier,
LOG_TRACE("requesting replication applier start. fullSync: %d", (int) fullSync);
// wait until previous apply thread is shut down
while (! TRI_WaitReplicationApplier(applier, 10 * 1000));
TRI_WriteLockReadWriteLock(&applier->_statusLock);
@ -547,9 +587,6 @@ int TRI_StopReplicationApplier (TRI_replication_applier_t* applier) {
// join the thread without the status lock (otherwise it would propbably not join)
TRI_JoinThread(&applier->_thread);
assert(applier->_fetcher != NULL);
TRI_DeleteFetcherReplication(applier->_fetcher);
applier->_fetcher = NULL;
SetTerminateFlag(applier, false);
@ -602,18 +639,29 @@ int TRI_StateReplicationApplier (TRI_replication_applier_t* applier,
state->_active = applier->_state._active;
state->_lastAppliedContinuousTick = applier->_state._lastAppliedContinuousTick;
state->_lastProcessedContinuousTick = applier->_state._lastProcessedContinuousTick;
state->_lastAvailableContinuousTick = applier->_state._lastAvailableContinuousTick;
state->_lastAppliedInitialTick = applier->_state._lastAppliedInitialTick;
state->_serverId = applier->_state._serverId;
state->_phase = applier->_state._phase;
state->_lastError._code = applier->_state._lastError._code;
memcpy(&state->_lastError._time, &applier->_state._lastError._time, sizeof(state->_lastError._time));
if (applier->_state._progress != NULL) {
state->_progress = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, applier->_state._progress);
if (applier->_state._progressMsg != NULL) {
state->_progressMsg = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, applier->_state._progressMsg);
}
else {
state->_progressMsg = NULL;
}
memcpy(&state->_progressTime, &applier->_state._progressTime, sizeof(state->_progressTime));
if (applier->_state._lastError._msg != NULL) {
state->_lastError._msg = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, applier->_state._lastError._msg);
}
else {
state->_lastError._msg = NULL;
}
TRI_ReadUnlockReadWriteLock(&applier->_statusLock);
@ -628,16 +676,17 @@ TRI_json_t* TRI_JsonStateReplicationApplier (TRI_replication_apply_state_t const
TRI_json_t* json;
TRI_json_t* last;
TRI_json_t* phase;
TRI_json_t* progress;
TRI_json_t* error;
char* lastString;
json = TRI_CreateArray2Json(TRI_CORE_MEM_ZONE, 6);
json = TRI_CreateArray2Json(TRI_CORE_MEM_ZONE, 8);
// add replication state
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "running", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, state->_active));
// lastAppliedContinuousTick
if (state->_lastAppliedContinuousTick == 0) {
if (state->_lastAppliedContinuousTick > 0) {
lastString = TRI_StringUInt64(state->_lastAppliedContinuousTick);
last = TRI_CreateStringJson(TRI_CORE_MEM_ZONE, lastString);
}
@ -647,7 +696,7 @@ TRI_json_t* TRI_JsonStateReplicationApplier (TRI_replication_apply_state_t const
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "lastAppliedContinuousTick", last);
// lastProcessedContinuousTick
if (state->_lastProcessedContinuousTick == 0) {
if (state->_lastProcessedContinuousTick > 0) {
lastString = TRI_StringUInt64(state->_lastProcessedContinuousTick);
last = TRI_CreateStringJson(TRI_CORE_MEM_ZONE, lastString);
}
@ -657,17 +706,17 @@ TRI_json_t* TRI_JsonStateReplicationApplier (TRI_replication_apply_state_t const
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "lastProcessedContinuousTick", last);
// lastAvailableContinuousTick
if (state->_lastAvailableContinuousTick == 0) {
if (state->_lastAvailableContinuousTick > 0) {
lastString = TRI_StringUInt64(state->_lastAvailableContinuousTick);
last = TRI_CreateStringJson(TRI_CORE_MEM_ZONE, lastString);
}
else {
last = TRI_CreateNullJson(TRI_CORE_MEM_ZONE);
}
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "lastAvaiableContinuousTick", last);
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "lastAvailableContinuousTick", last);
// lastAppliedInitialTick
if (state->_lastAppliedInitialTick == 0) {
if (state->_lastAppliedInitialTick > 0) {
lastString = TRI_StringUInt64(state->_lastAppliedInitialTick);
last = TRI_CreateStringJson(TRI_CORE_MEM_ZONE, lastString);
}
@ -683,11 +732,18 @@ TRI_json_t* TRI_JsonStateReplicationApplier (TRI_replication_apply_state_t const
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, phase, "label", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, StringifyPhase(state->_phase)));
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "currentPhase", phase);
if (state->_progress != NULL) {
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "progress", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, state->_progress));
}
// progress
progress = TRI_CreateArray2Json(TRI_CORE_MEM_ZONE, 2);
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, progress, "time", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, state->_progressTime));
if (state->_progressMsg != NULL) {
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, progress, "message", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, state->_progressMsg));
}
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "progress", progress);
// lastError
error = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE);
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, error, "time", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, state->_lastError._time));
TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, error, "errorNum", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) state->_lastError._code));
if (state->_lastError._msg != NULL) {
@ -729,25 +785,39 @@ void TRI_SetPhaseReplicationApplier (TRI_replication_applier_t* applier,
}
////////////////////////////////////////////////////////////////////////////////
/// @brief set the progress
/// @brief set the progress with or without a lock
////////////////////////////////////////////////////////////////////////////////
void TRI_SetProgressReplicationApplier (TRI_replication_applier_t* applier,
char const* msg) {
char* copy = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, msg);
char const* msg,
bool lock) {
char* copy;
char timeString[24];
copy = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, msg);
if (copy == NULL) {
return;
}
GetTime(timeString, sizeof(timeString));
if (lock) {
TRI_WriteLockReadWriteLock(&applier->_statusLock);
if (applier->_state._progress != NULL) {
TRI_FreeString(TRI_CORE_MEM_ZONE, applier->_state._progress);
}
applier->_state._progress = copy;
if (applier->_state._progressMsg != NULL) {
TRI_FreeString(TRI_CORE_MEM_ZONE, applier->_state._progressMsg);
}
applier->_state._progressMsg = copy;
// write time in buffer
memcpy(&applier->_state._progressTime, &timeString, sizeof(applier->_state._progressTime));
if (lock) {
TRI_WriteUnlockReadWriteLock(&applier->_statusLock);
}
}
////////////////////////////////////////////////////////////////////////////////
@ -758,8 +828,11 @@ void TRI_InitApplyStateReplicationApplier (TRI_replication_apply_state_t* state)
memset(state, 0, sizeof(TRI_replication_apply_state_t));
state->_active = false;
state->_lastError._code = TRI_ERROR_NO_ERROR;
state->_phase = PHASE_NONE;
state->_lastError._code = TRI_ERROR_NO_ERROR;
state->_lastError._msg = NULL;
state->_lastError._time[0] = '\0';
}
////////////////////////////////////////////////////////////////////////////////
@ -767,8 +840,8 @@ void TRI_InitApplyStateReplicationApplier (TRI_replication_apply_state_t* state)
////////////////////////////////////////////////////////////////////////////////
void TRI_DestroyApplyStateReplicationApplier (TRI_replication_apply_state_t* state) {
if (state->_progress != NULL) {
TRI_FreeString(TRI_CORE_MEM_ZONE, state->_progress);
if (state->_progressMsg != NULL) {
TRI_FreeString(TRI_CORE_MEM_ZONE, state->_progressMsg);
}
if (state->_lastError._msg != NULL) {
@ -908,6 +981,9 @@ int TRI_LoadStateFileReplicationApplier (TRI_vocbase_t* vocbase,
void TRI_InitApplyConfigurationReplicationApplier (TRI_replication_apply_configuration_t* config) {
memset(config, 0, sizeof(TRI_replication_apply_configuration_t));
config->_endpoint = NULL;
config->_username = NULL;
config->_password = NULL;
config->_requestTimeout = 300.0;
config->_connectTimeout = 10.0;
config->_maxConnectRetries = 10;
@ -924,6 +1000,16 @@ void TRI_DestroyApplyConfigurationReplicationApplier (TRI_replication_apply_conf
TRI_FreeString(TRI_CORE_MEM_ZONE, config->_endpoint);
config->_endpoint = NULL;
}
if (config->_username != NULL) {
TRI_FreeString(TRI_CORE_MEM_ZONE, config->_username);
config->_username = NULL;
}
if (config->_password != NULL) {
TRI_FreeString(TRI_CORE_MEM_ZONE, config->_password);
config->_password = NULL;
}
}
////////////////////////////////////////////////////////////////////////////////
@ -932,7 +1018,24 @@ void TRI_DestroyApplyConfigurationReplicationApplier (TRI_replication_apply_conf
void TRI_CopyApplyConfigurationReplicationApplier (TRI_replication_apply_configuration_t const* src,
TRI_replication_apply_configuration_t* dst) {
assert(src->_endpoint != NULL);
dst->_endpoint = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, src->_endpoint);
if (src->_username != NULL) {
dst->_username = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, src->_username);
}
else {
dst->_username = NULL;
}
if (src->_password != NULL) {
dst->_password = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, src->_password);
}
else {
dst->_password = NULL;
}
dst->_requestTimeout = src->_requestTimeout;
dst->_connectTimeout = src->_connectTimeout;
dst->_ignoreErrors = src->_ignoreErrors;
@ -1033,7 +1136,7 @@ int TRI_LoadConfigurationFileReplicationApplier (TRI_vocbase_t* vocbase,
res = TRI_ERROR_NO_ERROR;
// read the server id
// read the endpoint
value = TRI_LookupArrayJson(json, "endpoint");
if (! TRI_IsStringJson(value)) {
@ -1045,6 +1148,23 @@ int TRI_LoadConfigurationFileReplicationApplier (TRI_vocbase_t* vocbase,
value->_value._string.length - 1);
}
// read username / password
value = TRI_LookupArrayJson(json, "username");
if (TRI_IsStringJson(value)) {
config->_username = TRI_DuplicateString2Z(TRI_CORE_MEM_ZONE,
value->_value._string.data,
value->_value._string.length - 1);
}
value = TRI_LookupArrayJson(json, "password");
if (TRI_IsStringJson(value)) {
config->_password = TRI_DuplicateString2Z(TRI_CORE_MEM_ZONE,
value->_value._string.data,
value->_value._string.length - 1);
}
value = TRI_LookupArrayJson(json, "requestTimeout");
if (TRI_IsNumberJson(value)) {

View File

@ -68,6 +68,7 @@ struct TRI_vocbase_s;
typedef enum {
PHASE_NONE,
PHASE_INIT,
PHASE_VALIDATE,
PHASE_DROP,
PHASE_CREATE,
PHASE_DUMP,
@ -81,6 +82,8 @@ TRI_replication_apply_phase_e;
typedef struct TRI_replication_apply_configuration_s {
char* _endpoint;
char* _username;
char* _password;
double _requestTimeout;
double _connectTimeout;
uint64_t _ignoreErrors;
@ -97,6 +100,7 @@ TRI_replication_apply_configuration_t;
typedef struct TRI_replication_apply_error_s {
int _code;
char* _msg;
char _time[24];
}
TRI_replication_apply_error_t;
@ -105,14 +109,13 @@ TRI_replication_apply_error_t;
////////////////////////////////////////////////////////////////////////////////
typedef struct TRI_replication_apply_state_s {
struct TRI_transaction_s* _trx;
TRI_voc_tid_t _externalTid;
TRI_voc_tick_t _lastProcessedContinuousTick;
TRI_voc_tick_t _lastAppliedContinuousTick;
TRI_voc_tick_t _lastAvailableContinuousTick;
bool _active;
TRI_replication_apply_phase_e _phase;
char* _progress;
char* _progressMsg;
char _progressTime[24];
TRI_voc_tick_t _lastAppliedInitialTick;
TRI_server_id_t _serverId;
TRI_replication_apply_error_t _lastError;
@ -133,7 +136,6 @@ typedef struct TRI_replication_applier_s {
TRI_replication_apply_configuration_t _configuration;
char* _databaseName;
TRI_thread_t _thread;
void* _fetcher;
}
TRI_replication_applier_t;
@ -237,11 +239,12 @@ void TRI_SetPhaseReplicationApplier (TRI_replication_applier_t*,
TRI_replication_apply_phase_e);
////////////////////////////////////////////////////////////////////////////////
/// @brief set the progress
/// @brief set the progress with or without a lock
////////////////////////////////////////////////////////////////////////////////
void TRI_SetProgressReplicationApplier (TRI_replication_applier_t*,
char const*);
char const*,
bool);
////////////////////////////////////////////////////////////////////////////////
/// @brief initialise an apply state struct