Skip to content

Commit

Permalink
Trigger unwatched event instead of presence-changed event during detach
Browse files Browse the repository at this point in the history
  • Loading branch information
chacha912 committed Jul 31, 2023
1 parent 680c900 commit 27e541c
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 21 deletions.
5 changes: 5 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,9 @@ func (c *Client) Watch(
case types.DocumentsUnwatchedEvent:
p := doc.Presence(cli.String())
doc.RemoveOnlineClient(cli.String())
if p == nil {
return nil, nil
}

return &WatchResponse{
Type: DocumentUnwatched,
Expand Down Expand Up @@ -521,6 +524,8 @@ func (c *Client) Watch(
t := PresenceChanged
if e.Type == document.WatchedEvent {
t = DocumentWatched
} else if e.Type == document.UnwatchedEvent {
t = DocumentUnwatched
}
rch <- WatchResponse{Type: t, Presences: e.Presences}
case <-ctx.Done():
Expand Down
4 changes: 4 additions & 0 deletions pkg/document/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ const (
// enabling real-time synchronization.
WatchedEvent DocEventType = "watched"

// UnwatchedEvent means that the client has disconnected from the server,
// disabling real-time synchronization.
UnwatchedEvent DocEventType = "unwatched"

// PresenceChangedEvent means that the presences of the clients who are editing
// the document have changed.
PresenceChangedEvent DocEventType = "presence-changed"
Expand Down
32 changes: 22 additions & 10 deletions pkg/document/internal_document.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,17 +257,29 @@ func (d *InternalDocument) ApplyChanges(changes ...*change.Change) ([]DocEvent,
if c.PresenceChange() != nil {
clientID := c.ID().ActorID().String()
if _, ok := d.onlineClients.Load(clientID); ok {
event := DocEvent{
Type: PresenceChangedEvent,
Presences: map[string]innerpresence.Presence{
clientID: c.PresenceChange().Presence,
},
switch c.PresenceChange().ChangeType {
case innerpresence.Put:
eventType := PresenceChangedEvent
if !d.presences.Has(clientID) {
eventType = WatchedEvent
}
event := DocEvent{
Type: eventType,
Presences: map[string]innerpresence.Presence{
clientID: c.PresenceChange().Presence,
},
}
events = append(events, event)
case innerpresence.Clear:
event := DocEvent{
Type: UnwatchedEvent,
Presences: map[string]innerpresence.Presence{
clientID: d.Presence(clientID),
},
}
events = append(events, event)
d.RemoveOnlineClient(clientID)
}

if !d.presences.Has(clientID) {
event.Type = WatchedEvent
}
events = append(events, event)
}
}

Expand Down
15 changes: 4 additions & 11 deletions test/integration/presence_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ func TestPresence(t *testing.T) {
})
}

if len(responsePairs) == 4 {
if len(responsePairs) == 3 {
return
}
}
Expand Down Expand Up @@ -285,23 +285,16 @@ func TestPresence(t *testing.T) {

// 05. Unwatch the second client's document.
expected = append(expected, watchResponsePair{
Type: client.PresenceChanged,
Type: client.DocumentUnwatched,
Presences: map[string]innerpresence.Presence{
c2.ID().String(): nil,
c2.ID().String(): d2.MyPresence(),
},
})
assert.NoError(t, c2.Detach(ctx, d2))
assert.NoError(t, c1.Sync(ctx, client.WithDocKey(helper.TestDocKey(t))))
wgEvents.Wait()

expected = append(expected, watchResponsePair{
Type: client.DocumentUnwatched,
Presences: map[string]innerpresence.Presence{
c2.ID().String(): nil,
},
})
cancel2()

wgEvents.Wait()
assert.Equal(t, expected, responsePairs)
})

Expand Down

0 comments on commit 27e541c

Please sign in to comment.