Search in sources :

Example 1 with WatchExpiredException

use of io.kubernetes.client.informer.exception.WatchExpiredException in project java by kubernetes-client.

the class ReflectorRunnable method run.

/**
 * run first lists all items and get the resource version at the moment of call, and then use the
 * resource version to watch.
 */
public void run() {
    log.info("{}#Start listing and watching...", apiTypeClass);
    try {
        ApiListType list = listerWatcher.list(new CallGeneratorParams(Boolean.FALSE, getRelistResourceVersion(), null));
        V1ListMeta listMeta = list.getMetadata();
        String resourceVersion = listMeta.getResourceVersion();
        List<? extends KubernetesObject> items = list.getItems();
        if (log.isDebugEnabled()) {
            log.debug("{}#Extract resourceVersion {} list meta", apiTypeClass, resourceVersion);
        }
        this.syncWith(items, resourceVersion);
        this.lastSyncResourceVersion = resourceVersion;
        this.isLastSyncResourceVersionUnavailable = false;
        if (log.isDebugEnabled()) {
            log.debug("{}#Start watching with {}...", apiTypeClass, lastSyncResourceVersion);
        }
        while (true) {
            if (!isActive.get()) {
                closeWatch();
                return;
            }
            try {
                if (log.isDebugEnabled()) {
                    log.debug("{}#Start watch with resource version {}", apiTypeClass, lastSyncResourceVersion);
                }
                long jitteredWatchTimeoutSeconds = Double.valueOf(REFLECTOR_WATCH_CLIENTSIDE_TIMEOUT.getSeconds() * (1 + Math.random())).longValue();
                Watchable<ApiType> newWatch = listerWatcher.watch(new CallGeneratorParams(Boolean.TRUE, lastSyncResourceVersion, Long.valueOf(jitteredWatchTimeoutSeconds).intValue()));
                synchronized (this) {
                    if (!isActive.get()) {
                        newWatch.close();
                        continue;
                    }
                    watch = newWatch;
                }
                watchHandler(newWatch);
            } catch (WatchExpiredException e) {
                // Watch calls were failed due to expired resource-version. Returning
                // to unwind the list-watch loops so that we can respawn a new round
                // of list-watching.
                log.info("{}#Watch expired, will re-list-watch soon", this.apiTypeClass);
                return;
            } catch (Throwable t) {
                if (isConnectException(t)) {
                    // If this is "connection refused" error, it means that most likely
                    // apiserver is not responsive. It doesn't make sense to re-list all
                    // objects because most likely we will be able to restart watch where
                    // we ended. If that's the case wait and resend watch request.
                    log.info("{}#Watch get connect exception, retry watch", this.apiTypeClass);
                    try {
                        Thread.sleep(1000L);
                    } catch (InterruptedException e) {
                    // no-op
                    }
                    continue;
                }
                if ((t instanceof RuntimeException) && t.getMessage() != null && t.getMessage().contains("IO Exception during hasNext")) {
                    log.info("{}#Read timeout retry list and watch", this.apiTypeClass);
                    // IO timeout should be taken as a normal case
                    return;
                }
                this.exceptionHandler.accept(apiTypeClass, t);
                return;
            } finally {
                closeWatch();
            }
        }
    } catch (ApiException e) {
        if (e.getCode() == HttpURLConnection.HTTP_GONE) {
            log.info("ResourceVersion {} expired, will retry w/o resourceVersion at the next time", getRelistResourceVersion());
            isLastSyncResourceVersionUnavailable = true;
        } else {
            this.exceptionHandler.accept(apiTypeClass, e);
        }
    } catch (Throwable t) {
        this.exceptionHandler.accept(apiTypeClass, t);
    }
}
Also used : CallGeneratorParams(io.kubernetes.client.util.CallGeneratorParams) V1ListMeta(io.kubernetes.client.openapi.models.V1ListMeta) WatchExpiredException(io.kubernetes.client.informer.exception.WatchExpiredException) ApiException(io.kubernetes.client.openapi.ApiException)

Example 2 with WatchExpiredException

use of io.kubernetes.client.informer.exception.WatchExpiredException in project java by kubernetes-client.

the class ReflectorRunnable method watchHandler.

private void watchHandler(Watchable<ApiType> watch) {
    while (watch.hasNext()) {
        io.kubernetes.client.util.Watch.Response<ApiType> item = watch.next();
        Optional<EventType> eventType = EventType.findByType(item.type);
        if (!eventType.isPresent()) {
            log.error("unrecognized event {}", item);
            continue;
        }
        if (eventType.get() == EventType.ERROR) {
            if (item.status != null && item.status.getCode() == HttpURLConnection.HTTP_GONE) {
                log.info("ResourceVersion {} and Watch connection expired: {} , will retry w/o resourceVersion next time", getRelistResourceVersion(), item.status.getMessage());
                isLastSyncResourceVersionUnavailable = true;
                throw new WatchExpiredException();
            } else {
                String errorMessage = String.format("got ERROR event and its status: %s", item.status.toString());
                log.error(errorMessage);
                throw new RuntimeException(errorMessage);
            }
        }
        ApiType obj = item.object;
        V1ObjectMeta meta = obj.getMetadata();
        String newResourceVersion = meta.getResourceVersion();
        switch(eventType.get()) {
            case ADDED:
                store.add(obj);
                break;
            case MODIFIED:
                store.update(obj);
                break;
            case DELETED:
                store.delete(obj);
                break;
            case BOOKMARK:
                break;
        }
        lastSyncResourceVersion = newResourceVersion;
        if (log.isDebugEnabled()) {
            log.debug("{}#Receiving resourceVersion {}", apiTypeClass, lastSyncResourceVersion);
        }
    }
}
Also used : EventType(io.kubernetes.client.informer.EventType) V1ObjectMeta(io.kubernetes.client.openapi.models.V1ObjectMeta) WatchExpiredException(io.kubernetes.client.informer.exception.WatchExpiredException)

Aggregations

WatchExpiredException (io.kubernetes.client.informer.exception.WatchExpiredException)2 EventType (io.kubernetes.client.informer.EventType)1 ApiException (io.kubernetes.client.openapi.ApiException)1 V1ListMeta (io.kubernetes.client.openapi.models.V1ListMeta)1 V1ObjectMeta (io.kubernetes.client.openapi.models.V1ObjectMeta)1 CallGeneratorParams (io.kubernetes.client.util.CallGeneratorParams)1