Add DELETE task API for stored task results#21727
Conversation
PR Reviewer Guide 🔍(Review updated until commit fec3337)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to fec3337 Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit 09efb27
Suggestions up to commit 210ff74
Suggestions up to commit 536a025
|
|
Persistent review updated to latest commit 210ff74 |
|
Persistent review updated to latest commit 09efb27 |
|
❌ Gradle check result for 09efb27: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
❌ Gradle check result for 09efb27: null Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #21727 +/- ##
============================================
+ Coverage 73.46% 73.50% +0.04%
- Complexity 74825 74842 +17
============================================
Files 5997 5996 -1
Lines 339688 339694 +6
Branches 48961 48961
============================================
+ Hits 249558 249700 +142
+ Misses 70272 70117 -155
- Partials 19858 19877 +19 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Thanks @cwperks for working on it. I'm not sure if passing a param to GET api is the right way to cleanup stored tasks here. |
@rishabhmaurya what do you suggest for cleanup? FYI if you look at the linked issue this PR is one of 2 proposals. The other is a TTL on .tasks entries so they can periodically be cleaned up on expiry (if the task is completed). wdyt? I suggested this because I think it would make sense for a caller to explicitly request cleanup when they are done with the task. |
|
@cwperks can we support POST on this API? |
|
I am not sure if adding a cleanup parameter is the right way to do it. If we really want to solve this, a better way might be to introduce a dynamic cluster type setting where user can define their own time interval, and retain the task results until a certain point after it got completed or fetched. By default it would be disabled i.e. the current behavior. |
We can make sure the cleanup would only clean completed tasks and make sure they don't linger in perpetuity. I like @sgup432 suggestion of a separate DELETE _task API as well. This actually doesn't exist. See https://docs.opensearch.org/latest/api-reference/tasks/tasks/ for the list of Tasks APIs. |
Oh wow! I am surprised that we don't have any way to delete a task_id!? We certainly need this then. Actually considering |
Signed-off-by: Craig Perkins <craig5008@gmail.com>
|
Persistent review updated to latest commit fec3337 |
Not in a cluster with FGAC. Any mutating operation to a system index is blocked when using FGAC as writing to a system index can cause corruption and any writing should be done through dedicated APIs where the system is the one doing system index access. I pivoted this PR to reveal a DELETE _task/{task_id} API to delete from this index and it properly guards to ensure that in-flight tasks cannot be deleted from the index. |
|
❕ Gradle check result for fec3337: UNSTABLE Please review all flaky tests that succeeded after retry and create an issue if one does not already exist to track the flaky failure. |
Description
Adds Layer 1 of #21724 with a dedicated
DELETE /_tasks/{task_id}API for deleting stored completed task results.The new delete API removes a completed task result from the
.tasksindex and returns an acknowledged response. Running tasks are not cancelled or deleted by this API; callers should continue to use the cancel tasks API for running tasks.The change wires the new action through transport, REST routing, REST API spec, the Java transport client, and the high-level REST client.
API Behavior
Delete a stored completed task result:
curl -XDELETE "http://localhost:9200/_tasks/node-1:12345"Successful response:
{ "acknowledged": true }After the stored result is deleted, a follow-up
GET /_tasks/node-1:12345returns404because the task is no longer running and no stored task result remains.This API intentionally does not cancel or remove running tasks. If the task is still running on the node that owns it, OpenSearch returns a conflict response:
{ "error": { "type": "opensearch_status_exception", "reason": "task [node-1:12345] is still running and cannot be deleted; use the cancel tasks API to cancel running tasks" }, "status": 409 }If the task id does not correspond to a running task or a stored result in
.tasks, OpenSearch returns404:{ "error": { "type": "resource_not_found_exception", "reason": "task [node-1:12345] isn't running and hasn't stored its results" }, "status": 404 }If a task id belongs to a node that is no longer part of the cluster, the delete API still attempts to remove a stored result from
.tasks. If no stored result exists, OpenSearch returns404with context that the owning node is no longer in the cluster.If a stored task result is found but is not marked completed, OpenSearch returns
409and leaves the stored document in place.Related Issues
Resolves #21724
Check List
Testing
./gradlew :server:test --tests org.opensearch.action.admin.cluster.node.tasks.delete.DeleteTaskRequestTests :client:rest-high-level:test --tests org.opensearch.client.TasksRequestConvertersTests./gradlew :server:internalClusterTest --tests org.opensearch.action.admin.cluster.node.tasks.TasksIT.testTaskStoringSuccessfulResult --tests org.opensearch.action.admin.cluster.node.tasks.TasksIT.testTaskStoringFailureResult --tests org.opensearch.action.admin.cluster.node.tasks.TasksIT.testNodeNotFoundButTaskFound./gradlew :server:precommit :client:rest-high-level:precommit :rest-api-spec:validateRestSpec :rest-api-spec:validateNoKeywordsManual REST verification against a local 3.7.0-SNAPSHOT node
With OpenSearch running at
http://localhost:9200:Start from a clean slate so the test indices do not inherit state from a previous run.
curl -s -XDELETE 'http://localhost:9200/movies_source,movies_archive?ignore_unavailable=true'Create a small source index with no replicas so the test is deterministic on a single local node.
Index a couple of documents and refresh immediately so the async reindex task has known source content.
Start
_reindexasynchronously. This returns a task id and causes OpenSearch to persist the completed task result in.tasks.Fetch the task with
wait_for_completion=true. This waits for completion and confirms the completed stored task result can be read.curl -s -i "http://localhost:9200/_tasks/${TASK_ID}?wait_for_completion=true"Fetch the same task again. This confirms
GET /_tasks/{task_id}remains read-only and does not remove the stored result.curl -s -i "http://localhost:9200/_tasks/${TASK_ID}"Delete the stored completed task result using the dedicated delete API.
curl -s -i -XDELETE "http://localhost:9200/_tasks/${TASK_ID}"Fetch the task again. The expected
404confirms the stored completed task result was deleted.curl -s -i "http://localhost:9200/_tasks/${TASK_ID}"Remove the temporary indices created by the manual test.
curl -s -XDELETE 'http://localhost:9200/movies_source,movies_archive?ignore_unavailable=true'Expected behavior:
200for the completed task result.200, confirming GET preserved the stored result.DELETE /_tasks/${TASK_ID}returns200with"acknowledged":true.404, confirming the stored completed task result was deleted.