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

GraphQL subscription sequence is not guaranteed #113

Closed
andrexus opened this issue Nov 22, 2023 · 3 comments · Fixed by #114
Closed

GraphQL subscription sequence is not guaranteed #113

andrexus opened this issue Nov 22, 2023 · 3 comments · Fixed by #114

Comments

@andrexus
Copy link

HI,

thanks for a great library!

today I started testing the client with subscriptions and found out that sometimes subscription completes before emitting the last message.

After investigation I found the lines that are responsible for this behavior

go func() {

go func() {
	if err := sc.protocol.OnMessage(subContext, *sub, message); err != nil {
		sc.errorChan <- err
	}

	sc.checkSubscriptionStatuses(subContext)
}()

It seems that every message is handled in a separate goroutine, thus the order of all incoming messages (incl. errors and complete message) is not anyhow guaranteed which can be a problem in certain scenarios.

Current workaround for original issue where complete is coming before the last message is :

.OnSubscriptionComplete(func(sub graphql.Subscription) {
  handler := sub.GetHandler()
  time.Sleep(1 * time.Second) // hope for the best
  handler(nil, io.EOF)
})

that's however is quite nasty and does not anyway guarantee the message order.

How to deal with this? Does it make sense to add a configuration parameter that enforces the correct execution order even sacrificing some performance?

@hgiasac
Copy link

hgiasac commented Nov 23, 2023

Adding a sync mode to subscription configs that execute the OnMessage callback in sequence is possible. However, it may not solve the unordered messages from the server, for example, the server emits the completed message before the error message.

@andrexus
Copy link
Author

You are right. There is no way to control the sequence of the messages that the server emits, but it would be nice to have this option, at least on the client side.

The current subscription API doesn't give the subscriber an option to know when its subscription is completed. In my example, I've attempted to solve this problem by calling a subscription's handler with the 'io.EOF' error. This way, the subscriber knows when its subscription is completed. In my test case, the server sends only one message and then completes the subscription. However, on the client side, the result is not consistent: sometimes it receives the message, and sometimes it does not. This depends on which message is processed first: 'next' or 'complete'.

@hgiasac
Copy link

hgiasac commented Nov 25, 2023

@andrexus would you mind verifying this PR and confirm if it works for your use case? Thanks

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 a pull request may close this issue.

2 participants