Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch back to botocore _make_api_call under the hood #1079

Merged
merged 12 commits into from
Nov 29, 2023

Conversation

garrettheel
Copy link
Member

@garrettheel garrettheel commented Oct 11, 2022

It's not clear that the reasons for diverging from botocore's _make_api_call are still valid 7 years later. The most immediate negative impact of this implementation is that PynamoDB is incompatible with the opentelemetry botocore instrumentation.

Our retry implementation is also lacking compared to botocore's these days, so we'll be better off by switching back.

Note that this PR lessens the degree to which we're using internal private methods in botocore, but does not eliminate it entirely.

TODO:

  • Benchmark to ensure this doesn't cause a noticeable performance regression
  • Deprecate base_backoff_ms (not valid when using native botocore retries)
  • Ensure that binary attribute decoding still occurs
  • Ensure that exceptions are wrapped appropriately, check back-compat (currently missing VerboseClientError wrapping)
  • Reimplement extra_headers (through the before-sign. hook)

Note: I also modernized the connection/base test since it was the most affected by this change.


Benchmarks

previous calls/sec new calls/sec delta
get_item 5064 3718 -27%
put_item 4353 3267 -25%

@@ -349,124 +349,7 @@ def send_pre_boto_callback(self, operation_name, req_uuid, table_name):
log.exception("pre_boto callback threw an exception.")

def _make_api_call(self, operation_name: str, operation_kwargs: Dict, settings: OperationSettings = OperationSettings.default) -> Dict:

Choose a reason for hiding this comment

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

are we concerned about settings: OperationSettings now not being used? I see it only passed into self._create_prepared_request

Copy link

@matthewgrossman matthewgrossman Oct 11, 2022

Choose a reason for hiding this comment

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

ah thats probably TODO Reimplement extra_headers (through the before-sign. hook)

Copy link
Contributor

Choose a reason for hiding this comment

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

The motivation for 'settings' was to allow per-request controls of retries, e.g. you might want to hedged-retry a read but not a write. Honestly didn't end up using this anywhere. With retries delegated to boto, this might not be needed since we'd no longer retry perm-fails indiscriminately.

Copy link
Member Author

Choose a reason for hiding this comment

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

I removed this in 4f28c9f since I can't find a good way to retain this without taking more deps on botocore internals, and I think it's unlikely to be used much

@tomwans
Copy link

tomwans commented Oct 18, 2022

+1

@garrettheel
Copy link
Member Author

Update on this: the performance regression was larger than I expected, so I don't feel comfortable merging this as is. While I was able to get back a chunk of that by removing additional response parsing (~5%), there is still another 20% or so regression that comes from a lot of little things and is not easily fixed (hooks, passing around context for retries, etc.).

I'll leave this open for now in case something changes later that makes this worth revisiting. At least the benchmark script is likely to come in handy in future

ikonst referenced this pull request Nov 25, 2022
Improving the first iteration logic in `PageIterator` and `ResultIterator`.

Both iterators had a `_first_iteration` state attribute that could be replaced with better logic:
- In `PageIterator`, it can be replaced with `_is_last_page` which
  - is exception-safe (only mutate after we do I/O), and
  - (IMO) more directly relates to the state we're handling
- In `ResultsIterator`, we can do without `_first_iteration` (but we should initialize `_index` and `_count`)

Inspired by #1059.
@ikonst ikonst added this to the 6.0 milestone Feb 6, 2023
@ilanjb
Copy link

ilanjb commented Apr 9, 2023

@garrettheel is this still in the works?

@garrettheel
Copy link
Member Author

@ilanjb not right now, the performance regression of 25% is a bit too high. this could be revisited if botocore performance improves and lessens the delta

test.py Outdated
@@ -0,0 +1,49 @@
import traceback
Copy link
Contributor

Choose a reason for hiding this comment

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

test left behind

@ikonst
Copy link
Contributor

ikonst commented Apr 26, 2023

removing additional response parsing

What change is that?

FWIW, I'm feeling like we should merge this for sanity/correctness, and then perhaps plead botocore to optimize? (Are there any obvious bottlenecks we can point them at?)

@ikonst ikonst force-pushed the move-to-botocore-make-api-call branch from f046855 to 214c690 Compare June 14, 2023 05:21
@ikonst ikonst force-pushed the move-to-botocore-make-api-call branch from 214c690 to 69de228 Compare June 14, 2023 05:33
@ikonst
Copy link
Contributor

ikonst commented Jun 14, 2023

Fixed conflicts with master. Given the resourcing to maintain this project and how deeper uses of internal botocore APIs made us rush with hot fixes last year, I think the 20% slowdown is a good tradeoff.

@garrettheel
Copy link
Member Author

Fixed conflicts with master. Given the resourcing to maintain this project and how deeper uses of internal botocore APIs made us rush with hot fixes last year, I think the 20% slowdown is a good tradeoff.

That's fair, I'm on board with merging if you like. We should just make sure to update the README/project motivation accordingly and be pretty upfront in the release notes

@ikonst ikonst marked this pull request as ready for review November 26, 2023 05:21
@ikonst ikonst merged commit 369f461 into master Nov 29, 2023
11 checks passed
@ikonst ikonst deleted the move-to-botocore-make-api-call branch November 29, 2023 18:38
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.

5 participants