Search in sources :

Example 1 with Request

use of io.kubernetes.client.extended.controller.reconciler.Request in project java by kubernetes-client.

the class DefaultController method worker.

private void worker() {
    // taking tasks from work-queue in a loop
    while (!workQueue.isShuttingDown()) {
        gaugeWorkQueueLength.labels(name).set(workQueue.length());
        Request request = null;
        try {
            request = workQueue.get();
        } catch (InterruptedException e) {
            // we're reaching here mostly because of forcibly shutting down the controller.
            log.error("Controller worker interrupted.. keeps working until work-queue shutdown", e);
            if (request != null) {
                workQueue.addRateLimited(request);
            }
        }
        // request is expected to be null, when the work-queue is shutting-down.
        if (request == null) {
            log.info("Controller {} worker exiting because work-queue has shutdown..", this.name);
            return;
        }
        log.debug("Controller {} start reconciling {}..", this.name, request);
        // do reconciliation, invoke user customized logic.
        Result result = null;
        try {
            result = this.reconciler.reconcile(request);
        } catch (Throwable t) {
            log.error("Reconciler aborted unexpectedly", t);
            result = new Result(true);
        } finally {
            counterControllerReconcile.labels(this.name, Boolean.toString(result.isRequeue())).inc();
        }
        try {
            // checks whether do a re-queue (on failure)
            if (result.isRequeue()) {
                if (result.getRequeueAfter() == null) {
                    log.debug("Controller {} reconciling {} failed, requeuing {}..", this.name, request);
                    workQueue.addRateLimited(request);
                } else {
                    log.debug("Controller {} reconciling {} failed, requeuing after {}..", this.name, request, result.getRequeueAfter());
                    workQueue.addAfter(request, result.getRequeueAfter());
                }
            } else {
                workQueue.forget(request);
            }
        } finally {
            workQueue.done(request);
            gaugeWorkQueueLength.labels(name).set(workQueue.length());
            log.debug("Controller {} finished reconciling {}..", this.name, request);
        }
    }
}
Also used : Request(io.kubernetes.client.extended.controller.reconciler.Request) Result(io.kubernetes.client.extended.controller.reconciler.Result)

Example 2 with Request

use of io.kubernetes.client.extended.controller.reconciler.Request in project java by kubernetes-client.

the class DefaultControllerTest method testStartingStoppingController.

@Test(timeout = 90000)
public void testStartingStoppingController() throws InterruptedException {
    DefaultController testController = new DefaultController("", mockReconciler, workQueue);
    testController.setWorkerCount(1);
    testController.setWorkerThreadPool(Executors.newScheduledThreadPool(1));
    Request request1 = new Request("test1");
    final Semaphore latch = new Semaphore(1);
    latch.acquire();
    when(mockReconciler.reconcile(request1)).thenAnswer(new Answer() {

        public Object answer(InvocationOnMock invocation) {
            latch.release();
            return new Result(false);
        }
    });
    // emit an event when the controller hasn't started
    workQueue.add(request1);
    // I don't love sleeping here, but we're waiting for something we don't expect
    // to happen, so there's no good way to do it other than sleep (that I can think of)
    cooldown();
    verify(mockReconciler, times(0)).reconcile(request1);
    controllerThead.submit(testController::run);
    latch.acquire();
    verify(mockReconciler, times(1)).reconcile(request1);
    testController.shutdown();
    Request request2 = new Request("test2");
    // emit an event after the controller has shutdown
    workQueue.add(request2);
    // as above wrt sleep
    cooldown();
    verify(mockReconciler, times(0)).reconcile(request2);
}
Also used : Answer(org.mockito.stubbing.Answer) InvocationOnMock(org.mockito.invocation.InvocationOnMock) Request(io.kubernetes.client.extended.controller.reconciler.Request) Semaphore(java.util.concurrent.Semaphore) Result(io.kubernetes.client.extended.controller.reconciler.Result) Test(org.junit.Test)

Example 3 with Request

use of io.kubernetes.client.extended.controller.reconciler.Request in project java by kubernetes-client.

the class DefaultControllerTest method testControllerKeepsWorkingWhenReconcilerAbortsWithRuntimeException.

@Test(timeout = 90000)
public void testControllerKeepsWorkingWhenReconcilerAbortsWithRuntimeException() throws InterruptedException {
    AtomicBoolean aborts = new AtomicBoolean(true);
    AtomicBoolean resumed = new AtomicBoolean(false);
    List<Request> finishedRequests = new ArrayList<>();
    final Semaphore latch = new Semaphore(1);
    DefaultController testController = new DefaultController("", new Reconciler() {

        @Override
        public Result reconcile(Request request) {
            try {
                if (aborts.get()) {
                    throw new RuntimeException("Oops!!");
                }
                resumed.set(true);
                finishedRequests.add(request);
                return new Result(false);
            } finally {
                latch.release();
            }
        }
    }, workQueue);
    testController.setWorkerCount(1);
    testController.setWorkerThreadPool(Executors.newScheduledThreadPool(1));
    controllerThead.submit(testController::run);
    Request request1 = new Request("test1");
    workQueue.add(request1);
    latch.acquire();
    aborts.set(false);
    // emit another event, the previous one has been backoff'd
    Request request2 = new Request("test2");
    workQueue.add(request2);
    latch.acquire();
    testController.shutdown();
    assertTrue(resumed.get());
    assertTrue(finishedRequests.size() >= 1);
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Reconciler(io.kubernetes.client.extended.controller.reconciler.Reconciler) Request(io.kubernetes.client.extended.controller.reconciler.Request) ArrayList(java.util.ArrayList) Semaphore(java.util.concurrent.Semaphore) Result(io.kubernetes.client.extended.controller.reconciler.Result) Test(org.junit.Test)

Example 4 with Request

use of io.kubernetes.client.extended.controller.reconciler.Request in project java by kubernetes-client.

the class DefaultControllerBuilderTest method testBuildWatchShouldWorkIfInformerPresent.

@Test
public void testBuildWatchShouldWorkIfInformerPresent() {
    CoreV1Api api = new CoreV1Api();
    informerFactory.sharedIndexInformerFor((CallGeneratorParams params) -> {
        return api.listPodForAllNamespacesCall(null, null, null, null, null, null, params.resourceVersion, null, params.timeoutSeconds, params.watch, null);
    }, V1Pod.class, V1PodList.class);
    ControllerBuilder.defaultBuilder(informerFactory).watch((workQueue) -> ControllerBuilder.controllerWatchBuilder(V1Pod.class, workQueue).build()).withReconciler(new Reconciler() {

        @Override
        public Result reconcile(Request request) {
            return new Result(false);
        }
    }).build();
}
Also used : Reconciler(io.kubernetes.client.extended.controller.reconciler.Reconciler) Request(io.kubernetes.client.extended.controller.reconciler.Request) CallGeneratorParams(io.kubernetes.client.util.CallGeneratorParams) CoreV1Api(io.kubernetes.client.openapi.apis.CoreV1Api) Result(io.kubernetes.client.extended.controller.reconciler.Result) Test(org.junit.Test)

Example 5 with Request

use of io.kubernetes.client.extended.controller.reconciler.Request in project java by kubernetes-client.

the class DefaultControllerBuilderTest method testControllerBuilderCustomizationShouldWork.

@Test
public void testControllerBuilderCustomizationShouldWork() {
    String testName = "test-controller";
    int testWorkerCount = 1024;
    ExecutorService threadPool = Executors.newCachedThreadPool();
    ControllerBuilder.defaultBuilder(informerFactory).withName(testName).withWorkerCount(testWorkerCount).withWorkQueue(null).withReconciler(new Reconciler() {

        @Override
        public Result reconcile(Request request) {
            return new Result(false);
        }
    }).build();
}
Also used : Reconciler(io.kubernetes.client.extended.controller.reconciler.Reconciler) ExecutorService(java.util.concurrent.ExecutorService) Request(io.kubernetes.client.extended.controller.reconciler.Request) Result(io.kubernetes.client.extended.controller.reconciler.Result) Test(org.junit.Test)

Aggregations

Request (io.kubernetes.client.extended.controller.reconciler.Request)9 Result (io.kubernetes.client.extended.controller.reconciler.Result)8 Reconciler (io.kubernetes.client.extended.controller.reconciler.Reconciler)6 Test (org.junit.Test)6 Semaphore (java.util.concurrent.Semaphore)4 Controller (io.kubernetes.client.extended.controller.Controller)3 SharedInformerFactory (io.kubernetes.client.informer.SharedInformerFactory)3 CoreV1Api (io.kubernetes.client.openapi.apis.CoreV1Api)3 CallGeneratorParams (io.kubernetes.client.util.CallGeneratorParams)3 ArrayList (java.util.ArrayList)3 ControllerBuilder (io.kubernetes.client.extended.controller.builder.ControllerBuilder)2 SharedIndexInformer (io.kubernetes.client.informer.SharedIndexInformer)2 ApiClient (io.kubernetes.client.openapi.ApiClient)2 Duration (java.time.Duration)2 List (java.util.List)2 ExecutorService (java.util.concurrent.ExecutorService)2 WireMock (com.github.tomakehurst.wiremock.client.WireMock)1 WireMockRule (com.github.tomakehurst.wiremock.junit.WireMockRule)1 KubernetesObject (io.kubernetes.client.common.KubernetesObject)1 ControllerManager (io.kubernetes.client.extended.controller.ControllerManager)1