use of io.kubernetes.client.extended.controller.reconciler.Result 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);
}
}
}
use of io.kubernetes.client.extended.controller.reconciler.Result 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);
}
use of io.kubernetes.client.extended.controller.reconciler.Result 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);
}
use of io.kubernetes.client.extended.controller.reconciler.Result 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();
}
use of io.kubernetes.client.extended.controller.reconciler.Result 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();
}
Aggregations