void TRI_SetProgressReplicationApplier (TRI_replication_applier_t* applier, char const* msg, bool lock) { char* copy; copy = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, msg); if (copy == NULL) { return; } if (lock) { TRI_WriteLockReadWriteLock(&applier->_statusLock); } if (applier->_state._progressMsg != NULL) { TRI_FreeString(TRI_CORE_MEM_ZONE, applier->_state._progressMsg); } applier->_state._progressMsg = copy; // write time in buffer TRI_GetTimeStampReplication(applier->_state._progressTime, sizeof(applier->_state._progressTime) - 1); if (lock) { TRI_WriteUnlockReadWriteLock(&applier->_statusLock); } }
static int StopApplier (TRI_replication_applier_t* applier, bool resetError) { TRI_replication_applier_state_t* state; state = &applier->_state; if (! state->_active) { return TRI_ERROR_INTERNAL; } state->_active = false; SetTerminateFlag(applier, true); TRI_SetProgressReplicationApplier(applier, "applier stopped", false); if (resetError) { if (state->_lastError._msg != NULL) { TRI_FreeString(TRI_CORE_MEM_ZONE, state->_lastError._msg); state->_lastError._msg = NULL; } state->_lastError._code = TRI_ERROR_NO_ERROR; TRI_GetTimeStampReplication(state->_lastError._time, sizeof(state->_lastError._time) - 1); } TRI_LockCondition(&applier->_runStateChangeCondition); TRI_SignalCondition(&applier->_runStateChangeCondition); TRI_UnlockCondition(&applier->_runStateChangeCondition); return TRI_ERROR_NO_ERROR; }
static int SetError (TRI_replication_applier_t* applier, int errorCode, char const* msg) { TRI_replication_applier_state_t* state; char const* realMsg; if (msg == NULL || strlen(msg) == 0) { realMsg = TRI_errno_string(errorCode); } else { realMsg = msg; } // log error message if (errorCode != TRI_ERROR_REPLICATION_APPLIER_STOPPED) { LOG_ERROR("replication applier error for database '%s': %s", applier->_databaseName, realMsg); } state = &applier->_state; state->_lastError._code = errorCode; TRI_GetTimeStampReplication(state->_lastError._time, sizeof(state->_lastError._time) - 1); if (state->_lastError._msg != NULL) { TRI_FreeString(TRI_CORE_MEM_ZONE, state->_lastError._msg); } state->_lastError._msg = TRI_DuplicateStringZ(TRI_CORE_MEM_ZONE, realMsg); return errorCode; }
static int StartApplier (TRI_replication_applier_t* applier, TRI_voc_tick_t initialTick, bool useTick) { TRI_replication_applier_state_t* state; void* fetcher; state = &applier->_state; if (state->_active) { return TRI_ERROR_INTERNAL; } if (applier->_configuration._endpoint == NULL) { return SetError(applier, TRI_ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION, "no endpoint configured"); } if (applier->_configuration._database == NULL) { return SetError(applier, TRI_ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION, "no database configured"); } fetcher = (void*) TRI_CreateContinuousSyncerReplication(applier->_vocbase, &applier->_configuration, initialTick, useTick); if (fetcher == NULL) { return TRI_ERROR_OUT_OF_MEMORY; } // reset error if (state->_lastError._msg != NULL) { TRI_FreeString(TRI_CORE_MEM_ZONE, state->_lastError._msg); state->_lastError._msg = NULL; } state->_lastError._code = TRI_ERROR_NO_ERROR; TRI_GetTimeStampReplication(state->_lastError._time, sizeof(state->_lastError._time) - 1); SetTerminateFlag(applier, false); state->_active = true; TRI_InitThread(&applier->_thread); if (! TRI_StartThread(&applier->_thread, "[applier]", ApplyThread, fetcher)) { TRI_DeleteContinuousSyncerReplication(fetcher); return TRI_ERROR_INTERNAL; } LOG_INFO("started replication applier for database '%s'", applier->_databaseName); return TRI_ERROR_NO_ERROR; }
static int StartApplier (TRI_replication_applier_t* applier, TRI_voc_tick_t initialTick, bool useTick) { TRI_replication_applier_state_t* state = &applier->_state; if (state->_active) { return TRI_ERROR_INTERNAL; } if (applier->_configuration._endpoint == nullptr) { return SetError(applier, TRI_ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION, "no endpoint configured"); } if (applier->_configuration._database == nullptr) { return SetError(applier, TRI_ERROR_REPLICATION_INVALID_APPLIER_CONFIGURATION, "no database configured"); } // TODO: prevent restart of the applier with a tick after a shutdown auto fetcher = new triagens::arango::ContinuousSyncer(applier->_server, applier->_vocbase, &applier->_configuration, initialTick, useTick); if (fetcher == nullptr) { return TRI_ERROR_OUT_OF_MEMORY; } // reset error if (state->_lastError._msg != nullptr) { TRI_FreeString(TRI_CORE_MEM_ZONE, state->_lastError._msg); state->_lastError._msg = nullptr; } state->_lastError._code = TRI_ERROR_NO_ERROR; TRI_GetTimeStampReplication(state->_lastError._time, sizeof(state->_lastError._time) - 1); SetTerminateFlag(applier, false); state->_active = true; TRI_InitThread(&applier->_thread); if (! TRI_StartThread(&applier->_thread, nullptr, "[applier]", ApplyThread, static_cast<void*>(fetcher))) { delete fetcher; return TRI_ERROR_INTERNAL; } LOG_INFO("started replication applier for database '%s'", applier->_databaseName); return TRI_ERROR_NO_ERROR; }
static TRI_json_t* JsonState (TRI_replication_applier_state_t const* state) { TRI_json_t* json; TRI_json_t* last; TRI_json_t* progress; TRI_json_t* error; char* lastString; char timeString[24]; json = TRI_CreateArray2Json(TRI_CORE_MEM_ZONE, 9); // add replication state TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "running", TRI_CreateBooleanJson(TRI_CORE_MEM_ZONE, state->_active)); // lastAppliedContinuousTick if (state->_lastAppliedContinuousTick > 0) { lastString = TRI_StringUInt64(state->_lastAppliedContinuousTick); last = TRI_CreateStringJson(TRI_CORE_MEM_ZONE, lastString); } else { last = TRI_CreateNullJson(TRI_CORE_MEM_ZONE); } TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "lastAppliedContinuousTick", last); // lastProcessedContinuousTick if (state->_lastProcessedContinuousTick > 0) { lastString = TRI_StringUInt64(state->_lastProcessedContinuousTick); last = TRI_CreateStringJson(TRI_CORE_MEM_ZONE, lastString); } else { last = TRI_CreateNullJson(TRI_CORE_MEM_ZONE); } TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "lastProcessedContinuousTick", last); // lastAvailableContinuousTick 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, "lastAvailableContinuousTick", last); // 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, progress, "failedConnects", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) state->_failedConnects)); TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "progress", progress); TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "totalRequests", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) state->_totalRequests)); TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "totalFailedConnects", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) state->_totalFailedConnects)); TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "totalEvents", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) state->_totalEvents)); // lastError error = TRI_CreateArrayJson(TRI_CORE_MEM_ZONE); if (error != NULL) { if (state->_lastError._code > 0) { TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, error, "time", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, state->_lastError._time)); if (state->_lastError._msg != NULL) { TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, error, "errorMessage", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, state->_lastError._msg)); } } TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, error, "errorNum", TRI_CreateNumberJson(TRI_CORE_MEM_ZONE, (double) state->_lastError._code)); TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "lastError", error); } TRI_GetTimeStampReplication(timeString, sizeof(timeString) - 1); TRI_Insert3ArrayJson(TRI_CORE_MEM_ZONE, json, "time", TRI_CreateStringCopyJson(TRI_CORE_MEM_ZONE, timeString)); return json; }