fix(coderd): prevent lost messages in watchWorkspaceAgentMetadata (#7934)

* fix(codersdk): wait for subscription in WatchWorkspaceAgentMetadata
* fix(coderd): subscribe before sending initial metadata event
* test(coderd): add retries to TestWorkspaceAgent_Metadata to avoid flake
This commit is contained in:
Mathias Fredriksson
2023-06-13 12:21:06 +00:00
committed by GitHub
parent 518300a26c
commit 1d0fae83a2
3 changed files with 51 additions and 17 deletions
+17 -2
View File
@@ -304,6 +304,7 @@ func (c *Client) WatchWorkspaceAgentMetadata(ctx context.Context, id uuid.UUID)
metadataChan := make(chan []WorkspaceAgentMetadata, 256)
ready := make(chan struct{})
watch := func() error {
res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaceagents/%s/watch-metadata", id), nil)
if err != nil {
@@ -316,12 +317,12 @@ func (c *Client) WatchWorkspaceAgentMetadata(ctx context.Context, id uuid.UUID)
nextEvent := ServerSentEventReader(ctx, res.Body)
defer res.Body.Close()
firstEvent := true
for {
select {
case <-ctx.Done():
return ctx.Err()
default:
break
}
sse, err := nextEvent()
@@ -329,6 +330,11 @@ func (c *Client) WatchWorkspaceAgentMetadata(ctx context.Context, id uuid.UUID)
return err
}
if firstEvent {
close(ready) // Only close ready after the first event is received.
firstEvent = false
}
b, ok := sse.Data.([]byte)
if !ok {
return xerrors.Errorf("unexpected data type: %T", sse.Data)
@@ -358,9 +364,18 @@ func (c *Client) WatchWorkspaceAgentMetadata(ctx context.Context, id uuid.UUID)
errorChan := make(chan error, 1)
go func() {
defer close(errorChan)
errorChan <- watch()
err := watch()
select {
case <-ready:
default:
close(ready) // Error before first event.
}
errorChan <- err
}()
// Wait until first event is received and the subscription is registered.
<-ready
return metadataChan, errorChan
}