diff --git a/application/src/main/java/run/halo/app/extension/gc/GcReconciler.java b/application/src/main/java/run/halo/app/extension/gc/GcReconciler.java index 47531f4949..009871db02 100644 --- a/application/src/main/java/run/halo/app/extension/gc/GcReconciler.java +++ b/application/src/main/java/run/halo/app/extension/gc/GcReconciler.java @@ -10,6 +10,7 @@ import run.halo.app.extension.ExtensionClient; import run.halo.app.extension.ExtensionConverter; import run.halo.app.extension.SchemeManager; +import run.halo.app.extension.SchemeWatcherManager; import run.halo.app.extension.controller.Controller; import run.halo.app.extension.controller.ControllerBuilder; import run.halo.app.extension.controller.DefaultController; @@ -29,12 +30,18 @@ class GcReconciler implements Reconciler { private final SchemeManager schemeManager; - GcReconciler(ExtensionClient client, ExtensionStoreClient storeClient, - ExtensionConverter converter, SchemeManager schemeManager) { + private final SchemeWatcherManager schemeWatcherManager; + + GcReconciler(ExtensionClient client, + ExtensionStoreClient storeClient, + ExtensionConverter converter, + SchemeManager schemeManager, + SchemeWatcherManager schemeWatcherManager) { this.client = client; this.storeClient = storeClient; this.converter = converter; this.schemeManager = schemeManager; + this.schemeWatcherManager = schemeWatcherManager; } @@ -56,7 +63,7 @@ public Result reconcile(GcRequest request) { @Override public Controller setupWith(ControllerBuilder builder) { var queue = new DefaultQueue(Instant::now, Duration.ofMillis(500)); - var synchronizer = new GcSynchronizer(client, queue, schemeManager); + var synchronizer = new GcSynchronizer(client, queue, schemeManager, schemeWatcherManager); return new DefaultController<>( "garbage-collector-controller", this, diff --git a/application/src/main/java/run/halo/app/extension/gc/GcSynchronizer.java b/application/src/main/java/run/halo/app/extension/gc/GcSynchronizer.java index 3f4843dc42..8265bb6367 100644 --- a/application/src/main/java/run/halo/app/extension/gc/GcSynchronizer.java +++ b/application/src/main/java/run/halo/app/extension/gc/GcSynchronizer.java @@ -1,10 +1,14 @@ package run.halo.app.extension.gc; +import static run.halo.app.extension.Comparators.compareCreationTimestamp; + import java.util.function.Predicate; import run.halo.app.extension.Extension; import run.halo.app.extension.ExtensionClient; import run.halo.app.extension.Scheme; import run.halo.app.extension.SchemeManager; +import run.halo.app.extension.SchemeWatcherManager; +import run.halo.app.extension.SchemeWatcherManager.SchemeRegistered; import run.halo.app.extension.Watcher; import run.halo.app.extension.controller.RequestQueue; import run.halo.app.extension.controller.Synchronizer; @@ -13,10 +17,10 @@ class GcSynchronizer implements Synchronizer { private final ExtensionClient client; - private final RequestQueue queue; - private final SchemeManager schemeManager; + private final SchemeWatcherManager schemeWatcherManager; + private boolean disposed = false; private boolean started = false; @@ -24,11 +28,11 @@ class GcSynchronizer implements Synchronizer { private final Watcher watcher; GcSynchronizer(ExtensionClient client, RequestQueue queue, - SchemeManager schemeManager) { + SchemeManager schemeManager, SchemeWatcherManager schemeWatcherManager) { this.client = client; - this.queue = queue; this.schemeManager = schemeManager; this.watcher = new GcWatcher(queue); + this.schemeWatcherManager = schemeWatcherManager; } @Override @@ -51,10 +55,17 @@ public void start() { return; } this.started = true; + this.schemeWatcherManager.register(event -> { + if (event instanceof SchemeRegistered registeredEvent) { + var newScheme = registeredEvent.getNewScheme(); + client.list(newScheme.type(), deleted(), compareCreationTimestamp(true)) + .forEach(watcher::onDelete); + } + }); client.watch(watcher); schemeManager.schemes().stream() .map(Scheme::type) - .forEach(type -> client.list(type, deleted(), null) + .forEach(type -> client.list(type, deleted(), compareCreationTimestamp(true)) .forEach(watcher::onDelete)); } diff --git a/application/src/test/java/run/halo/app/extension/gc/GcSynchronizerTest.java b/application/src/test/java/run/halo/app/extension/gc/GcSynchronizerTest.java new file mode 100644 index 0000000000..48c270dd49 --- /dev/null +++ b/application/src/test/java/run/halo/app/extension/gc/GcSynchronizerTest.java @@ -0,0 +1,52 @@ +package run.halo.app.extension.gc; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.isA; +import static org.mockito.Mockito.verify; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import run.halo.app.extension.ExtensionClient; +import run.halo.app.extension.SchemeManager; +import run.halo.app.extension.SchemeWatcherManager; +import run.halo.app.extension.SchemeWatcherManager.SchemeWatcher; + +@ExtendWith(MockitoExtension.class) +class GcSynchronizerTest { + + @Mock + ExtensionClient client; + + @Mock + SchemeManager schemeManager; + + @Mock + SchemeWatcherManager schemeWatcherManager; + + @InjectMocks + GcSynchronizer synchronizer; + + @Test + void shouldStartNormally() { + synchronizer.start(); + + assertFalse(synchronizer.isDisposed()); + verify(schemeWatcherManager).register(any(SchemeWatcher.class)); + verify(client).watch(isA(GcWatcher.class)); + verify(schemeManager).schemes(); + } + + @Test + void shouldDisposeSuccessfully() { + assertFalse(synchronizer.isDisposed()); + + synchronizer.dispose(); + + assertTrue(synchronizer.isDisposed()); + } +} \ No newline at end of file