Skip to content

Commit

Permalink
fix subscription hanging on error and add a stop subscription option …
Browse files Browse the repository at this point in the history
…inside the callback (shurcooL#39)

* fix the deadlock issue that the subscription client can't receive error events from the channel.
* close the connection when there is no running subscription
* add a particular error that stops the subscription inside the callback
  • Loading branch information
hgiasac authored Jul 5, 2022
1 parent fd4ee75 commit 7e9cc29
Show file tree
Hide file tree
Showing 5 changed files with 321 additions and 111 deletions.
22 changes: 20 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ For more information, see package [`github.com/shurcooL/githubv4`](https://githu
- [Subscription](#subscription)
- [Usage](#usage-1)
- [Subscribe](#subscribe)
- [Stop the subscription](#stop-the-subscription)
- [Authentication](#authentication-1)
- [Options](#options)
- [Events](#events)
Expand Down Expand Up @@ -490,13 +491,30 @@ subscriptionId, err := client.Subscribe(&query, nil, func(dataValue *json.RawMes
fmt.Println(query.Me.Name)

// Output: Luke Skywalker
return nil
})

if err != nil {
// Handle error.
}
```
#### Stop the subscription
You can programmatically stop the subscription while the client is running by using the `Unsubscribe` method, or returning a special error to stop it in the callback.
```Go
subscriptionId, err := client.Subscribe(&query, nil, func(dataValue *json.RawMessage, errValue error) error {
// ...
// return this error to stop the subscription in the callback
return graphql.ErrSubscriptionStopped
})

if err != nil {
// Handle error.
}

// you can unsubscribe the subscription while the client is running
// unsubscribe the subscription while the client is running with the subscription ID
client.Unsubscribe(subscriptionId)
```
Expand Down Expand Up @@ -537,7 +555,7 @@ client.
// OnConnected event is triggered when the websocket connected to GraphQL server sucessfully
client.OnConnected(fn func())

// OnDisconnected event is triggered when the websocket server was stil down after retry timeout
// OnDisconnected event is triggered when the websocket client was disconnected
client.OnDisconnected(fn func())

// OnConnected event is triggered when there is any connection error. This is bottom exception handler level
Expand Down
13 changes: 10 additions & 3 deletions example/subscription/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func startSubscription() error {
} `graphql:"helloSaid"`
}

_, err := client.Subscribe(sub, nil, func(data *json.RawMessage, err error) error {
subId, err := client.Subscribe(sub, nil, func(data *json.RawMessage, err error) error {

if err != nil {
log.Println(err)
Expand All @@ -64,15 +64,22 @@ func startSubscription() error {
panic(err)
}

// automatically unsubscribe after 10 seconds
go func() {
time.Sleep(10 * time.Second)
client.Unsubscribe(subId)
}()

return client.Run()
}

// send hello mutations to the graphql server, so the subscription client can receive messages
func startSendHello() {

client := graphql.NewClient(getServerEndpoint(), &http.Client{Transport: http.DefaultTransport})

for i := 0; i < 120; i++ {
// stop until the subscription client is connected
time.Sleep(time.Second)
for i := 0; i < 10; i++ {
/*
mutation ($msg: String!) {
sayHello(msg: $msg) {
Expand Down
4 changes: 2 additions & 2 deletions example/subscription/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ package main

func main() {
go startServer()
go startSubscription()
startSendHello()
go startSendHello()
startSubscription()
}
Loading

0 comments on commit 7e9cc29

Please sign in to comment.