Skip to content

Commit

Permalink
support the graphql-ws subprotocol
Browse files Browse the repository at this point in the history
* The protocol for message exchange employed over a websocket
  connection is referred as the subprotocol.
* We currently use the `graphql-ws` subprotocol for serving GraphQL
  subscriptions over websockets.
* The JavaScript library which implements the `grahpql-ws` subprotocol
  is no longer maintained.
* This PR adds support for the `graphql-transport-ws` subprotocol,
  allowing us to migrate our client away from this unsupported library.
* This requires graphql-python/graphql-ws#65
  and a new release of the Python graphql-ws library to work.
  • Loading branch information
oliver-sanders committed Aug 9, 2023
1 parent 7a6e1b9 commit 9d91564
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions cylc/uiserver/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

from graphene_tornado.tornado_graphql_handler import TornadoGraphQLHandler
from graphql import get_default_backend
from graphql_ws.constants import GRAPHQL_WS
from graphql_ws.constants import GRAPHQL_WS, TRANSPORT_WS_PROTOCOL
from jupyter_server.base.handlers import JupyterHandler
from tornado import web, websocket
from tornado.ioloop import IOLoop
Expand All @@ -36,9 +36,10 @@
from cylc.uiserver.authorise import Authorization, AuthorizationMiddleware
from cylc.uiserver.resolvers import Resolvers
from cylc.uiserver.websockets import authenticated as websockets_authenticated
from cylc.uiserver.websockets.tornado import TornadoSubscriptionServer

if TYPE_CHECKING:
from graphql.execution import ExecutionResult
from cylc.uiserver.websockets.tornado import TornadoSubscriptionServer


ME = getpass.getuser()
Expand Down Expand Up @@ -367,11 +368,15 @@ class SubscriptionHandler(CylcAppHandler, websocket.WebSocketHandler):
# No authorization decorators here, auth handled in AuthorizationMiddleware
def initialize(self, sub_server, resolvers, sub_statuses=None):
self.queue: Queue = Queue(100)
self.subscription_server: TornadoSubscriptionServer = sub_server
self.subscription_server: 'TornadoSubscriptionServer' = sub_server
self.resolvers: Resolvers = resolvers
self.sub_statuses: Dict = sub_statuses

def select_subprotocol(self, subprotocols):
if TRANSPORT_WS_PROTOCOL in subprotocols:
# use graphql-transport-ws out of preference
return TRANSPORT_WS_PROTOCOL
# fallback to graphql-ws if required
return GRAPHQL_WS

@websockets_authenticated
Expand Down Expand Up @@ -415,5 +420,6 @@ def context(self):
self.get_current_user()
).get('name'),
'ops_queue': {},
'sub_statuses': self.sub_statuses
'sub_statuses': self.sub_statuses,
'subprotocols': [self.selected_subprotocol],
}

0 comments on commit 9d91564

Please sign in to comment.