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

Subscription support is currently deactivated by throwing a schema_exception #67

Closed
soustelle opened this issue Aug 25, 2019 · 1 comment · Fixed by #78
Closed

Subscription support is currently deactivated by throwing a schema_exception #67

soustelle opened this issue Aug 25, 2019 · 1 comment · Fixed by #78
Assignees
Labels
question Further information is requested

Comments

@soustelle
Copy link

soustelle commented Aug 25, 2019

When taking in account #24, #26, #31 as proposed by GitHub and thus also the existence of Request::subcribe(.) and Request::unsubscribe(.), I still observe that aside from a test fragments in "TodayTests.cpp" there is no documentation or example of how to make use of these methods within the graphql::service framework. Probably I don't see the forest for the trees.

Currently (v3.0.2) any query along the lines

subscription sPersons {
    change(rid:"70-20-91-04" ) {
         rid
         status 
         person {
             id
             name
         }
    }
}

will be aborted with the message "Unexpected Subscription" (in GraphqlService.cpp +1631)

My current idea wrt subscription requests is to return a status (e.g. "registered") along with an empty changeSet after having written the subscription request to the database, since waiting for dataset changes within the service framework would block the main loop and thus require to implement it reentrant or multi-threaded.
A second thread or process would wait for notifications from the database, calculate the changeset and send it to the client using the same channel as was used for the request, so a client would be able to receive synchronous and asynchronous messages by the same channel. Yet in order to create asynchronous replies, the selection set as defined in the subscription query is needed, since the field composition and order are controlled by the client request. However, that information is not available in the standard "FieldParams" parameter as passed to the service::Object getter methods.

@wravery wravery added the question Further information is requested label Aug 31, 2019
@wravery
Copy link
Contributor

wravery commented Aug 31, 2019

This could use some better documentation, but it's effectively by design. Subscriptions have to go through Request::subscribe rather than Request::resolve and get invoked asynchronously in response to matching calls to Request::deliver.

My own prototypes have used a separate path to create subscriptions (mostly using Relay, which calls a different method on the Network object), but per issue #34, Apollo handles them all through the same channel by default. If you're doing something like that, you can use Request::findOperationDefinition to determine whether the query you just parsed is a subscription or not and route it appropriately.

I'll keep this open as a documentation request.

@wravery wravery self-assigned this Aug 31, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants