This is an automated email from the ASF dual-hosted git repository.
cecemei pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git
The following commit(s) were added to refs/heads/master by this push:
new 76b26715d53 feat: Default skipRestartIfUnmodified to true on
supervisor update (#20649)
76b26715d53 is described below
commit 76b26715d531d66ff1ff9af22bd6fecc8f5393bc
Author: Cece Mei <[email protected]>
AuthorDate: Wed Oct 21 19:38:44 2026 -0700
feat: Default skipRestartIfUnmodified to true on supervisor update (#20649)
* skip
* Update docs/api-reference/supervisor-api.md
Co-authored-by: Kashif Faraz <[email protected]>
* Update docs/api-reference/supervisor-api.md
Co-authored-by: Kashif Faraz <[email protected]>
* comment
---------
Co-authored-by: Kashif Faraz <[email protected]>
---
docs/api-reference/supervisor-api.md | 20 ++++++++++++++++----
.../overlord/supervisor/SupervisorResource.java | 3 ++-
.../overlord/supervisor/SupervisorResourceTest.java | 18 ++++++++++++++++++
3 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/docs/api-reference/supervisor-api.md
b/docs/api-reference/supervisor-api.md
index 48dbd1d47c0..0d1a76eb72f 100644
--- a/docs/api-reference/supervisor-api.md
+++ b/docs/api-reference/supervisor-api.md
@@ -2288,13 +2288,22 @@ The following table lists the properties of a
supervisor spec:
|`dataSchema`|Object|The schema for the indexing task to use during ingestion.
See [`dataSchema`](../ingestion/ingestion-spec.md#dataschema) for more
information.|Yes|
|`tuningConfig`|Object|The tuning configuration object to define
performance-related settings for the supervisor and indexing tasks.|No|
-When you call this endpoint on an existing supervisor, the running supervisor
signals its tasks to stop reading and begin publishing, exiting itself. Druid
then uses the provided configuration from the request body to create a new
supervisor. Druid submits a new schema while retaining existing publishing
tasks and starts new tasks at the previous task offsets.
-This way, you can apply configuration changes without a pause in ingestion.
+When called on an existing supervisor, Druid compares the submitted spec with
the running one. If the change requires a restart, the supervisor signals its
tasks to stop reading and begin publishing, then exits. Druid creates a new
supervisor using the submitted spec, retaining existing publishing tasks and
starting new tasks from the previous task offsets. This allows configuration
changes without interrupting data processing.
+
+Otherwise, Druid does not restart the supervisor. If the spec is unchanged,
the call is a no-op. If the only difference is `taskCount` while task
auto-scaling is enabled, Druid persists the updated `taskCount` without
restarting the supervisor.
+
+Set `skipRestartIfUnmodified` to false to always restart the supervisor and
its tasks, even when the spec is effectively unchanged.
#### URL
`POST` `/druid/indexer/v1/supervisor`
+#### Query parameters
+
+|Property|Type|Description|Default|
+|--------|----|-----------|-------|
+|`skipRestartIfUnmodified`|Boolean|Whether to skip restarting the supervisor
if the submitted spec is unchanged or differs only in ways that can be applied
without a restart. Set to `false` to always restart the supervisor.|`true`|
+
#### Responses
<Tabs>
@@ -2445,9 +2454,11 @@ Content-Length: 1359
#### Sample request with `skipRestartIfUnmodified`
-The following example sets the `skipRestartIfUnmodified` flag to true. With
this flag set to true, the Supervisor will only restart if there has been a
modification to the SupervisorSpec. If left unset, the flag defaults to false.
+By default, `skipRestartIfUnmodified` is `true`, so Druid only restarts the
supervisor for changes that require it. Set `skipRestartIfUnmodified=false` to
always restart the supervisor on this call.
+
+The following example sets `skipRestartIfUnmodified` to `false`, so this call
always restarts the supervisor, even if the spec is unchanged.
```shell
-curl
"http://ROUTER_IP:ROUTER_PORT/druid/indexer/v1/supervisor?skipRestartIfUnmodified=true"
\
+curl
"http://ROUTER_IP:ROUTER_PORT/druid/indexer/v1/supervisor?skipRestartIfUnmodified=false"
\
--header 'Content-Type: application/json' \
--data '{
"type": "kafka",
@@ -2516,6 +2527,7 @@ curl
"http://ROUTER_IP:ROUTER_PORT/druid/indexer/v1/supervisor?skipRestartIfUnmo
The response includes the following fields:
- `id`: The supervisor ID.
+- `modified`: A boolean indicating whether the submitted spec was different
from the existing spec and was persisted as a new version.
- `restarted`: A boolean indicating whether the supervisor was restarted. When
`skipRestartIfUnmodified` is set to `true` and the supervisor spec is
unchanged, this field will be `false`; otherwise, it will be `true`.
### Suspend a running supervisor
diff --git
a/indexing-service/src/main/java/org/apache/druid/indexing/overlord/supervisor/SupervisorResource.java
b/indexing-service/src/main/java/org/apache/druid/indexing/overlord/supervisor/SupervisorResource.java
index 73ab668f16d..87428df2375 100644
---
a/indexing-service/src/main/java/org/apache/druid/indexing/overlord/supervisor/SupervisorResource.java
+++
b/indexing-service/src/main/java/org/apache/druid/indexing/overlord/supervisor/SupervisorResource.java
@@ -58,6 +58,7 @@ import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
+import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
@@ -123,7 +124,7 @@ public class SupervisorResource
@Produces(MediaType.APPLICATION_JSON)
public Response specPost(
final SupervisorSpec spec,
- @QueryParam("skipRestartIfUnmodified") Boolean skipRestartIfUnmodified,
+ @QueryParam("skipRestartIfUnmodified") @DefaultValue("true") Boolean
skipRestartIfUnmodified,
@Context final HttpServletRequest req
)
{
diff --git
a/indexing-service/src/test/java/org/apache/druid/indexing/overlord/supervisor/SupervisorResourceTest.java
b/indexing-service/src/test/java/org/apache/druid/indexing/overlord/supervisor/SupervisorResourceTest.java
index 98b5d501134..b7124f7782a 100644
---
a/indexing-service/src/test/java/org/apache/druid/indexing/overlord/supervisor/SupervisorResourceTest.java
+++
b/indexing-service/src/test/java/org/apache/druid/indexing/overlord/supervisor/SupervisorResourceTest.java
@@ -68,7 +68,9 @@ import org.junit.jupiter.api.extension.ExtendWith;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.DefaultValue;
import javax.ws.rs.core.Response;
+import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@@ -317,6 +319,22 @@ public class SupervisorResourceTest extends EasyMockSupport
Assertions.assertEquals(Map.of("id", "my-id", "modified", true,
"restarted", true), response.getEntity());
}
+ @Test
+ public void testSpecPost_skipRestartIfUnmodifiedQueryParam_defaultsToTrue()
throws NoSuchMethodException
+ {
+ // JAX-RS applies @DefaultValue only when binding an actual HTTP request,
so a direct call to
+ // specPost(spec, null, ...) can't exercise that default.
+ Method specPost = SupervisorResource.class.getMethod(
+ "specPost",
+ SupervisorSpec.class,
+ Boolean.class,
+ HttpServletRequest.class
+ );
+ DefaultValue defaultValue =
specPost.getParameters()[1].getAnnotation(DefaultValue.class);
+ Assertions.assertNotNull(defaultValue);
+ Assertions.assertEquals("true", defaultValue.value());
+ }
+
@Test
public void testSpecPostWithInputSourceSecurityEnabledAuthorized()
{
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]