in bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c [1112:1185]
static void discoveryZeroconfWatcher_refreshEndpoints(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) {
watched_endpoint_entry_t *epEntry = NULL;
watched_service_entry_t *svcEntry = NULL;
unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime;
celix_auto(celix_mutex_lock_guard_t) lockGuard = celixMutexLockGuard_init(&watcher->mutex);
struct timespec now = celix_gettime(CLOCK_MONOTONIC);
//remove the endpoint which ip address list changed and expired endpoint, and mark expired time of the endpoint.
celix_string_hash_map_iterator_t epIter = celix_stringHashMap_begin(watcher->watchedEndpoints);
while (!celix_stringHashMapIterator_isEnd(&epIter)) {
epEntry = (watched_endpoint_entry_t *)epIter.value.ptrValue;
if (discoveryZeroconfWatcher_checkEndpointIpAddressesChanged(watcher, epEntry)
|| celix_compareTime(&now, &epEntry->expiredTime) >= 0) {
celix_logHelper_debug(watcher->logHelper, "Watcher: Remove endpoint for %s on %d.", epEntry->endpoint->serviceName, epEntry->ifIndex);
celix_stringHashMapIterator_remove(&epIter);
discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, false);
endpointEntry_destroy(epEntry);
} else {
if (epEntry->expiredTime.tv_sec == INT_MAX) {
epEntry->expiredTime = celix_gettime(CLOCK_MONOTONIC);
epEntry->expiredTime.tv_sec += DZC_EP_JITTER_INTERVAL;
}
celix_stringHashMapIterator_next(&epIter);
}
}
//add new endpoint
CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) {
svcEntry = (watched_service_entry_t *)iter.value.ptrValue;
if (svcEntry->endpointId != NULL && svcEntry->resolved) {
epEntry = (watched_endpoint_entry_t *)celix_stringHashMap_get(watcher->watchedEndpoints, svcEntry->endpointId);
if (epEntry == NULL && discoveryZeroConfWatcher_isHostResolved(watcher, svcEntry->hostname, svcEntry->ifIndex)) {
celix_status_t status = discoveryZeroConfWatcher_createEndpointEntryForService(watcher, svcEntry, &epEntry);
if (status != CELIX_SUCCESS) {
// If properties invalid,endpointDescription_create will return error.
// Avoid create endpointDescription again, set svcEntry->resolved false.
if (status != CELIX_ENOMEM) {
svcEntry->resolved = false;
} else {
nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds
}
celix_logHelper_error(watcher->logHelper, "Watcher: Failed to create endpoint for %s. %d.", svcEntry->instanceName, status);
continue;
}
celix_logHelper_debug(watcher->logHelper, "Watcher: Add endpoint for %s on %d.", epEntry->endpoint->serviceName, epEntry->ifIndex);
if (celix_stringHashMap_put(watcher->watchedEndpoints, epEntry->endpoint->id, epEntry) == CELIX_SUCCESS) {
discoveryZeroConfWatcher_informEPLs(watcher, epEntry->endpoint, true);
} else {
celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR);
celix_logHelper_error(watcher->logHelper, "Watcher: Failed to add endpoint for %s.", epEntry->endpoint->serviceName);
endpointEntry_destroy(epEntry);
nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds
}
} else if (epEntry != NULL && endpointEntry_matchServiceEntry(epEntry, svcEntry)) {
epEntry->expiredTime.tv_sec = INT_MAX;
epEntry->expiredTime.tv_nsec = 0;
}
}
}
//calculate next work time
CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedEndpoints, iter) {
epEntry = (watched_endpoint_entry_t *)iter.value.ptrValue;
if (epEntry->expiredTime.tv_sec != INT_MAX) {
int timeOut = celix_difftime(&now, &epEntry->expiredTime) + 1;
assert(timeOut >= 0);//We have removed expired endpoint before.
nextWorkIntervalTime = MIN(nextWorkIntervalTime, timeOut);
}
}
*pNextWorkIntervalTime = nextWorkIntervalTime;
return;
}