* Update the dependency state information of the given checkable and its associated dependency groups in Redis. * * This function serializes the dependency state information of the provided Checkable object and its associated * DependencyGroup into Redis HMSETs and streams the state updates to the runtime state stream. It's intended to * be called by the background worker when processing runti
| 1370 | * @param dependencyGroup The dependency group to process for the given checkable. |
| 1371 | */ |
| 1372 | void IcingaDB::UpdateDependenciesState(const Checkable::Ptr& checkable, const DependencyGroup::Ptr& dependencyGroup) const |
| 1373 | { |
| 1374 | RedisConnection::Queries streamStates; |
| 1375 | auto addDependencyStateToStream([&streamStates](std::string_view redisKey, const Dictionary::Ptr& stateAttrs) { |
| 1376 | RedisConnection::Query xAdd{ |
| 1377 | "XADD", "icinga:runtime:state", "MAXLEN", "~", "1000000", "*", "runtime_type", "upsert", |
| 1378 | "redis_key", redisKey |
| 1379 | }; |
| 1380 | ObjectLock olock(stateAttrs); |
| 1381 | for (auto& [key, value] : stateAttrs) { |
| 1382 | xAdd.emplace_back(key); |
| 1383 | xAdd.emplace_back(IcingaToStreamValue(value)); |
| 1384 | } |
| 1385 | streamStates.emplace_back(std::move(xAdd)); |
| 1386 | }); |
| 1387 | |
| 1388 | std::map<RedisConnection::QueryArg, RedisConnection::Query> hMSets; |
| 1389 | auto dependencies(dependencyGroup->GetDependenciesForChild(checkable.get())); |
| 1390 | std::sort(dependencies.begin(), dependencies.end(), [](const Dependency::Ptr& lhs, const Dependency::Ptr& rhs) { |
| 1391 | return lhs->GetParent() < rhs->GetParent(); |
| 1392 | }); |
| 1393 | for (auto it(dependencies.begin()); it != dependencies.end(); /* no increment */) { |
| 1394 | const auto& dependency(*it); |
| 1395 | |
| 1396 | Dictionary::Ptr stateAttrs; |
| 1397 | // Note: The following loop is intended to cover some possible special cases but may not occur in practice |
| 1398 | // that often. That is, having two or more dependency objects that point to the same parent Checkable. |
| 1399 | // So, traverse all those duplicates and merge their relevant state information into a single edge. |
| 1400 | for (; it != dependencies.end() && (*it)->GetParent() == dependency->GetParent(); ++it) { |
| 1401 | if (!stateAttrs || stateAttrs->Get("failed") == false) { |
| 1402 | stateAttrs = SerializeDependencyEdgeState(dependencyGroup, *it); |
| 1403 | } |
| 1404 | } |
| 1405 | |
| 1406 | addDependencyStateToStream(CONFIG_REDIS_KEY_PREFIX "dependency:edge:state", stateAttrs); |
| 1407 | AddDataToHmSets(hMSets, CONFIG_REDIS_KEY_PREFIX "dependency:edge:state", stateAttrs->Get("id"), stateAttrs); |
| 1408 | } |
| 1409 | |
| 1410 | if (dependencyGroup->IsRedundancyGroup()) { |
| 1411 | Dictionary::Ptr stateAttrs(SerializeRedundancyGroupState(checkable, dependencyGroup)); |
| 1412 | |
| 1413 | Dictionary::Ptr sharedGroupState(stateAttrs->ShallowClone()); |
| 1414 | sharedGroupState->Remove("redundancy_group_id"); |
| 1415 | sharedGroupState->Remove("is_reachable"); |
| 1416 | sharedGroupState->Remove("last_state_change"); |
| 1417 | |
| 1418 | addDependencyStateToStream(CONFIG_REDIS_KEY_PREFIX "redundancygroup:state", stateAttrs); |
| 1419 | addDependencyStateToStream(CONFIG_REDIS_KEY_PREFIX "dependency:edge:state", sharedGroupState); |
| 1420 | AddDataToHmSets(hMSets, CONFIG_REDIS_KEY_PREFIX "redundancygroup:state", dependencyGroup->GetIcingaDBIdentifier(), stateAttrs); |
| 1421 | AddDataToHmSets(hMSets, CONFIG_REDIS_KEY_PREFIX "dependency:edge:state", dependencyGroup->GetIcingaDBIdentifier(), sharedGroupState); |
| 1422 | } |
| 1423 | |
| 1424 | if (!streamStates.empty()) { |
| 1425 | RedisConnection::Queries queries; |
| 1426 | for (auto& [redisKey, query] : hMSets) { |
| 1427 | query.insert(query.begin(), {"HSET", redisKey}); |
| 1428 | queries.emplace_back(std::move(query)); |
| 1429 | } |
nothing calls this directly
no test coverage detected