diff --git a/CMakeLists.txt b/CMakeLists.txt index d48b805..ea8b9e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -337,6 +337,16 @@ add_test(NAME amduatd_graph_contract ) set_tests_properties(amduatd_graph_contract PROPERTIES SKIP_RETURN_CODE 77) +add_test(NAME amduatd_graph_index_append + COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/scripts/test_graph_index_append.sh +) +set_tests_properties(amduatd_graph_index_append PROPERTIES SKIP_RETURN_CODE 77) + +add_test(NAME amduatd_graph_index_append_stress + COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/scripts/test_graph_index_append_stress.sh +) +set_tests_properties(amduatd_graph_index_append_stress PROPERTIES SKIP_RETURN_CODE 77) + add_executable(amduatd_test_space_doctor tests/test_amduatd_space_doctor.c src/amduatd_space_doctor.c diff --git a/src/amduatd_concepts.c b/src/amduatd_concepts.c index bdf0cab..b03178b 100644 --- a/src/amduatd_concepts.c +++ b/src/amduatd_concepts.c @@ -47,6 +47,8 @@ static const char *const AMDUATD_EDGE_COLLECTION = "daemon/edges"; static const uint32_t AMDUATD_EDGE_VIEW_BATCH = 1024u; static const uint32_t AMDUATD_EDGE_REFRESH_BATCH = 512u; static const uint16_t AMDUATD_EDGE_COLLECTION_KIND = 1u; +static const uint32_t AMDUATD_EDGE_APPEND_MAX_ATTEMPTS = 6u; +static const useconds_t AMDUATD_EDGE_APPEND_RETRY_US = 2000u; static bool amduatd_relation_entry_ref(const amduatd_concepts_t *concepts, const char *rel_name, @@ -1930,14 +1932,31 @@ static bool amduatd_concepts_append_edge_record(amduatd_concepts_t *c, } free((void *)payload.data); { - amduat_asl_collection_error_t append_err = - amduat_asl_collection_append(&c->edge_collection, - c->edge_collection_name, - record_ref, - AMDUATD_EDGE_COLLECTION_KIND, - actor, - &offset); + amduat_asl_collection_error_t append_err = AMDUAT_ASL_COLLECTION_ERR_IO; + uint32_t attempt = 0u; + for (attempt = 0u; attempt < AMDUATD_EDGE_APPEND_MAX_ATTEMPTS; ++attempt) { + append_err = amduat_asl_collection_append(&c->edge_collection, + c->edge_collection_name, + record_ref, + AMDUATD_EDGE_COLLECTION_KIND, + actor, + &offset); + if (append_err == AMDUAT_ASL_COLLECTION_OK) { + break; + } + if (append_err != AMDUAT_ASL_COLLECTION_ERR_IO || + attempt + 1u >= AMDUATD_EDGE_APPEND_MAX_ATTEMPTS) { + break; + } + usleep(AMDUATD_EDGE_APPEND_RETRY_US); + } if (append_err != AMDUAT_ASL_COLLECTION_OK) { + amduat_log(AMDUAT_LOG_ERROR, + "edge append context: root=%s pointer_root=%s collection=%s attempts=%u", + c->root_path != NULL ? c->root_path : "?", + c->edge_collection.pointer_store.root_path, + c->edge_collection_name != NULL ? c->edge_collection_name : "?", + (unsigned)(attempt + 1u)); if (c->edge_collection_name != NULL && !amduat_asl_pointer_name_is_valid(c->edge_collection_name)) { amduat_log(AMDUAT_LOG_ERROR, "edge collection name invalid: %s", @@ -1995,10 +2014,11 @@ static bool amduatd_concepts_append_edge_record(amduatd_concepts_t *c, free(log_name); } } - amduat_log(AMDUAT_LOG_ERROR, "edge append failed for %s (err=%d)", + amduat_log(AMDUAT_LOG_ERROR, "edge append failed for %s (err=%d attempts=%u)", c->edge_collection_name != NULL ? c->edge_collection_name : "?", - (int)append_err); + (int)append_err, + (unsigned)(attempt + 1u)); amduat_reference_free(&record_ref); return false; }