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

Per-operation context + initial payload #93

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

AndreyMZ
Copy link

This pull request adds two features:

  1. Per-operation context - allows sharing any data between different calls to Subscription.publish for the same subscription (and the same connection).
  2. Initial payload - allows sending an arbitrary "initial" response to a client as soon as it is subscribed (before any call to Subscription.broadcast).

I use them like so (in schema.py):

import channels_graphql_ws
import graphene
from channels_graphql_ws.operation_context import OperationContext
from graphene import ResolveInfo

from .task import Task

class TaskLogChanged(channels_graphql_ws.Subscription):
    class Arguments:
        id = graphene.Argument(graphene.NonNull(graphene.ID))

    content = graphene.Field(graphene.NonNull(graphene.List(graphene.NonNull(graphene.String))))
    begin = graphene.Field(graphene.NonNull(graphene.Int))
    end = graphene.Field(graphene.NonNull(graphene.Int))

    class Meta:
        initial_payload = None

    @staticmethod
    def subscribe(root: None, info: ResolveInfo, id: str) -> Optional[List[str]]:
        task = Task(id)
        return [task.uuid]

    @classmethod
    def trigger(cls, task: Task) -> None:
        cls.broadcast_sync(group=task.uuid, payload=None)

    @staticmethod
    def publish(payload: None, info: ResolveInfo, id: str) -> Union[TaskLogChanged, object]:
        assert isinstance(info.context, OperationContext)
        saved_cursor: int = info.context.operation_context.get('cursor', 0)

        task = Task(id)
        content, new_cursor = task.get_log(saved_cursor)

        if new_cursor == saved_cursor:
            assert len(list(content)) == 0
            return TaskLogChanged.SKIP
        else:
            info.context.operation_context['cursor'] = new_cursor
            return TaskLogChanged(content=content, begin=saved_cursor, end=new_cursor)

Andrey Zelenchuk added 5 commits March 10, 2022 23:58
@fdev
Copy link

fdev commented May 28, 2022

@stmarkevich @sergey-komissarov @prokher is there something preventing this pull request from being merged? I'm eagerly waiting for the initial payload feature to become available. 🙏

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.

None yet

2 participants