package agenttask import ( "context" "fmt" ) func (m *Manager) claimProject(ctx context.Context, projectID ProjectID) (bool, error) { now := m.clock.Now() token := fmt.Sprintf("%s/%s/%d", m.config.OwnerID, projectID, now.UnixNano()) return mutateDecision(m, ctx, func(state *ManagerState) (bool, error) { project, ok := state.Projects[projectID] if !ok || project.Status != ProjectStatusRunning { return false, nil } if project.Lease != nil && project.Lease.OwnerID != m.config.OwnerID && project.Lease.ExpiresAt.After(now) { return false, nil } project.Lease = &LeaseRecord{ OwnerID: m.config.OwnerID, Token: token, ExpiresAt: now.Add(m.config.LeaseDuration), } project.UpdatedAt = now state.Projects[projectID] = project return true, nil }) } func (m *Manager) releaseProject(ctx context.Context, projectID ProjectID) { _ = m.mutate(ctx, func(state *ManagerState) error { project, ok := state.Projects[projectID] if !ok || project.Lease == nil || project.Lease.OwnerID != m.config.OwnerID { return nil } project.Lease = nil project.UpdatedAt = m.clock.Now() state.Projects[projectID] = project return nil }) } func (m *Manager) claimIntegration( ctx context.Context, workspaceID WorkspaceID, ) (bool, error) { now := m.clock.Now() return mutateDecision(m, ctx, func(state *ManagerState) (bool, error) { lease, exists := state.IntegrationLeases[workspaceID] if exists && lease.OwnerID != m.config.OwnerID && lease.ExpiresAt.After(now) { return false, nil } state.IntegrationLeases[workspaceID] = LeaseRecord{ OwnerID: m.config.OwnerID, Token: fmt.Sprintf("%s/integration/%s/%d", m.config.OwnerID, workspaceID, now.UnixNano()), ExpiresAt: now.Add(m.config.LeaseDuration), } return true, nil }) } func (m *Manager) releaseIntegration(ctx context.Context, workspaceID WorkspaceID) { _ = m.mutate(ctx, func(state *ManagerState) error { lease, ok := state.IntegrationLeases[workspaceID] if ok && lease.OwnerID == m.config.OwnerID { delete(state.IntegrationLeases, workspaceID) } return nil }) }