Skip to content

Commit da9c744

Browse files
committed
Make WorkspaceWatcher
1 parent 0551613 commit da9c744

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

codersdk/client.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"strings"
1313

1414
"golang.org/x/xerrors"
15+
"nhooyr.io/websocket"
1516

1617
"github.com/coder/coder/coderd/httpapi"
1718
"github.com/coder/coder/coderd/httpmw"
@@ -80,6 +81,41 @@ func (c *Client) Request(ctx context.Context, method, path string, body interfac
8081
return resp, err
8182
}
8283

84+
// request performs an HTTP request with the body provided.
85+
// The caller is responsible for closing the response body.
86+
func (c *Client) websocket(ctx context.Context, path string) (*websocket.Conn, error) {
87+
serverURL, err := c.URL.Parse(path)
88+
if err != nil {
89+
return nil, xerrors.Errorf("parse url: %w", err)
90+
}
91+
92+
apiURL, err := url.Parse(serverURL.String())
93+
apiURL.Scheme = "ws"
94+
if serverURL.Scheme == "https" {
95+
apiURL.Scheme = "wss"
96+
}
97+
apiURL.Path = path
98+
99+
client := &http.Client{
100+
Jar: c.HTTPClient.Jar,
101+
}
102+
cookies := append(client.Jar.Cookies(c.URL), &http.Cookie{
103+
Name: httpmw.AuthCookie,
104+
Value: c.SessionToken,
105+
})
106+
client.Jar.SetCookies(c.URL, cookies)
107+
108+
//nolint:bodyclose
109+
conn, _, err := websocket.Dial(context.Background(), apiURL.String(), &websocket.DialOptions{
110+
HTTPClient: c.HTTPClient,
111+
})
112+
if err != nil {
113+
return nil, xerrors.Errorf("dial websocket: %w", err)
114+
}
115+
116+
return conn, nil
117+
}
118+
83119
// readBodyAsError reads the response as an httpapi.Message, and
84120
// wraps it in a codersdk.Error type for easy marshaling.
85121
func readBodyAsError(res *http.Response) error {

codersdk/workspaces.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import (
99

1010
"github.com/google/uuid"
1111
"golang.org/x/xerrors"
12+
"nhooyr.io/websocket"
13+
"nhooyr.io/websocket/wsjson"
1214

1315
"github.com/coder/coder/coderd/database"
1416
)
@@ -98,6 +100,40 @@ func (c *Client) WorkspaceBuildByName(ctx context.Context, workspace uuid.UUID,
98100
return workspaceBuild, json.NewDecoder(res.Body).Decode(&workspaceBuild)
99101
}
100102

103+
type WorkspaceWatcher struct {
104+
conn *websocket.Conn
105+
}
106+
107+
func (w *WorkspaceWatcher) Read(ctx context.Context) (Workspace, error) {
108+
var ws Workspace
109+
err := wsjson.Read(ctx, w.conn, &ws)
110+
if err != nil {
111+
return ws, xerrors.Errorf("read workspace: %w")
112+
}
113+
114+
return ws, nil
115+
}
116+
117+
func (w *WorkspaceWatcher) Close() error {
118+
err := w.conn.Close(websocket.StatusNormalClosure, "")
119+
if err != nil {
120+
return xerrors.Errorf("closing workspace watcher: %w", err)
121+
}
122+
123+
return nil
124+
}
125+
126+
func (c *Client) WorkspaceWatcher(ctx context.Context, id uuid.UUID) (*WorkspaceWatcher, error) {
127+
conn, err := c.websocket(ctx, fmt.Sprintf("/api/v2/workspaces/%s/watch", id))
128+
if err != nil {
129+
return nil, err
130+
}
131+
132+
return &WorkspaceWatcher{
133+
conn: conn,
134+
}, nil
135+
}
136+
101137
// UpdateWorkspaceAutostartRequest is a request to update a workspace's autostart schedule.
102138
type UpdateWorkspaceAutostartRequest struct {
103139
Schedule string `json:"schedule"`

0 commit comments

Comments
 (0)