Skip to content

Cancel reindex returns same response as GET#140626

Merged
szybia merged 2 commits intoelastic:mainfrom
szybia:reindex-cancel-complete-response
Jan 15, 2026
Merged

Cancel reindex returns same response as GET#140626
szybia merged 2 commits intoelastic:mainfrom
szybia:reindex-cancel-complete-response

Conversation

@szybia
Copy link
Contributor

@szybia szybia commented Jan 13, 2026

  • Add more fully-featured response on POST _reindex/{task_id}/_cancel?wait_for_completion=true, similar to what is returned in GET _reindex/{task_id} since it's handy to have without doing a follow-up GET
  • ?wait_for_completion=false returns the existing acknowledge: true response

Closes elastic/elasticsearch-team#2086


final Map<String, Object> response = cancelReindexInProjectAndWaitForCompletion(taskId, projectWithReindex);
assertThat("reindex is cancelled", response, equalTo(Map.of("acknowledged", true)));
assertThat("reindex is cancelled", response, allOf(hasEntry("cancelled", true), hasEntry("completed", true)));
Copy link
Contributor Author

@szybia szybia Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

incoming yaml rest tests (next PR) will assert response more definitively

for now, just asserting the basics that are relevant for these tests

ActionListener.wrap(ignored -> listener.onResponse(new CancelReindexTaskResponse()), listener::onFailure)
ActionListener.wrap(ignored -> {
final TaskResult completedTaskResult = request.waitForCompletion()
? new TaskResult(true, task.taskInfo(clusterService.localNode().getId(), true))
Copy link
Contributor Author

@szybia szybia Jan 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's a choice to be made here that we discussed on the meeting, detailing so we can make a concrete decision.


firstly, context/existing art:

  • cancelled field is not recorded in tasks index, so a GET after cancellation seems to default to default value (false)
  • POST _tasks/:taskId/_cancel?wait_for_completion=true&filter_path=nodes.*.tasks
    • Note the cancelled: true and absence of response/full-featured response
      {
        "nodes": {
          "1RCnK_OnSamzfgmhcshBrA": {
            "tasks": {
              "1RCnK_OnSamzfgmhcshBrA:7281": {
                "node": "1RCnK_OnSamzfgmhcshBrA",
                "id": 7281,
                "type": "transport",
                "action": "indices:data/write/reindex",
                "start_time_in_millis": 1768412466161,
                "running_time_in_nanos": 6862322167,
                "cancellable": true,
                "cancelled": true,
                "headers": {}
              }
            }
          }
        }
      }
      
  • GET _tasks/:taskId
    • Returns fully-featured response (task, slices, response, response.failures) and notably cancelled: false

in terms of what we're doing here, I see two main choices to get what we want (a more fully-featured response on POST _reindex/{task_id}/_cancel?wait_for_completion=true)

  • what i currently have here: we generate the taskInfo here
    • pros:
      • cancelled: true (makes sense)
      • slightly simpler code
      • still get status.slices information, same as GET _reindex/{task_id}
    • cons
      • running_time_in_nanos is calculated right here System.nanoTime() - start, so this will be slightly different from what we will see in GET _reindex/{task_id} (taskInfo generated elsewhere)
      • don't get response, response.failures objects
  • do a GET _reindex/{task_id} transport call
    • pros:
      • get exact same response as GET _reindex/{task_id}, including response
      • building on top of GET
    • cons:
      • cancelled: false, confusing

other potential avenues:

  • we could get the full response using GET, and hackily flip cancelled to true
  • i could investigate further whether any way to get from cancelTaskAndDescendants the full TaskResult that will be stored in tasks index, but assuming async stuff will make it hard to hand off

stating preference:

  • i'm leaning towards saying what i have here is good enough, on first glance response field returned in GET doesn't seem to have extra useful info other than what is here already within slices, maybe response.failures from the BulkByScroll
  • in the unlikely case this is wanted, you can just do a folllow-up GET
  • in previous conversations we didn't seem too bothered about having response but we included it (from what i read, because why not)

attaching below two files so reviewers can diff what is returned in POST _reindex/{task_id}/_cancel?wait_for_completion=true, and GET _reindex/{task_id} after cancellation

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'm happy with what you have here. As discussed, I'm okay with not including the full response. I think I'm also okay with the times not matching up perfectly, especially as they're in different units. Reporting the correct value for cancelled is probably a good thing. The only thing that's giving me pause is that we're not consistent with get tasks... but there's no real reason we should be, since we're trying to mostly obfuscate the fact that this is wrappers around tasks (and esp. since that is doing something confusing around the cancelled field.)

@szybia szybia added >non-issue :Distributed/Reindex Issues relating to reindex that are not caused by issues further down labels Jan 14, 2026
@szybia szybia marked this pull request as ready for review January 14, 2026 18:39
@elasticsearchmachine elasticsearchmachine added the Team:Distributed Indexing (obsolete) Meta label for Distributed Indexing team. Obsolete. Please do not use. label Jan 14, 2026
@elasticsearchmachine
Copy link
Collaborator

Pinging @elastic/es-distributed-indexing (Team:Distributed Indexing)

Copy link
Member

@PeteGillinElastic PeteGillinElastic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this LGTM, although I'd also be interested to see if @samxbr agrees.

ActionListener.wrap(ignored -> listener.onResponse(new CancelReindexTaskResponse()), listener::onFailure)
ActionListener.wrap(ignored -> {
final TaskResult completedTaskResult = request.waitForCompletion()
? new TaskResult(true, task.taskInfo(clusterService.localNode().getId(), true))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'm happy with what you have here. As discussed, I'm okay with not including the full response. I think I'm also okay with the times not matching up perfectly, especially as they're in different units. Reporting the correct value for cancelled is probably a good thing. The only thing that's giving me pause is that we're not consistent with get tasks... but there's no real reason we should be, since we're trying to mostly obfuscate the fact that this is wrappers around tasks (and esp. since that is doing something confusing around the cancelled field.)

Copy link
Member

@PeteGillinElastic PeteGillinElastic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'm okay with this (see below) but I'd also be interested to know what @samxbr thinks.

Copy link
Contributor

@samxbr samxbr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@szybia szybia enabled auto-merge (squash) January 15, 2026 21:14
@szybia szybia merged commit 86dcd53 into elastic:main Jan 15, 2026
35 checks passed
spinscale pushed a commit to spinscale/elasticsearch that referenced this pull request Jan 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

:Distributed/Reindex Issues relating to reindex that are not caused by issues further down >non-issue Team:Distributed Indexing (obsolete) Meta label for Distributed Indexing team. Obsolete. Please do not use. v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants