mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
fix(cli): port-forward: update workspace last_used_at (#12659)
This PR updates the coder port-forward command to periodically inform coderd that the workspace is being used: - Adds workspaceusage.Tracker which periodically batch-updates workspace LastUsedAt - Adds coderd endpoint to signal workspace usage - Updates coder port-forward to periodically hit this endpoint - Modifies BatchUpdateWorkspacesLastUsedAt to avoid overwriting with stale data Co-authored-by: Danny Kopping <danny@coder.com>
This commit is contained in:
co-authored by
Danny Kopping
parent
d789a60d47
commit
92aa1eba97
@@ -136,6 +136,8 @@ func (r *RootCmd) portForward() *serpent.Command {
|
||||
listeners[i] = l
|
||||
}
|
||||
|
||||
stopUpdating := client.UpdateWorkspaceUsageContext(ctx, workspace.ID)
|
||||
|
||||
// Wait for the context to be canceled or for a signal and close
|
||||
// all listeners.
|
||||
var closeErr error
|
||||
@@ -156,6 +158,7 @@ func (r *RootCmd) portForward() *serpent.Command {
|
||||
}
|
||||
|
||||
cancel()
|
||||
stopUpdating()
|
||||
closeAllListeners()
|
||||
}()
|
||||
|
||||
|
||||
+28
-1
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/coder/coder/v2/coderd/coderdtest"
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
"github.com/coder/coder/v2/coderd/database/dbfake"
|
||||
"github.com/coder/coder/v2/coderd/database/dbtime"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/pty/ptytest"
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
@@ -96,7 +97,12 @@ func TestPortForward(t *testing.T) {
|
||||
// Setup agent once to be shared between test-cases (avoid expensive
|
||||
// non-parallel setup).
|
||||
var (
|
||||
client, db = coderdtest.NewWithDatabase(t, nil)
|
||||
wuTick = make(chan time.Time)
|
||||
wuFlush = make(chan int, 1)
|
||||
client, db = coderdtest.NewWithDatabase(t, &coderdtest.Options{
|
||||
WorkspaceUsageTrackerTick: wuTick,
|
||||
WorkspaceUsageTrackerFlush: wuFlush,
|
||||
})
|
||||
admin = coderdtest.CreateFirstUser(t, client)
|
||||
member, memberUser = coderdtest.CreateAnotherUser(t, client, admin.OrganizationID)
|
||||
workspace = runAgent(t, client, memberUser.ID, db)
|
||||
@@ -148,6 +154,13 @@ func TestPortForward(t *testing.T) {
|
||||
cancel()
|
||||
err = <-errC
|
||||
require.ErrorIs(t, err, context.Canceled)
|
||||
|
||||
flushCtx := testutil.Context(t, testutil.WaitShort)
|
||||
testutil.RequireSendCtx(flushCtx, t, wuTick, dbtime.Now())
|
||||
_ = testutil.RequireRecvCtx(flushCtx, t, wuFlush)
|
||||
updated, err := client.Workspace(context.Background(), workspace.ID)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, updated.LastUsedAt, workspace.LastUsedAt)
|
||||
})
|
||||
|
||||
t.Run(c.name+"_TwoPorts", func(t *testing.T) {
|
||||
@@ -196,6 +209,13 @@ func TestPortForward(t *testing.T) {
|
||||
cancel()
|
||||
err = <-errC
|
||||
require.ErrorIs(t, err, context.Canceled)
|
||||
|
||||
flushCtx := testutil.Context(t, testutil.WaitShort)
|
||||
testutil.RequireSendCtx(flushCtx, t, wuTick, dbtime.Now())
|
||||
_ = testutil.RequireRecvCtx(flushCtx, t, wuFlush)
|
||||
updated, err := client.Workspace(context.Background(), workspace.ID)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, updated.LastUsedAt, workspace.LastUsedAt)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -257,6 +277,13 @@ func TestPortForward(t *testing.T) {
|
||||
cancel()
|
||||
err := <-errC
|
||||
require.ErrorIs(t, err, context.Canceled)
|
||||
|
||||
flushCtx := testutil.Context(t, testutil.WaitShort)
|
||||
testutil.RequireSendCtx(flushCtx, t, wuTick, dbtime.Now())
|
||||
_ = testutil.RequireRecvCtx(flushCtx, t, wuFlush)
|
||||
updated, err := client.Workspace(context.Background(), workspace.ID)
|
||||
require.NoError(t, err)
|
||||
require.Greater(t, updated.LastUsedAt, workspace.LastUsedAt)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,7 @@ import (
|
||||
stringutil "github.com/coder/coder/v2/coderd/util/strings"
|
||||
"github.com/coder/coder/v2/coderd/workspaceapps"
|
||||
"github.com/coder/coder/v2/coderd/workspaceapps/appurl"
|
||||
"github.com/coder/coder/v2/coderd/workspaceusage"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/codersdk/drpc"
|
||||
"github.com/coder/coder/v2/cryptorand"
|
||||
@@ -968,6 +969,13 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
|
||||
purger := dbpurge.New(ctx, logger, options.Database)
|
||||
defer purger.Close()
|
||||
|
||||
// Updates workspace usage
|
||||
tracker := workspaceusage.New(options.Database,
|
||||
workspaceusage.WithLogger(logger.Named("workspace_usage_tracker")),
|
||||
)
|
||||
options.WorkspaceUsageTracker = tracker
|
||||
defer tracker.Close()
|
||||
|
||||
// Wrap the server in middleware that redirects to the access URL if
|
||||
// the request is not to a local IP.
|
||||
var handler http.Handler = coderAPI.RootHandler
|
||||
|
||||
Reference in New Issue
Block a user