From e822d472f9028a50134d55944db09acb4923bb44 Mon Sep 17 00:00:00 2001 From: "Michael N. Lipp" Date: Sat, 1 Mar 2025 17:44:52 +0100 Subject: [PATCH] Optimize status update. --- .../vmoperator/common/K8sGenericStub.java | 65 +++++++++++++++---- .../vmoperator/runner/qemu/StatusUpdater.java | 17 ++--- 2 files changed, 61 insertions(+), 21 deletions(-) diff --git a/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/K8sGenericStub.java b/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/K8sGenericStub.java index 2af4d1b..b8f1992 100644 --- a/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/K8sGenericStub.java +++ b/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/K8sGenericStub.java @@ -193,7 +193,7 @@ public class K8sGenericStub updateStatus(Function updater, O current, + int retries) throws ApiException { + while (true) { + try { + if (current == null) { + current = api.get(namespace, name) + .throwsApiException().getObject(); + } + return updateStatus(current, updater); + } catch (ApiException e) { + if (HttpURLConnection.HTTP_CONFLICT != e.getCode() + || retries-- <= 0) { + throw e; + } + // Get current version for new attempt + current = null; + } + } + } + /** * Gets the object and updates the status. In case of conflict, retries * up to `retries` times. @@ -218,17 +251,23 @@ public class K8sGenericStub updateStatus(Function updater, int retries) throws ApiException { - while (true) { - try { - return updateStatus(api.get(namespace, name) - .throwsApiException().getObject(), updater); - } catch (ApiException e) { - if (HttpURLConnection.HTTP_CONFLICT != e.getCode() - || retries-- <= 0) { - throw e; - } - } - } + return updateStatus(updater, null, retries); + } + + /** + * Updates the status of the given object. In case of conflict, + * get the current version of the object and tries again. Retries + * up to `retries` times. + * + * @param updater the function updating the status + * @param current the current + * @return the kubernetes api response + * the updated model or empty if not successful + * @throws ApiException the api exception + */ + public Optional updateStatus(Function updater, O current) + throws ApiException { + return updateStatus(updater, current, 16); } /** @@ -241,7 +280,7 @@ public class K8sGenericStub updateStatus(Function updater) throws ApiException { - return updateStatus(updater, 16); + return updateStatus(updater, null); } /** diff --git a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/StatusUpdater.java b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/StatusUpdater.java index 1bea80f..f2437d3 100644 --- a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/StatusUpdater.java +++ b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/StatusUpdater.java @@ -153,11 +153,13 @@ public class StatusUpdater extends VmDefUpdater { // by a new version of the CR. So we update only if we have // a new version of the CR. There's one exception: the display // password is configured by a file, not by the CR. - var vmDef = vmStub.model(); - if (vmDef.isPresent() - && vmDef.get().metadata().getGeneration() == observedGeneration + var vmDef = vmStub.model().orElse(null); + if (vmDef == null) { + return; + } + if (vmDef.metadata().getGeneration() == observedGeneration && (event.configuration().hasDisplayPassword - || vmDef.get().statusJson().getAsJsonPrimitive( + || vmDef.statusJson().getAsJsonPrimitive( "displayPasswordSerial").getAsInt() == -1)) { return; } @@ -172,7 +174,7 @@ public class StatusUpdater extends VmDefUpdater { .forEach(cond -> cond.addProperty("observedGeneration", from.getMetadata().getGeneration())); return status; - }); + }, vmDef); } /** @@ -219,7 +221,7 @@ public class StatusUpdater extends VmDefUpdater { "The VM is not running"); } return status; - }); + }, vmDef); // Maybe stop VM if (event.runState() == RunState.TERMINATING && !event.failed() @@ -325,7 +327,6 @@ public class StatusUpdater extends VmDefUpdater { } var asGson = gson.toJsonTree( objectMapper.convertValue(event.osinfo(), Object.class)); - vmStub.updateStatus(from -> { JsonObject status = from.statusJson(); status.add("osinfo", asGson); @@ -349,7 +350,7 @@ public class StatusUpdater extends VmDefUpdater { vmStub.updateStatus(from -> { return updateCondition(vmDef, "VmopAgentConnected", true, "VmopAgentStarted", "The VM operator agent is running"); - }); + }, vmDef); } /**