static void discoveryZeroconfWatcher_refreshEndpoints()

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;
}