Restructure tim.opensearch bulk methods and retry deletes#390
Merged
jonavellecuerdo merged 1 commit intoJul 14, 2026
Merged
Conversation
jonavellecuerdo
force-pushed
the
TIMX-639-clean-up-bulk-methods-and-retry-deletes
branch
from
July 13, 2026 18:50
89a11e1 to
c337b5e
Compare
jonavellecuerdo
marked this pull request as ready for review
July 13, 2026 18:52
There was a problem hiding this comment.
Pull request overview
Refactors the OpenSearch bulk indexing/updating/deleting helpers in tim.opensearch to make streaming-bulk responses easier to interpret, and adds a retry path for bulk deletes on transport error 507, while aligning CLI error handling and updating tests accordingly.
Changes:
- Restructured
bulk_index,bulk_update, andbulk_deleteto unpack(ok, item)and parse response fields directly. - Added retry-on-507 behavior for
bulk_deleteusingexecute_single_record_action. - Standardized bulk error raising/handling around
BulkOperationErrorand updated CLI/tests.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tim/opensearch.py | Refactors bulk methods’ response parsing; adds delete retry-on-507; updates single-record execution signature usage. |
| tim/errors.py | Adjusts BulkOperationError constructor parameter naming (action → operation). |
| tim/cli.py | Updates exception imports/handlers to catch BulkOperationError instead of BulkIndexingError. |
| tests/test_opensearch.py | Adds unit test coverage for bulk delete retry behavior on 507. |
| tests/test_cli.py | Updates tests to raise BulkOperationError with the new parameter name. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
jonavellecuerdo
added a commit
that referenced
this pull request
Jul 13, 2026
Why these changes are being introduced:
* The three bulk methods for indexing, updating, and deleting records from
an OpenSearch index defined in `tim.opensearch` share a lot of the same code,
but it was somewhat difficult to understand what was happening in its previous
structure. The changes in this PR were intended to make the code easier to
follow and set a clear path for integrating the retry solution for the
`bulk_delete` method. The `bulk_*` methods execute the following steps in
sequential order:
1. Instantiate a `result_summary` dict to track the number of modified records
2. Create a generator of bulk actions
3. In chunks, execute actions via streaming_bulk and evaluate results
- Check if action was successful update result_summary with ["created", "updated",
"deleted", "skipped"] record counts
- Check if a "loggable" error (i.e., doesn't raise `BulkOperationError`) was returned,
log error message and update result_summary "errors" count
- Check if status=507 (retryable error)
- Retry action with progressive backoff (defaults to ~180 seconds)
- If successful, update `result_summary
- If RetryFailedWithUnexpectedError or TimeoutError is raised and action is "index" or "update",
exit method call
- If RetryFailedWithUnexpectedError or TimeoutError is raised and action is "delete", log error message
with traceback and update result_summary "errors" count
- Otherwise, if action failed and caused by non-loggable or non-retryable error
- And action is "index" or "update", raise `BulkActionError`
- And action is "delete", log error message and update result_summary "errors" count
How this addresses that need:
* Replace `BulkIndexingError` with `BulkActionError`
* Standardize code for iterating and evaluating over streaming_bulk responses
* Add retry solution for `tim.opensearch.bulk_delete`, handling raised errors
by `retry` decorator method
Side effects of this change:
* None
Relevant ticket(s):
* https://mitlibraries.atlassian.net/browse/TIMX-639
jonavellecuerdo
force-pushed
the
TIMX-639-clean-up-bulk-methods-and-retry-deletes
branch
from
July 14, 2026 15:50
5d596d9 to
a8c8868
Compare
jonavellecuerdo
deleted the
TIMX-639-clean-up-bulk-methods-and-retry-deletes
branch
July 14, 2026 15:52
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose and background context
The three bulk methods for indexing, updating, and deleting records from an OpenSearch index defined in
tim.opensearchshare a lot of the same code, but it was somewhat difficult to understand what was happening in its previous structure. The changes in this PR were intended to make the code easier to follow and set a clear path for integrating the retry solution for thebulk_deletemethod.The main changes introduced in this PR is unpacking the tuple returned by
streaming_bulk, followed by unpacking a key-value pair from a dictionary item. Applying these two changes simplified the way we access attributes in the response object (i.e., no moreresponse[<index>][<operation]...). The commit message for afb61a5 describes the general control flow structure in more detail.Note: When I originally started on this work, I was initially thinking I'd be introducing significant changes to the PR to remove the duplicated steps/code in
bulk_*commands. However, the subtle differences for each method, such as:result_summarybulk_indextracked["created", "updated"]bulk_updatetracked["updated", "skipped"]bulk_deletetracked["deleted"]bulk_indexandbulk_updateraiseBulkOperationErrorwhen original response is non-loggable or non-retryable error and raisesSingleOperationErrororTimeoutErrorfor failed retriesbulk_deletehandles all errors, incrementing"errors"countbulk_indexallowsmapper_parsing_exceptionbulk_updateallowsmapper_parsing_exceptionanddocument_missing_exceptionmake it challenging to abstract the method into smaller methods. Ultimately, I decided that implementing a private, sub-method was not worth it at this time and that a future larger-scale, refactoring of TIM would benefit from the individual, written out
bulk_*method definitions!How can a reviewer manually see the effects of these changes?
See added unit test.
Includes new or updated dependencies?
NO
Changes expectations for external applications?
NO
What are the relevant tickets?
Code review