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]

Reply via email to