Skip to content

Restructure tim.opensearch bulk methods and retry deletes#390

Merged
jonavellecuerdo merged 1 commit into
mainfrom
TIMX-639-clean-up-bulk-methods-and-retry-deletes
Jul 14, 2026
Merged

Restructure tim.opensearch bulk methods and retry deletes#390
jonavellecuerdo merged 1 commit into
mainfrom
TIMX-639-clean-up-bulk-methods-and-retry-deletes

Conversation

@jonavellecuerdo

@jonavellecuerdo jonavellecuerdo commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Purpose and background context

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 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 more response[<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:

make 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

  • Code review best practices are documented here and you are encouraged to have a constructive dialogue with your reviewers about their preferences and expectations.

@jonavellecuerdo
jonavellecuerdo force-pushed the TIMX-639-clean-up-bulk-methods-and-retry-deletes branch from 89a11e1 to c337b5e Compare July 13, 2026 18:50
@jonavellecuerdo
jonavellecuerdo marked this pull request as ready for review July 13, 2026 18:52
@jonavellecuerdo
jonavellecuerdo requested a review from a team as a code owner July 13, 2026 18:52
@jonavellecuerdo
jonavellecuerdo requested a review from ehanson8 July 13, 2026 18:52
@ehanson8
ehanson8 requested a review from Copilot July 13, 2026 19:25

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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, and bulk_delete to unpack (ok, item) and parse response fields directly.
  • Added retry-on-507 behavior for bulk_delete using execute_single_record_action.
  • Standardized bulk error raising/handling around BulkOperationError and 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 (actionoperation).
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.

Comment thread tim/errors.py Outdated
Comment thread tim/opensearch.py Outdated
Comment thread tim/opensearch.py Outdated
Comment thread tim/opensearch.py Outdated
jonavellecuerdo added a commit that referenced this pull request Jul 13, 2026

@ehanson8 ehanson8 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great work!

Comment thread tests/test_helpers.py
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
jonavellecuerdo force-pushed the TIMX-639-clean-up-bulk-methods-and-retry-deletes branch from 5d596d9 to a8c8868 Compare July 14, 2026 15:50
@jonavellecuerdo
jonavellecuerdo merged commit d5dd337 into main Jul 14, 2026
5 checks passed
@jonavellecuerdo
jonavellecuerdo deleted the TIMX-639-clean-up-bulk-methods-and-retry-deletes branch July 14, 2026 15:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants