From 943736fcd651a9aa6994588c92e6e7380a34af39 Mon Sep 17 00:00:00 2001 From: Bingdom Date: Wed, 2 Oct 2024 01:15:30 +1000 Subject: [PATCH] Added subscription unsubscribing info (#3654) * Added subscription unsubscribing info * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fixed typos * Follow python naming convention --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Jonathan Ehwald --- docs/general/subscriptions.md | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/docs/general/subscriptions.md b/docs/general/subscriptions.md index 7d4161bdc4..6363fc3051 100644 --- a/docs/general/subscriptions.md +++ b/docs/general/subscriptions.md @@ -254,6 +254,55 @@ schema = strawberry.Schema(query=Query, subscription=Subscription) [pep-525]: https://www.python.org/dev/peps/pep-0525/ +## Unsubscribing subscriptions + +In GraphQL, it is possible to unsubscribe from a subscription. Strawberry +supports this behaviour, and is done using a `try...except` block. + +In Apollo-client, closing a subscription can be achieved like the following: + +```javascript +const client = useApolloClient(); +const subscriber = client.subscribe({query: ...}).subscribe({...}) +// ... +// done with subscription. now unsubscribe +subscriber.unsubscribe(); +``` + +Strawberry can easily capture when a subscriber unsubscribes using an +`asyncio.CancelledError` exception. + +```python +import asyncio +from typing import AsyncGenerator +from uuid import uuid4 + +import strawberry + +# track active subscribers +event_messages = {} + + +@strawberry.type +class Subscription: + @strawberry.subscription + async def message(self) -> AsyncGenerator[int, None]: + try: + subscription_id = uuid4() + + event_messages[subscription_id] = [] + + while True: + if len(event_messages[subscription_id]) > 0: + yield event_messages[subscription_id] + event_messages[subscription_id].clear() + + await asyncio.sleep(1) + except asyncio.CancelledError: + # stop listening to events + del event_messages[subscription_id] +``` + ## GraphQL over WebSocket protocols Strawberry support both the legacy