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

improve the subscription life cycle event and add new settings #82

Merged
merged 6 commits into from
Mar 16, 2023

Conversation

hgiasac
Copy link

@hgiasac hgiasac commented Mar 10, 2023

Fix #80
The PR improves the subscription client with a new event and settings

Event

// OnSubscriptionComplete event is triggered when the subscription receives 
// a terminated message from the server
client.OnSubscriptionComplete(fn func(sub Subscription))

Settings

client.
    // the client should exit when all subscriptions were closed, default true
    WithExitWhenNoSubscription(false).
    // WithRetryStatusCodes allow retry the subscription connection when receiving one of these codes
    // the input parameter can be number string or range, e.g 4000-5000 
    WithRetryStatusCodes([]string{"4000", "4000-4050"})

@hgiasac hgiasac marked this pull request as ready for review March 11, 2023 16:46
@hgiasac
Copy link
Author

hgiasac commented Mar 11, 2023

@sermojohn this improvement is for the subscription run flow that you suggested. There is no recursive Run call in goroutines. All events are centralized in the main loop to control the retry behavior.

@@ -257,58 +306,75 @@ type handlerFunc func(data []byte, err error) error

// Subscription stores the subscription declaration and its state
type Subscription struct {
id string

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference between id and the key, so to have both per subscription?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see but looking up the subscription either by the key or the id seems complicating, no?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can separate them into 2 functions. However, I just unify the search function into a single function. We still need to find the subscription by id internally but the user only has the original id before resetting.

@sermojohn
Copy link

@sermojohn this improvement is for the subscription run flow that you suggested. There is no recursive Run call in goroutines. All events are centralized in the main loop to control the retry behavior.

Nice improvement!

I ran our test-suite, but having some issue. This could be due to the synchronisation, I need to check further.

How should the library handle Subscribe calls happening during or after close is called?
In my test, here is the error I get:

failed to write JSON message: failed to get writer: WebSocket closed: read timed out: context canceled

@hgiasac
Copy link
Author

hgiasac commented Mar 13, 2023

I assume that the client should wait until the cleanup process is done. Anyway, I'll fix this

@@ -634,14 +634,14 @@ func (sc *SubscriptionClient) doRaw(query string, variables map[string]interface
// if the websocket client is running and acknowledged by the server
// start subscription immediately
ctx := sc.getContext()
if ctx != nil && ctx.GetAcknowledge() {
if ctx != nil && sc.getClientStatus() == scStatusRunning && ctx.GetAcknowledge() {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!
Taken that we do not lock, there are still chances that Subscribe will be triggered on a closed connection.
But this seems correct to me, based on existing logic.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't found any absolute approach to solve this race condition issue. However, the chance is low except the user tries to close and run repeatedly in parallel. IMO it's better to create a new client and subscribe because all subscriptions were cleared after the client was closed. There isn't any benefit over the new client.

@hgiasac hgiasac merged commit 0acd9d9 into master Mar 16, 2023
@hgiasac hgiasac deleted the subscription-lifecycle-fixes branch March 16, 2023 16:36
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.

SubscriptionClient OnDisconnected() regression in v0.9.1
2 participants