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

Implement coditional execution "result" field retrieval for the "/v1/executions/<id>" (get one execution) API endpoint #5197

Merged
merged 9 commits into from
Mar 31, 2021

Conversation

Kami
Copy link
Member

@Kami Kami commented Mar 20, 2021

As per my comment in #4846 (#4846 (comment)), I couldn't live with that one additional query on the st2web side to implement "only retrieve execution result if it's smaller than X" functionality even though that with the additional query overall end user experience and performance was already much, much better than previous status quo, but I'm kinda OCD and wanted to get rid of that additional API operation in st2web (StackStorm/st2web#868).

So to do that, I implemented conditional "get one execution" API operation where the result field is only returned if it's smaller than the provided value.

Imo, this implementation is a win-win since it allow us to get rid of additional API operation on the st2web side, we can even simplify st2web code a lot and other clients can also utilize this new API operation / query parameter. In addition to that it's also a win-win for the server - in case client won't actually render the result if it's too large it also makes no sense for the server to return it (so this way we reduce load a bit on the server as well).

We also have fall back in st2web so it's fully backward compatible and even works with old executions which may not contain result_size field (in that case we calculate result size on the client which takes some time, but it's still very, very fast compared to actually rendering and displaying large results).

Implementation Details

If you check the code and comments, you will see the operation is implemented by utilizing two MongoDB queries.

One to check if corresponding execution with result_size smaller than the specified threshold exists and one to then retrieve that execution (and only including the result field size is smaller than specified threshold).

I experimented with a couple of different approaches (always retrieve execution result and do filtering and result field removal in the Python code, etc.), but it turns out this two query approach is actually the fastest.

To some extent that's expected because the first query we run already performs first filtering on the primary key (object id) which is an index lookup and it's very fast and we also do a projection operation where only 2 tiny indexed fields are retrieved and returned.

I will make necessary changes to st2web PR (StackStorm/st2web#868) to utilize this new query param filter shortly.

API endpoint.

With this query parameter, user can decide to exclude execution.result
field from the response in case it exceeds this size.

This allows us to implement efficient execution retrieval in the client
(st2web) side and avoid additional queries / API operations on the
client side - aka win-win situation (reduce the load on the client and
the server).
@Kami Kami requested a review from blag March 20, 2021 15:25
@pull-request-size pull-request-size bot added the size/L PR that changes 100-499 lines. Requires some effort to review. label Mar 20, 2021
Kami added a commit to StackStorm/st2web that referenced this pull request Mar 20, 2021
This allows us to simplify the code and make it even more efficient by
only always performing single "get one" execution API operation.
@Kami
Copy link
Member Author

Kami commented Mar 20, 2021

Alright, I also updated the st2web changes in StackStorm/st2web#868 (which are very simple now).

@Kami Kami added this to the 3.5.0 milestone Mar 20, 2021
Copy link
Contributor

@winem winem left a comment

Choose a reason for hiding this comment

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

Just have a few minor remarks regarding some comments and a copy paste failure I guess.

Although it's a real edge case, we may also want to add a check where max_result_size is equal to the actual size since we use __lte as operator.

st2api/tests/unit/controllers/v1/test_executions.py Outdated Show resolved Hide resolved
st2api/tests/unit/controllers/v1/test_executions.py Outdated Show resolved Hide resolved
st2common/st2common/openapi.yaml Outdated Show resolved Hide resolved
st2common/st2common/openapi.yaml.j2 Outdated Show resolved Hide resolved
result_size == max_result_size, clarify query parameter value represents
bytes.
@Kami
Copy link
Member Author

Kami commented Mar 30, 2021

@winem Thanks for the review.

I believe 0c80a00 should address all the feedback.

@winem
Copy link
Contributor

winem commented Mar 31, 2021

LGTM now!

@Kami Kami merged commit 9909f2b into master Mar 31, 2021
@Kami Kami deleted the api_endpoint_exclude_result_if_size_greater branch March 31, 2021 20:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
API performance service: api size/L PR that changes 100-499 lines. Requires some effort to review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants