- Notifications
You must be signed in to change notification settings - Fork1k
feat(coderd): implement task to app linking#20237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
base:mafredri/feat-coderd-tasks-data-model-split4_split_split
Are you sure you want to change the base?
Changes fromall commits
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1964,18 +1964,41 @@ func (s *server) completeWorkspaceBuildJob(ctx context.Context, job database.Pro | ||
} | ||
appIDs := make([]string, 0) | ||
agentIDByAppID := make(map[string]uuid.UUID) | ||
agentTimeouts := make(map[time.Duration]bool) // A set of agent timeouts. | ||
// This could be a bulk insert to improve performance. | ||
for _, protoResource := range jobType.WorkspaceBuild.Resources { | ||
for _, protoAgent := range protoResource.GetAgents() { | ||
if protoAgent == nil { | ||
continue | ||
} | ||
// By default InsertWorkspaceResource ignores the protoAgent.Id | ||
// and generates a new one, but we will insert these using the | ||
// InsertWorkspaceResourceWithAgentIDsFromProto option so that | ||
// we can properly map agent IDs to app IDs. This is needed for | ||
// task linking. | ||
agentID := uuid.New() | ||
protoAgent.Id = agentID.String() | ||
dur := time.Duration(protoAgent.GetConnectionTimeoutSeconds()) * time.Second | ||
agentTimeouts[dur] = true | ||
for _, app := range protoAgent.GetApps() { | ||
appIDs = append(appIDs, app.GetId()) | ||
agentIDByAppID[app.GetId()] = agentID | ||
} | ||
} | ||
err = InsertWorkspaceResource( | ||
ctx, | ||
db, | ||
job.ID, | ||
workspaceBuild.Transition, | ||
protoResource, | ||
telemetrySnapshot, | ||
// Ensure that the agent IDs we set previously | ||
// are written to the database. | ||
InsertWorkspaceResourceWithAgentIDsFromProto(), | ||
) | ||
if err != nil { | ||
return xerrors.Errorf("insert provisioner job: %w", err) | ||
} | ||
@@ -1987,6 +2010,7 @@ func (s *server) completeWorkspaceBuildJob(ctx context.Context, job database.Pro | ||
} | ||
var taskAppID uuid.NullUUID | ||
var taskAgentID uuid.NullUUID | ||
var hasAITask bool | ||
var warnUnknownTaskAppID bool | ||
if tasks := jobType.WorkspaceBuild.GetAiTasks(); len(tasks) > 0 { | ||
@@ -2014,6 +2038,9 @@ func (s *server) completeWorkspaceBuildJob(ctx context.Context, job database.Pro | ||
} | ||
taskAppID = uuid.NullUUID{UUID: id, Valid: true} | ||
agentID, ok := agentIDByAppID[appID] | ||
taskAgentID = uuid.NullUUID{UUID: agentID, Valid: ok} | ||
} | ||
// This is a hacky workaround for the issue with tasks 'disappearing' on stop: | ||
@@ -2108,6 +2135,27 @@ func (s *server) completeWorkspaceBuildJob(ctx context.Context, job database.Pro | ||
} | ||
} | ||
if task, err := db.GetTaskByWorkspaceID(ctx, workspace.ID); err == nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Review: Previous sidebar app behavior is retained for the time being, we're just improving the task data model in parallel. | ||
// Irrespective of whether the agent or sidebar app is present, | ||
// perform the upsert to ensure a link between the task and | ||
// workspace build. Linking the task to the build is typically | ||
// already established by wsbuilder. | ||
_, err = db.UpsertTaskWorkspaceApp( | ||
ctx, | ||
database.UpsertTaskWorkspaceAppParams{ | ||
TaskID: task.ID, | ||
WorkspaceBuildNumber: workspaceBuild.BuildNumber, | ||
WorkspaceAgentID: taskAgentID, | ||
WorkspaceAppID: taskAppID, | ||
}, | ||
) | ||
if err != nil { | ||
return xerrors.Errorf("upsert task workspace app: %w", err) | ||
} | ||
} else if !errors.Is(err, sql.ErrNoRows) { | ||
return xerrors.Errorf("get task by workspace id: %w", err) | ||
} | ||
// Regardless of whether there is an AI task or not, update the field to indicate one way or the other since it | ||
// always defaults to nil. ONLY if has_ai_task=true MUST ai_task_sidebar_app_id be set. | ||
if err := db.UpdateWorkspaceBuildFlagsByID(ctx, database.UpdateWorkspaceBuildFlagsByIDParams{ | ||
@@ -2578,7 +2626,28 @@ func InsertWorkspacePresetAndParameters(ctx context.Context, db database.Store, | ||
return nil | ||
} | ||
type insertWorkspaceResourceOptions struct { | ||
useAgentIDsFromProto bool | ||
} | ||
// InsertWorkspaceResourceOption represents a functional option for | ||
// InsertWorkspaceResource. | ||
type InsertWorkspaceResourceOption func(*insertWorkspaceResourceOptions) | ||
// InsertWorkspaceResourceWithAgentIDsFromProto allows inserting agents into the | ||
// database using the agent IDs defined in the proto resource. | ||
func InsertWorkspaceResourceWithAgentIDsFromProto() InsertWorkspaceResourceOption { | ||
return func(opts *insertWorkspaceResourceOptions) { | ||
opts.useAgentIDsFromProto = true | ||
} | ||
} | ||
func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.UUID, transition database.WorkspaceTransition, protoResource *sdkproto.Resource, snapshot *telemetry.Snapshot, opt ...InsertWorkspaceResourceOption) error { | ||
opts := &insertWorkspaceResourceOptions{} | ||
for _, o := range opt { | ||
o(opts) | ||
} | ||
resource, err := db.InsertWorkspaceResource(ctx, database.InsertWorkspaceResourceParams{ | ||
ID: uuid.New(), | ||
CreatedAt: dbtime.Now(), | ||
@@ -2675,6 +2744,12 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid. | ||
} | ||
agentID := uuid.New() | ||
if opts.useAgentIDsFromProto { | ||
agentID, err = uuid.Parse(prAgent.Id) | ||
if err != nil { | ||
return xerrors.Errorf("invalid agent ID format; must be uuid: %w", err) | ||
} | ||
} | ||
dbAgent, err := db.InsertWorkspaceAgent(ctx, database.InsertWorkspaceAgentParams{ | ||
ID: agentID, | ||
ParentID: uuid.NullUUID{}, | ||
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.