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

Unify single-response-requests with streaming requests on graphql-transport-ws #1792

Merged
merged 12 commits into from
Apr 14, 2022

Conversation

kristjanvalur
Copy link
Contributor

(replaces closed #1739)

Various problems with single-response-requests existed as a result of their having a separate control
path from streaming requests. Single-response-requests are really just special cases of streaming requests
that deliver at most one Next message and need to behave as such.

Description

single-response-request are now handled as tasks and can be overlapped with other requests
on the same connection, can be cancelled, and share the same unique requests ID namespace.

Types of Changes

  • Core
  • Bugfix
  • New feature
  • Enhancement/optimization
  • Documentation

Issues Fixed or Closed by This PR

Checklist

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • I have tested the changes and verified that they work and don't break anything (as well as I can manage).

test overlapped single result queries
Single result operations are now executed on a task.
They can be cancelled like regular streamed operations.
They can be overlapped like regular streamed operations.
They don't have an associated generator, merely a task.
@codecov
Copy link

codecov bot commented Apr 4, 2022

Codecov Report

Merging #1792 (27694f3) into main (c775fd1) will increase coverage by 0.04%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main    #1792      +/-   ##
==========================================
+ Coverage   98.11%   98.15%   +0.04%     
==========================================
  Files         139      139              
  Lines        5250     5260      +10     
  Branches      957      958       +1     
==========================================
+ Hits         5151     5163      +12     
+ Misses         53       52       -1     
+ Partials       46       45       -1     

@kristjanvalur kristjanvalur changed the title Uniri single-response-requests with streaming requests on graphql-transport-ws Unify single-response-requests with streaming requests on graphql-transport-ws Apr 4, 2022
@botberry
Copy link
Member

botberry commented Apr 4, 2022

Thanks for adding the RELEASE.md file!

Here's a preview of the changelog:


This release fixes a number of problems with single-result-operations over
graphql-transport-ws protocol

  • operation IDs now share the same namespace as streaming operations
    meaning that they cannot be reused while the others are in operation

  • single-result-operations now run as tasks meaning that messages related
    to them can be overlapped with other messages on the websocket.

  • single-result-operations can be cancelled with the complete message.

  • IDs for single result and streaming result operations are now released
    once the operation is done, allowing them to be re-used later, as well as
    freeing up resources related to previous requests.


Here's the preview release card for twitter:

Here's the tweet text:

🆕 Release (next) is out! Thanks to @kristjanvalur for the PR 👏

Get it here 👉 https://github.com/strawberry-graphql/strawberry/releases/tag/(next)

@@ -285,6 +285,55 @@ async def test_duplicated_operation_ids(aiohttp_client):
assert data.extra == "Subscriber for sub1 already exists"


async def test_reused_operation_ids(aiohttp_client):
Copy link
Member

Choose a reason for hiding this comment

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

As these are fairly complicated tests, could you add some docstrings describing what functionality is being tested

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good Idea.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added docstrings.
It is a bit annoying that we have three identical sets of tests, testing internal functionality, that is in theory quite independent of the integration in use. Would it make sense to separate "integration" tests from unit tests?

Copy link
Member

Choose a reason for hiding this comment

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

cc @patrick91, I think we were discussing ideas for doing this last week

Copy link
Member

Choose a reason for hiding this comment

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

@kristjanvalur totally, I've opened up an issue for this: #1809

Copy link
Member

@patrick91 patrick91 left a comment

Choose a reason for hiding this comment

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

this looks great! thanks so much and sorry for the late review!

Comment on lines +174 to +193
if operation_type == OperationType.SUBSCRIPTION:
result_source = await self.schema.subscribe(
query=message.payload.query,
variable_values=message.payload.variables,
operation_name=message.payload.operationName,
context_value=context,
root_value=root_value,
)
else:
# create AsyncGenerator returning a single result
async def get_result_source():
yield await self.schema.execute(
query=message.payload.query,
variable_values=message.payload.variables,
context_value=context,
root_value=root_value,
operation_name=message.payload.operationName,
)

result_source = get_result_source()
Copy link
Member

Choose a reason for hiding this comment

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

maybe in a future PR we can move this to a classmethod to clean this method 😊

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

5 participants