Fix custom scheduler support for @Scheduled methods
This commit fixes a regression introduced by gh-24560, when adding execution metadata support for scheduled tasks. The `OutcomeTrackingRunnable` would delegate to the actual runnable but could also hide whether it implements the `SchedulingAwareRunnable` contract. This commit ensures that `OutcomeTrackingRunnable` always implements that contract and delegates to the runnable if possible, or return default values otherwise. Fixes gh-34058
This commit is contained in:
@@ -18,6 +18,8 @@ package org.springframework.scheduling.config;
|
|||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.scheduling.SchedulingAwareRunnable;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,7 +70,7 @@ public class Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class OutcomeTrackingRunnable implements Runnable {
|
private class OutcomeTrackingRunnable implements SchedulingAwareRunnable {
|
||||||
|
|
||||||
private final Runnable runnable;
|
private final Runnable runnable;
|
||||||
|
|
||||||
@@ -89,6 +91,23 @@ public class Task {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isLongLived() {
|
||||||
|
if (this.runnable instanceof SchedulingAwareRunnable sar) {
|
||||||
|
return sar.isLongLived();
|
||||||
|
}
|
||||||
|
return SchedulingAwareRunnable.super.isLongLived();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public String getQualifier() {
|
||||||
|
if (this.runnable instanceof SchedulingAwareRunnable sar) {
|
||||||
|
return sar.getQualifier();
|
||||||
|
}
|
||||||
|
return SchedulingAwareRunnable.super.getQualifier();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return this.runnable.toString();
|
return this.runnable.toString();
|
||||||
|
|||||||
@@ -16,8 +16,12 @@
|
|||||||
|
|
||||||
package org.springframework.scheduling.config;
|
package org.springframework.scheduling.config;
|
||||||
|
|
||||||
|
import io.micrometer.observation.tck.TestObservationRegistry;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.scheduling.SchedulingAwareRunnable;
|
||||||
|
import org.springframework.scheduling.support.ScheduledMethodRunnable;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||||
@@ -72,6 +76,18 @@ class TaskTests {
|
|||||||
assertThat(executionOutcome.throwable()).isInstanceOf(IllegalStateException.class);
|
assertThat(executionOutcome.throwable()).isInstanceOf(IllegalStateException.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void shouldDelegateToSchedulingAwareRunnable() throws Exception {
|
||||||
|
ScheduledMethodRunnable methodRunnable = new ScheduledMethodRunnable(new TestRunnable(),
|
||||||
|
TestRunnable.class.getMethod("run"), "myScheduler", TestObservationRegistry::create);
|
||||||
|
Task task = new Task(methodRunnable);
|
||||||
|
|
||||||
|
assertThat(task.getRunnable()).isInstanceOf(SchedulingAwareRunnable.class);
|
||||||
|
SchedulingAwareRunnable actual = (SchedulingAwareRunnable) task.getRunnable();
|
||||||
|
assertThat(actual.getQualifier()).isEqualTo(methodRunnable.getQualifier());
|
||||||
|
assertThat(actual.isLongLived()).isEqualTo(methodRunnable.isLongLived());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static class TestRunnable implements Runnable {
|
static class TestRunnable implements Runnable {
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user