| 218 | } |
| 219 | |
| 220 | func (c *Client) WatchWorkspace(ctx context.Context, id uuid.UUID) (<-chan Workspace, error) { |
| 221 | ctx, span := tracing.StartSpan(ctx) |
| 222 | defer span.End() |
| 223 | //nolint:bodyclose |
| 224 | res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/workspaces/%s/watch", id), nil) |
| 225 | if err != nil { |
| 226 | return nil, err |
| 227 | } |
| 228 | if res.StatusCode != http.StatusOK { |
| 229 | return nil, ReadBodyAsError(res) |
| 230 | } |
| 231 | nextEvent := ServerSentEventReader(ctx, res.Body) |
| 232 | |
| 233 | wc := make(chan Workspace, 256) |
| 234 | go func() { |
| 235 | defer close(wc) |
| 236 | defer res.Body.Close() |
| 237 | |
| 238 | for { |
| 239 | select { |
| 240 | case <-ctx.Done(): |
| 241 | return |
| 242 | default: |
| 243 | sse, err := nextEvent() |
| 244 | if err != nil { |
| 245 | return |
| 246 | } |
| 247 | if sse.Type != ServerSentEventTypeData { |
| 248 | continue |
| 249 | } |
| 250 | var ws Workspace |
| 251 | b, ok := sse.Data.([]byte) |
| 252 | if !ok { |
| 253 | return |
| 254 | } |
| 255 | err = json.Unmarshal(b, &ws) |
| 256 | if err != nil { |
| 257 | return |
| 258 | } |
| 259 | select { |
| 260 | case <-ctx.Done(): |
| 261 | return |
| 262 | case wc <- ws: |
| 263 | } |
| 264 | } |
| 265 | } |
| 266 | }() |
| 267 | |
| 268 | return wc, nil |
| 269 | } |
| 270 | |
| 271 | type UpdateWorkspaceRequest struct { |
| 272 | Name string `json:"name,omitempty" validate:"username"` |