mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
perf: reduce number of queries made by /api/v2/workspaceagents/{id} (#21522)
Relates to https://github.com/coder/internal/issues/1214 The `ExtractWorkspaceAgentParam` middleware ends up making 4 database queries to follow the chain of `WorkspaceAgent` -> `WorkspaceResource` -> `ProvisionerJob` -> `WorkspaceBuild` -- but then dropping all that hard work on the floor. The `api.workspaceAgent` handler that references this middleware then has to do all of that work again, plus one more query to get the related `User` so we can get the username. This pattern is also mirrored in `getDatabaseTerminal` but without the middleware. This PR: * Adds a new query `GetWorkspaceAgentAndWorkspaceByID` to fetch all this information at once to avoid the multiple round-trips, * Updates the existing usage of `GetWorkspaceAgentByID` to this new query instead, * Updates `ExtractWorkspaceAgentParam` to also store the workspace in the request context Dalibo: [0.63ms](https://explain.dalibo.com/plan/40bb597f3539gc6c)
This commit is contained in:
@@ -148,7 +148,7 @@ func (p *DBTokenProvider) Issue(ctx context.Context, rw http.ResponseWriter, r *
|
||||
|
||||
aReq.dbReq = dbReq // Update audit request.
|
||||
|
||||
token.UserID = dbReq.User.ID
|
||||
token.UserID = dbReq.UserID
|
||||
token.WorkspaceID = dbReq.Workspace.ID
|
||||
token.AgentID = dbReq.Agent.ID
|
||||
if dbReq.AppURL != nil {
|
||||
|
||||
@@ -188,10 +188,10 @@ func (r Request) Check() error {
|
||||
|
||||
type databaseRequest struct {
|
||||
Request
|
||||
// User is the user that owns the app.
|
||||
User database.User
|
||||
// UserID is the ID of the user that owns the app.
|
||||
UserID uuid.UUID
|
||||
// Workspace is the workspace that the app is in.
|
||||
Workspace database.Workspace
|
||||
Workspace database.WorkspaceTable
|
||||
// Agent is the agent that the app is running on.
|
||||
Agent database.WorkspaceAgent
|
||||
// App is the app that the user is trying to access.
|
||||
@@ -420,8 +420,8 @@ func (r Request) getDatabase(ctx context.Context, db database.Store) (*databaseR
|
||||
|
||||
return &databaseRequest{
|
||||
Request: r,
|
||||
User: user,
|
||||
Workspace: workspace,
|
||||
UserID: user.ID,
|
||||
Workspace: workspace.WorkspaceTable(),
|
||||
Agent: agent,
|
||||
App: app,
|
||||
AppURL: appURLParsed,
|
||||
@@ -443,40 +443,16 @@ func (r Request) getDatabaseTerminal(ctx context.Context, db database.Store) (*d
|
||||
}
|
||||
|
||||
var err error
|
||||
agent, err := db.GetWorkspaceAgentByID(ctx, agentID)
|
||||
aw, err := db.GetWorkspaceAgentAndWorkspaceByID(ctx, agentID)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get workspace agent %q: %w", agentID, err)
|
||||
}
|
||||
|
||||
// Get the corresponding resource.
|
||||
res, err := db.GetWorkspaceResourceByID(ctx, agent.ResourceID)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get workspace agent resource %q: %w", agent.ResourceID, err)
|
||||
}
|
||||
|
||||
// Get the corresponding workspace build.
|
||||
build, err := db.GetWorkspaceBuildByJobID(ctx, res.JobID)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get workspace build by job ID %q: %w", res.JobID, err)
|
||||
}
|
||||
|
||||
// Get the corresponding workspace.
|
||||
workspace, err := db.GetWorkspaceByID(ctx, build.WorkspaceID)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get workspace %q: %w", build.WorkspaceID, err)
|
||||
}
|
||||
|
||||
// Get the workspace's owner.
|
||||
user, err := db.GetUserByID(ctx, workspace.OwnerID)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get user %q: %w", workspace.OwnerID, err)
|
||||
return nil, xerrors.Errorf("get workspace agent %q with workspace: %w", agentID, err)
|
||||
}
|
||||
|
||||
return &databaseRequest{
|
||||
Request: r,
|
||||
User: user,
|
||||
Workspace: workspace,
|
||||
Agent: agent,
|
||||
UserID: aw.WorkspaceTable.OwnerID,
|
||||
Workspace: aw.WorkspaceTable,
|
||||
Agent: aw.WorkspaceAgent,
|
||||
AppURL: nil,
|
||||
AppSharingLevel: database.AppSharingLevelOwner,
|
||||
}, nil
|
||||
|
||||
Reference in New Issue
Block a user