From 98286a052a79fd79cfb524eaa8758fd911fb64e4 Mon Sep 17 00:00:00 2001 From: Thorsten Ball Date: Wed, 22 Sep 2021 12:03:57 +0200 Subject: [PATCH] Delete BatchSpecExecutions (#25178) --- .../frontend/internal/executorqueue/init.go | 8 +- .../executorqueue/queues/batches/queue.go | 13 - .../executorqueue/queues/batches/transform.go | 91 ----- .../queues/batches/transform_test.go | 70 ---- .../internal/batches/background/background.go | 3 - .../batch_spec_workspace_execution_worker.go | 10 + ...ch_spec_workspace_execution_worker_test.go | 2 + .../batches/background/execution_resetter.go | 21 - .../batches/background/executor_store.go | 194 --------- .../batches/background/executor_store_test.go | 230 ----------- .../internal/batches/background/metrics.go | 2 - .../batches/store/batch_spec_execution.go | 385 ------------------ .../store/batch_spec_execution_test.go | 280 ------------- .../internal/batches/store/batch_specs.go | 3 - .../batches/store/batch_specs_test.go | 26 +- .../batches/store/integration_test.go | 1 - .../batches/types/batch_spec_execution.go | 54 --- internal/database/schema.md | 41 -- ...395892_drop_batch_spec_executions.down.sql | 33 ++ ...28395892_drop_batch_spec_executions.up.sql | 5 + sg.config.yaml | 4 +- 21 files changed, 62 insertions(+), 1414 deletions(-) delete mode 100644 enterprise/internal/batches/background/execution_resetter.go delete mode 100644 enterprise/internal/batches/background/executor_store.go delete mode 100644 enterprise/internal/batches/background/executor_store_test.go delete mode 100644 enterprise/internal/batches/store/batch_spec_execution.go delete mode 100644 enterprise/internal/batches/store/batch_spec_execution_test.go delete mode 100644 enterprise/internal/batches/types/batch_spec_execution.go create mode 100644 migrations/frontend/1528395892_drop_batch_spec_executions.down.sql create mode 100644 migrations/frontend/1528395892_drop_batch_spec_executions.up.sql diff --git a/enterprise/cmd/frontend/internal/executorqueue/init.go b/enterprise/cmd/frontend/internal/executorqueue/init.go index 8d811f23907..207fd23d284 100644 --- a/enterprise/cmd/frontend/internal/executorqueue/init.go +++ b/enterprise/cmd/frontend/internal/executorqueue/init.go @@ -8,6 +8,8 @@ import ( "github.com/opentracing/opentracing-go" "github.com/prometheus/client_golang/prometheus" + "github.com/sourcegraph/sourcegraph/internal/database/dbutil" + "github.com/sourcegraph/sourcegraph/cmd/frontend/enterprise" "github.com/sourcegraph/sourcegraph/enterprise/cmd/frontend/internal/codeintel" "github.com/sourcegraph/sourcegraph/enterprise/cmd/frontend/internal/executorqueue/config" @@ -15,7 +17,6 @@ import ( "github.com/sourcegraph/sourcegraph/enterprise/cmd/frontend/internal/executorqueue/metrics" "github.com/sourcegraph/sourcegraph/enterprise/cmd/frontend/internal/executorqueue/queues/batches" codeintelqueue "github.com/sourcegraph/sourcegraph/enterprise/cmd/frontend/internal/executorqueue/queues/codeintel" - "github.com/sourcegraph/sourcegraph/internal/database/dbutil" "github.com/sourcegraph/sourcegraph/internal/observation" "github.com/sourcegraph/sourcegraph/internal/oobmigration" "github.com/sourcegraph/sourcegraph/internal/trace" @@ -63,9 +64,8 @@ func Init(ctx context.Context, db dbutil.DB, outOfBandMigrationRunner *oobmigrat // Register queues. If this set changes, be sure to also update the list of valid // queue names in ./metrics/queue_allocation.go. queueOptions := map[string]handler.QueueOptions{ - "codeintel": codeintelqueue.QueueOptions(db, codeintelConfig, observationContext), - "batches": batches.QueueOptions(db, batchesConfig, observationContext), - "batch-spec-workspaces": batches.WorkspaceExecutionQueueOptions(db, batchesConfig, observationContext), + "codeintel": codeintelqueue.QueueOptions(db, codeintelConfig, observationContext), + "batches": batches.QueueOptions(db, batchesConfig, observationContext), } handler, err := codeintel.NewCodeIntelUploadHandler(ctx, db, true) diff --git a/enterprise/cmd/frontend/internal/executorqueue/queues/batches/queue.go b/enterprise/cmd/frontend/internal/executorqueue/queues/batches/queue.go index 7d2c30d704e..352f19d7109 100644 --- a/enterprise/cmd/frontend/internal/executorqueue/queues/batches/queue.go +++ b/enterprise/cmd/frontend/internal/executorqueue/queues/batches/queue.go @@ -16,19 +16,6 @@ import ( ) func QueueOptions(db dbutil.DB, config *Config, observationContext *observation.Context) handler.QueueOptions { - recordTransformer := func(ctx context.Context, record workerutil.Record) (apiclient.Job, error) { - return transformRecord(ctx, db, record.(*btypes.BatchSpecExecution), config) - } - - store := background.NewExecutorStore(basestore.NewHandleWithDB(db, sql.TxOptions{}), observationContext) - return handler.QueueOptions{ - Store: store, - RecordTransformer: recordTransformer, - CanceledRecordsFetcher: store.FetchCanceled, - } -} - -func WorkspaceExecutionQueueOptions(db dbutil.DB, config *Config, observationContext *observation.Context) handler.QueueOptions { recordTransformer := func(ctx context.Context, record workerutil.Record) (apiclient.Job, error) { batchesStore := store.New(db, observationContext, nil) return transformBatchSpecWorkspaceExecutionJobRecord(ctx, batchesStore, record.(*btypes.BatchSpecWorkspaceExecutionJob), config) diff --git a/enterprise/cmd/frontend/internal/executorqueue/queues/batches/transform.go b/enterprise/cmd/frontend/internal/executorqueue/queues/batches/transform.go index 6345c26a807..c8717c7741a 100644 --- a/enterprise/cmd/frontend/internal/executorqueue/queues/batches/transform.go +++ b/enterprise/cmd/frontend/internal/executorqueue/queues/batches/transform.go @@ -18,97 +18,6 @@ import ( batcheslib "github.com/sourcegraph/sourcegraph/lib/batches" ) -// transformRecord transforms a *btypes.BatchSpecExecution into an apiclient.Job. -func transformRecord(ctx context.Context, db dbutil.DB, exec *btypes.BatchSpecExecution, config *Config) (apiclient.Job, error) { - // TODO: createAccessToken is a bit of technical debt until we figure out a - // better solution. The problem is that src-cli needs to make requests to - // the Sourcegraph instance *on behalf of the user*. - // - // Ideally we'd have something like one-time tokens that - // * we could hand to src-cli - // * are not visible to the user in the Sourcegraph web UI - // * valid only for the duration of the batch spec execution - // * and cleaned up after batch spec is executed - // - // Until then we create a fresh access token every time. - // - // GetOrCreate doesn't work because once an access token has been created - // in the database Sourcegraph can't access the plain-text token anymore. - // Only a hash for verification is kept in the database. - token, err := createAccessToken(ctx, db, exec.UserID) - if err != nil { - return apiclient.Job{}, err - } - - frontendURL := conf.Get().ExternalURL - - srcEndpoint, err := makeURL(frontendURL, config.Shared.FrontendUsername, config.Shared.FrontendPassword) - if err != nil { - return apiclient.Job{}, err - } - - redactedSrcEndpoint, err := makeURL(frontendURL, "USERNAME_REMOVED", "PASSWORD_REMOVED") - if err != nil { - return apiclient.Job{}, err - } - - cliEnv := []string{ - fmt.Sprintf("SRC_ENDPOINT=%s", srcEndpoint), - fmt.Sprintf("SRC_ACCESS_TOKEN=%s", token), - } - - var namespaceName string - if exec.NamespaceUserID != 0 { - user, err := database.Users(db).GetByID(ctx, exec.NamespaceUserID) - if err != nil { - return apiclient.Job{}, err - } - namespaceName = user.Username - } else { - org, err := database.Orgs(db).GetByID(ctx, exec.NamespaceOrgID) - if err != nil { - return apiclient.Job{}, err - } - namespaceName = org.Name - } - - return apiclient.Job{ - ID: int(exec.ID), - VirtualMachineFiles: map[string]string{"spec.yml": exec.BatchSpec}, - CliSteps: []apiclient.CliStep{ - { - Commands: []string{ - "batch", - "preview", - "-f", "spec.yml", - "-text-only", - "-skip-errors", - "-n", namespaceName, - }, - Dir: ".", - Env: cliEnv, - }, - }, - RedactedValues: map[string]string{ - // 🚨 SECURITY: Catch leak of upload endpoint. This is necessary in addition - // to the below in case the username or password contains illegal URL characters, - // which are then urlencoded and are not replaceable via byte comparison. - srcEndpoint: redactedSrcEndpoint, - - // 🚨 SECURITY: Catch uses of fragments pulled from URL to construct another target - // (in src-cli). We only pass the constructed URL to src-cli, which we trust not to - // ship the values to a third party, but not to trust to ensure the values are absent - // from the command's stdout or stderr streams. - config.Shared.FrontendUsername: "USERNAME_REMOVED", - config.Shared.FrontendPassword: "PASSWORD_REMOVED", - - // 🚨 SECURITY: Redact the access token used for src-cli to talk to - // Sourcegraph instance. - token: "SRC_ACCESS_TOKEN_REMOVED", - }, - }, nil -} - const ( accessTokenNote = "batch-spec-execution" accessTokenScope = "user:all" diff --git a/enterprise/cmd/frontend/internal/executorqueue/queues/batches/transform_test.go b/enterprise/cmd/frontend/internal/executorqueue/queues/batches/transform_test.go index ddf29f3761f..929463ff835 100644 --- a/enterprise/cmd/frontend/internal/executorqueue/queues/batches/transform_test.go +++ b/enterprise/cmd/frontend/internal/executorqueue/queues/batches/transform_test.go @@ -22,76 +22,6 @@ import ( "github.com/sourcegraph/sourcegraph/schema" ) -func TestTransformRecord(t *testing.T) { - accessToken := "thisissecret-dont-tell-anyone" - database.Mocks.AccessTokens.Create = func(subjectUserID int32, scopes []string, note string, creatorID int32) (int64, string, error) { - return 1234, accessToken, nil - } - t.Cleanup(func() { database.Mocks.AccessTokens.Create = nil }) - - testBatchSpec := `batchSpec: yeah` - index := &btypes.BatchSpecExecution{ - ID: 42, - UserID: 1, - NamespaceUserID: 1, - BatchSpec: testBatchSpec, - } - conf.Mock(&conf.Unified{SiteConfiguration: schema.SiteConfiguration{ExternalURL: "https://test.io"}}) - t.Cleanup(func() { - conf.Mock(nil) - }) - config := &Config{ - Shared: &config.SharedConfig{ - FrontendUsername: "test*", - FrontendPassword: "hunter2", - }, - } - - database.Mocks.Users.GetByID = func(ctx context.Context, id int32) (*types.User, error) { - return &types.User{ - Username: "john_namespace", - }, nil - } - t.Cleanup(func() { - database.Mocks.Users.GetByID = nil - }) - - job, err := transformRecord(context.Background(), &dbtesting.MockDB{}, index, config) - if err != nil { - t.Fatalf("unexpected error transforming record: %s", err) - } - - expected := apiclient.Job{ - ID: 42, - VirtualMachineFiles: map[string]string{"spec.yml": testBatchSpec}, - CliSteps: []apiclient.CliStep{ - { - Commands: []string{ - "batch", "preview", - "-f", "spec.yml", - "-text-only", - "-skip-errors", - "-n", "john_namespace", - }, - Dir: ".", - Env: []string{ - "SRC_ENDPOINT=https://test%2A:hunter2@test.io", - "SRC_ACCESS_TOKEN=" + accessToken, - }, - }, - }, - RedactedValues: map[string]string{ - "https://test%2A:hunter2@test.io": "https://USERNAME_REMOVED:PASSWORD_REMOVED@test.io", - "test*": "USERNAME_REMOVED", - "hunter2": "PASSWORD_REMOVED", - accessToken: "SRC_ACCESS_TOKEN_REMOVED", - }, - } - if diff := cmp.Diff(expected, job); diff != "" { - t.Errorf("unexpected job (-want +got):\n%s", diff) - } -} - func TestTransformBatchSpecWorkspaceExecutionJobRecord(t *testing.T) { accessToken := "thisissecret-dont-tell-anyone" database.Mocks.AccessTokens.Create = func(subjectUserID int32, scopes []string, note string, creatorID int32) (int64, string, error) { diff --git a/enterprise/internal/batches/background/background.go b/enterprise/internal/batches/background/background.go index d03978c89d8..ae1c655cfb6 100644 --- a/enterprise/internal/batches/background/background.go +++ b/enterprise/internal/batches/background/background.go @@ -18,7 +18,6 @@ func Routines(ctx context.Context, batchesStore *store.Store, cf *httpcli.Factor reconcilerWorkerStore := NewReconcilerDBWorkerStore(batchesStore.Handle(), observationContext) bulkProcessorWorkerStore := NewBulkOperationDBWorkerStore(batchesStore.Handle(), observationContext) - specExecutionWorkerStore := NewExecutorStore(batchesStore.Handle(), observationContext) batchSpecWorkspaceExecutionWorkerStore := NewBatchSpecWorkspaceExecutionWorkerStore(batchesStore.Handle(), observationContext) batchSpecResolutionWorkerStore := newBatchSpecResolutionWorkerStore(batchesStore.Handle(), observationContext) @@ -34,8 +33,6 @@ func Routines(ctx context.Context, batchesStore *store.Store, cf *httpcli.Factor newBulkOperationWorker(ctx, batchesStore, bulkProcessorWorkerStore, sourcer, metrics), newBulkOperationWorkerResetter(bulkProcessorWorkerStore, metrics), - newBatchSpecExecutionResetter(specExecutionWorkerStore, metrics), - newBatchSpecResolutionWorker(ctx, batchesStore, batchSpecResolutionWorkerStore, metrics), newBatchSpecResolutionWorkerResetter(batchSpecResolutionWorkerStore, metrics), diff --git a/enterprise/internal/batches/background/batch_spec_workspace_execution_worker.go b/enterprise/internal/batches/background/batch_spec_workspace_execution_worker.go index 760f0832c5d..0616f137271 100644 --- a/enterprise/internal/batches/background/batch_spec_workspace_execution_worker.go +++ b/enterprise/internal/batches/background/batch_spec_workspace_execution_worker.go @@ -22,7 +22,17 @@ import ( dbworkerstore "github.com/sourcegraph/sourcegraph/internal/workerutil/dbworker/store" ) +// batchSpecWorkspaceExecutionJobStalledJobMaximumAge is the maximum allowable +// duration between updating the state of a job as "processing" and locking the +// record during processing. An unlocked row that is marked as processing +// likely indicates that the executor that dequeued the job has died. There +// should be a nearly-zero delay between these states during normal operation. const batchSpecWorkspaceExecutionJobStalledJobMaximumAge = time.Second * 25 + +// batchSpecWorkspaceExecutionJobMaximumNumResets is the maximum number of +// times a job can be reset. If a job's failed attempts counter reaches this +// threshold, it will be moved into "errored" rather than "queued" on its next +// reset. const batchSpecWorkspaceExecutionJobMaximumNumResets = 3 func scanFirstBatchSpecWorkspaceExecutionJobRecord(rows *sql.Rows, err error) (workerutil.Record, bool, error) { diff --git a/enterprise/internal/batches/background/batch_spec_workspace_execution_worker_test.go b/enterprise/internal/batches/background/batch_spec_workspace_execution_worker_test.go index e55782d3546..b7feb34621f 100644 --- a/enterprise/internal/batches/background/batch_spec_workspace_execution_worker_test.go +++ b/enterprise/internal/batches/background/batch_spec_workspace_execution_worker_test.go @@ -249,3 +249,5 @@ stdout: {"operation":"UPLOADING_CHANGESET_SPECS","timestamp":"2021-09-09T13:20:3 }) } } + +func intptr(i int) *int { return &i } diff --git a/enterprise/internal/batches/background/execution_resetter.go b/enterprise/internal/batches/background/execution_resetter.go deleted file mode 100644 index a7f64f9e8a4..00000000000 --- a/enterprise/internal/batches/background/execution_resetter.go +++ /dev/null @@ -1,21 +0,0 @@ -package background - -import ( - "time" - - "github.com/sourcegraph/sourcegraph/internal/workerutil/dbworker" - dbworkerstore "github.com/sourcegraph/sourcegraph/internal/workerutil/dbworker/store" -) - -// newBatchSpecExecutionResetter creates a dbworker.Resetter that re-enqueues -// lost batch_spec_execution jobs for processing. -func newBatchSpecExecutionResetter(workerStore dbworkerstore.Store, metrics batchChangesMetrics) *dbworker.Resetter { - options := dbworker.ResetterOptions{ - Name: "batch_spec_executor_resetter", - Interval: 1 * time.Minute, - Metrics: metrics.executionResetterMetrics, - } - - resetter := dbworker.NewResetter(workerStore, options) - return resetter -} diff --git a/enterprise/internal/batches/background/executor_store.go b/enterprise/internal/batches/background/executor_store.go deleted file mode 100644 index 75b2aee9970..00000000000 --- a/enterprise/internal/batches/background/executor_store.go +++ /dev/null @@ -1,194 +0,0 @@ -package background - -import ( - "context" - "database/sql" - "encoding/json" - "fmt" - "strings" - "time" - - "github.com/cockroachdb/errors" - "github.com/graph-gophers/graphql-go" - "github.com/graph-gophers/graphql-go/relay" - "github.com/keegancsmith/sqlf" - - "github.com/sourcegraph/sourcegraph/enterprise/internal/batches/store" - btypes "github.com/sourcegraph/sourcegraph/enterprise/internal/batches/types" - "github.com/sourcegraph/sourcegraph/internal/database/basestore" - "github.com/sourcegraph/sourcegraph/internal/observation" - "github.com/sourcegraph/sourcegraph/internal/workerutil" - dbworkerstore "github.com/sourcegraph/sourcegraph/internal/workerutil/dbworker/store" - batcheslib "github.com/sourcegraph/sourcegraph/lib/batches" -) - -// executorStalledJobMaximumAge is the maximum allowable duration between updating the state of a -// job as "processing" and locking the record during processing. An unlocked row that is -// marked as processing likely indicates that the executor that dequeued the job has died. -// There should be a nearly-zero delay between these states during normal operation. -const executorStalledJobMaximumAge = time.Second * 25 - -// executorMaximumNumResets is the maximum number of times a job can be reset. If a job's failed -// attempts counter reaches this threshold, it will be moved into "errored" rather than -// "queued" on its next reset. -const executorMaximumNumResets = 3 - -var executorWorkerStoreOptions = dbworkerstore.Options{ - Name: "batch_spec_executor_worker_store", - TableName: "batch_spec_executions", - ColumnExpressions: store.BatchSpecExecutionColumns, - Scan: scanFirstExecutionRecord, - OrderByExpression: sqlf.Sprintf("batch_spec_executions.created_at, batch_spec_executions.id"), - StalledMaxAge: executorStalledJobMaximumAge, - MaxNumResets: executorMaximumNumResets, - // Explicitly disable retries. - MaxNumRetries: 0, -} - -type ExecutorStore interface { - dbworkerstore.Store - FetchCanceled(ctx context.Context, executorName string) (canceledIDs []int, err error) -} - -// NewExecutorStore creates a dbworker store that wraps the batch_spec_executions -// table. -func NewExecutorStore(handle *basestore.TransactableHandle, observationContext *observation.Context) ExecutorStore { - return &executorStore{ - Store: dbworkerstore.NewWithMetrics(handle, executorWorkerStoreOptions, observationContext), - observationContext: observationContext, - } -} - -var _ dbworkerstore.Store = &executorStore{} - -// executorStore is a thin wrapper around dbworkerstore.Store that allows us to -// extract information out of the ExecutionLogEntry field and persisting it to -// separate columns when marking a job as complete. -type executorStore struct { - dbworkerstore.Store - - observationContext *observation.Context -} - -// markCompleteQuery is taken from internal/workerutil/dbworker/store/store.go -// -// If that one changes we need to update this one here too. -const markCompleteQuery = ` -UPDATE batch_spec_executions -SET state = 'completed', finished_at = clock_timestamp(), batch_spec_id = (SELECT id FROM batch_specs WHERE rand_id = %s) -WHERE id = %s AND state = 'processing' AND worker_hostname = %s -RETURNING id -` - -func (s *executorStore) MarkComplete(ctx context.Context, id int, options dbworkerstore.MarkFinalOptions) (_ bool, err error) { - batchesStore := store.New(s.Store.Handle().DB(), s.observationContext, nil) - - batchSpecRandID, err := loadAndExtractBatchSpecRandID(ctx, batchesStore, int64(id)) - if err != nil { - // If we couldn't extract the batch spec rand id, we mark the job as failed - return s.Store.MarkFailed(ctx, id, fmt.Sprintf("failed to extract batch spec ID: %s", err), options) - } - - _, ok, err := basestore.ScanFirstInt(batchesStore.Query(ctx, sqlf.Sprintf(markCompleteQuery, batchSpecRandID, id, options.WorkerHostname))) - return ok, err -} - -func (s *executorStore) FetchCanceled(ctx context.Context, executorName string) (canceledIDs []int, err error) { - batchesStore := store.New(s.Store.Handle().DB(), s.observationContext, nil) - - t := true - cs, _, err := batchesStore.ListBatchSpecExecutions(ctx, store.ListBatchSpecExecutionsOpts{ - Cancel: &t, - State: btypes.BatchSpecExecutionStateProcessing, - WorkerHostname: executorName, - }) - if err != nil { - return nil, err - } - - ids := make([]int, 0, len(cs)) - for _, c := range cs { - ids = append(ids, c.RecordID()) - } - return ids, nil -} - -func loadAndExtractBatchSpecRandID(ctx context.Context, s *store.Store, id int64) (string, error) { - exec, err := s.GetBatchSpecExecution(ctx, store.GetBatchSpecExecutionOpts{ID: id}) - if err != nil { - return "", err - } - - if len(exec.ExecutionLogs) < 1 { - return "", errors.New("no execution logs") - } - - return extractBatchSpecRandID(exec.ExecutionLogs) -} - -var ErrNoBatchSpecRandID = errors.New("no batch spec rand id found in execution logs") - -func extractBatchSpecRandID(logs []workerutil.ExecutionLogEntry) (string, error) { - var ( - entry workerutil.ExecutionLogEntry - found bool - ) - - for _, e := range logs { - if e.Key == "step.src.0" { - entry = e - found = true - break - } - } - if !found { - return "", ErrNoBatchSpecRandID - } - - var batchSpecRandID string - for _, l := range strings.Split(entry.Out, "\n") { - const outputLinePrefix = "stdout: " - - if !strings.HasPrefix(l, outputLinePrefix) { - continue - } - - jsonPart := l[len(outputLinePrefix):] - - var e batcheslib.LogEvent - if err := json.Unmarshal([]byte(jsonPart), &e); err != nil { - // If we can't unmarshal the line as JSON we skip it - continue - } - - if e.Operation == batcheslib.LogEventOperationCreatingBatchSpec && e.Status == batcheslib.LogEventStatusSuccess { - url, ok := e.Metadata["batchSpecURL"] - if !ok { - return "", ErrNoBatchSpecRandID - } - urlStr, ok := url.(string) - if !ok { - return "", ErrNoBatchSpecRandID - } - parts := strings.Split(urlStr, "/") - if len(parts) == 0 { - return "", ErrNoBatchSpecRandID - } - - batchSpecGraphQLID := graphql.ID(parts[len(parts)-1]) - if err := relay.UnmarshalSpec(batchSpecGraphQLID, &batchSpecRandID); err != nil { - // If we can't extract the ID we simply return our main error - return "", ErrNoBatchSpecRandID - } - - return batchSpecRandID, nil - } - } - - return batchSpecRandID, ErrNoBatchSpecRandID -} - -// scanFirstExecutionRecord scans a slice of batch change executions and returns the first. -func scanFirstExecutionRecord(rows *sql.Rows, err error) (workerutil.Record, bool, error) { - return store.ScanFirstBatchSpecExecution(rows, err) -} diff --git a/enterprise/internal/batches/background/executor_store_test.go b/enterprise/internal/batches/background/executor_store_test.go deleted file mode 100644 index 94e2c9cfac0..00000000000 --- a/enterprise/internal/batches/background/executor_store_test.go +++ /dev/null @@ -1,230 +0,0 @@ -package background - -import ( - "context" - "testing" - "time" - - "github.com/sourcegraph/sourcegraph/enterprise/internal/batches/store" - ct "github.com/sourcegraph/sourcegraph/enterprise/internal/batches/testing" - "github.com/sourcegraph/sourcegraph/internal/database/dbtest" - "github.com/sourcegraph/sourcegraph/internal/observation" - "github.com/sourcegraph/sourcegraph/internal/workerutil" - dbworkerstore "github.com/sourcegraph/sourcegraph/internal/workerutil/dbworker/store" - - btypes "github.com/sourcegraph/sourcegraph/enterprise/internal/batches/types" -) - -func TestLoadAndExtractBatchSpecRandID(t *testing.T) { - db := dbtest.NewDB(t, "") - user := ct.CreateTestUser(t, db, true) - - s := store.New(db, &observation.TestContext, nil) - workStore := dbworkerstore.NewWithMetrics(s.Handle(), executorWorkerStoreOptions, &observation.TestContext) - - t.Run("success", func(t *testing.T) { - specExec := &btypes.BatchSpecExecution{ - State: btypes.BatchSpecExecutionStateProcessing, - BatchSpec: `name: testing`, - UserID: user.ID, - NamespaceUserID: user.ID, - } - - if err := s.CreateBatchSpecExecution(context.Background(), specExec); err != nil { - t.Fatal(err) - } - - entries := []workerutil.ExecutionLogEntry{ - { - Key: "setup.firecracker.start", - Command: []string{"ignite", "run"}, - StartTime: time.Now().Add(-5 * time.Second), - Out: `stdout: cool`, - DurationMs: intptr(200), - }, - { - Key: "step.src.0", - Command: []string{"src", "batch", "preview", "-f", "spec.yml", "-text-only"}, - StartTime: time.Now().Add(-5 * time.Second), - Out: `stdout: {"operation":"PARSING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.481Z","status":"STARTED"} -stdout: {"operation":"PARSING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.481Z","status":"SUCCESS"} -stdout: {"operation":"CREATING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.528Z","status":"STARTED"} -stdout: {"operation":"CREATING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.535Z","status":"SUCCESS","metadata":{"batchSpecURL":"http://USERNAME_REMOVED:PASSWORD_REMOVED@localhost:3080/users/mrnugget/batch-changes/apply/QmF0Y2hTcGVjOiJBZFBMTDU5SXJmWCI="}} -`, - DurationMs: intptr(200), - }, - } - - for i, e := range entries { - entryID, err := workStore.AddExecutionLogEntry(context.Background(), int(specExec.ID), e, dbworkerstore.ExecutionLogEntryOptions{}) - if err != nil { - t.Fatal(err) - } - if entryID != i+1 { - t.Fatalf("AddExecutionLogEntry returned wrong entryID. want=%d, have=%d", i+1, entryID) - } - } - - want := "AdPLL59IrfX" - have, err := loadAndExtractBatchSpecRandID(context.Background(), s, specExec.ID) - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - if have != want { - t.Fatalf("wrong rand id extracted. want=%s, have=%s", want, have) - } - }) - - t.Run("without log entry", func(t *testing.T) { - specExec := &btypes.BatchSpecExecution{ - State: btypes.BatchSpecExecutionStateProcessing, - BatchSpec: `name: testing`, - UserID: user.ID, - NamespaceUserID: user.ID, - } - - if err := s.CreateBatchSpecExecution(context.Background(), specExec); err != nil { - t.Fatal(err) - } - - _, err := loadAndExtractBatchSpecRandID(context.Background(), s, specExec.ID) - if err == nil { - t.Fatalf("expected error but got none") - } - - if err.Error() != "no execution logs" { - t.Fatalf("wrong error: %q", err.Error()) - } - }) -} - -func TestExtractBatchSpecRandID(t *testing.T) { - tests := []struct { - name string - entries []workerutil.ExecutionLogEntry - wantRandID string - wantErr error - }{ - { - name: "success", - entries: []workerutil.ExecutionLogEntry{ - {Key: "setup.firecracker.start"}, - // Reduced log output because we don't care about _all_ lines - { - Key: "step.src.0", - Out: `stdout: {"operation":"PARSING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.481Z","status":"STARTED"} -stdout: {"operation":"PARSING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.481Z","status":"SUCCESS"} -stdout: {"operation":"CREATING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.528Z","status":"STARTED"} -stdout: {"operation":"CREATING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.535Z","status":"SUCCESS","metadata":{"batchSpecURL":"http://USERNAME_REMOVED:PASSWORD_REMOVED@localhost:3080/users/mrnugget/batch-changes/apply/QmF0Y2hTcGVjOiJBZFBMTDU5SXJmWCI="}} -`, - }, - }, - // Run `echo "QmF0Y2hTcGVjOiJBZFBMTDU5SXJmWCI=" |base64 -d` to get this - wantRandID: "AdPLL59IrfX", - }, - { - - name: "no step.src.0 log entry", - entries: []workerutil.ExecutionLogEntry{}, - wantErr: ErrNoBatchSpecRandID, - }, - - { - - name: "no url in the output", - entries: []workerutil.ExecutionLogEntry{ - { - Key: "step.src.0", - Out: `stdout: {"operation":"PARSING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.481Z","status":"STARTED"} -stdout: {"operation":"PARSING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.481Z","status":"SUCCESS"} -`, - }, - }, - wantErr: ErrNoBatchSpecRandID, - }, - { - name: "invalid url in the output", - entries: []workerutil.ExecutionLogEntry{ - { - Key: "step.src.0", - Out: `stdout: {"operation":"PARSING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.481Z","status":"STARTED"} -stdout: {"operation":"PARSING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.481Z","status":"SUCCESS"} -stdout: {"operation":"CREATING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.528Z","status":"STARTED"} -stdout: {"operation":"CREATING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.535Z","status":"SUCCESS","metadata":{"batchSpecURL":"http://horse.txt"}} -`, - }, - }, - wantErr: ErrNoBatchSpecRandID, - }, - - { - name: "additional text in log output", - entries: []workerutil.ExecutionLogEntry{ - { - Key: "step.src.0", - Out: `stdout: {"operation":"PARSING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.481Z","status":"STARTED"} -stderr: HORSE -stdout: {"operation":"PARSING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.481Z","status":"SUCCESS"} -stderr: HORSE -stdout: {"operation":"CREATING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.528Z","status":"STARTED"} -stderr: HORSE -stdout: {"operation":"CREATING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.535Z","status":"SUCCESS","metadata":{"batchSpecURL":"http://USERNAME_REMOVED:PASSWORD_REMOVED@localhost:3080/users/mrnugget/batch-changes/apply/QmF0Y2hTcGVjOiJBZFBMTDU5SXJmWCI="}} -`, - }, - }, - wantRandID: "AdPLL59IrfX", - }, - - { - name: "invalid json", - entries: []workerutil.ExecutionLogEntry{ - { - Key: "step.src.0", - Out: `stdout: {"operation":"PARSING_BATCH_SPEC","timestamp":"2021-07-06T09:38:51.481Z","status":"STARTED"} -stdout: {HOOOORSE} -stdout: {HORSE} -stdout: {HORSE} -`, - }, - }, - wantErr: ErrNoBatchSpecRandID, - }, - - { - name: "non-json output inbetween valid json", - entries: []workerutil.ExecutionLogEntry{ - { - Key: "step.src.0", - Out: `stdout: {"operation":"PARSING_BATCH_SPEC","timestamp":"2021-07-12T12:25:33.965Z","status":"STARTED"} -stdout: No changeset specs created -stdout: {"operation":"CREATING_BATCH_SPEC","timestamp":"2021-07-12T12:26:01.165Z","status":"SUCCESS","metadata":{"batchSpecURL":"https://example.com/users/erik/batch-changes/apply/QmF0Y2hTcGVjOiI5cFZPcHJyTUhNQiI="}}`, - }, - }, - wantRandID: "9pVOprrMHMB", - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - have, err := extractBatchSpecRandID(tt.entries) - if tt.wantErr != nil { - if err != tt.wantErr { - t.Fatalf("wrong error. want=%s, got=%s", tt.wantErr, err) - } - return - } - - if err != nil { - t.Fatalf("unexpected error: %s", err) - } - - if have != tt.wantRandID { - t.Fatalf("wrong batch spec rand id extracted. want=%q, have=%q", tt.wantRandID, have) - } - }) - } - -} - -func intptr(v int) *int { return &v } diff --git a/enterprise/internal/batches/background/metrics.go b/enterprise/internal/batches/background/metrics.go index f37a556c2fe..c0894eefb0c 100644 --- a/enterprise/internal/batches/background/metrics.go +++ b/enterprise/internal/batches/background/metrics.go @@ -15,7 +15,6 @@ type batchChangesMetrics struct { bulkProcessorWorkerMetrics workerutil.WorkerMetrics reconcilerWorkerResetterMetrics dbworker.ResetterMetrics bulkProcessorWorkerResetterMetrics dbworker.ResetterMetrics - executionResetterMetrics dbworker.ResetterMetrics batchSpecResolutionWorkerMetrics workerutil.WorkerMetrics batchSpecResolutionWorkerResetterMetrics dbworker.ResetterMetrics @@ -29,7 +28,6 @@ func newMetrics(observationContext *observation.Context) batchChangesMetrics { bulkProcessorWorkerMetrics: workerutil.NewMetrics(observationContext, "batch_changes_bulk_processor", nil), reconcilerWorkerResetterMetrics: makeResetterMetrics(observationContext, "batch_changes_reconciler"), bulkProcessorWorkerResetterMetrics: makeResetterMetrics(observationContext, "batch_changes_bulk_processor"), - executionResetterMetrics: makeResetterMetrics(observationContext, "batch_spec_executor"), batchSpecResolutionWorkerMetrics: workerutil.NewMetrics(observationContext, "batch_changes_batch_spec_resolution_worker", nil), batchSpecResolutionWorkerResetterMetrics: makeResetterMetrics(observationContext, "batch_changes_batch_spec_resolution_worker_resetter"), diff --git a/enterprise/internal/batches/store/batch_spec_execution.go b/enterprise/internal/batches/store/batch_spec_execution.go deleted file mode 100644 index 5638bee0615..00000000000 --- a/enterprise/internal/batches/store/batch_spec_execution.go +++ /dev/null @@ -1,385 +0,0 @@ -package store - -import ( - "context" - "database/sql" - - "github.com/cockroachdb/errors" - "github.com/keegancsmith/sqlf" - "github.com/lib/pq" - "github.com/opentracing/opentracing-go/log" - - btypes "github.com/sourcegraph/sourcegraph/enterprise/internal/batches/types" - "github.com/sourcegraph/sourcegraph/internal/database/basestore" - "github.com/sourcegraph/sourcegraph/internal/database/dbutil" - "github.com/sourcegraph/sourcegraph/internal/observation" - "github.com/sourcegraph/sourcegraph/internal/workerutil" - dbworkerstore "github.com/sourcegraph/sourcegraph/internal/workerutil/dbworker/store" -) - -var BatchSpecExecutionColumns = []*sqlf.Query{ - sqlf.Sprintf("batch_spec_executions.id"), - sqlf.Sprintf("batch_spec_executions.rand_id"), - sqlf.Sprintf("batch_spec_executions.state"), - sqlf.Sprintf("batch_spec_executions.failure_message"), - sqlf.Sprintf("batch_spec_executions.started_at"), - sqlf.Sprintf("batch_spec_executions.finished_at"), - sqlf.Sprintf("batch_spec_executions.process_after"), - sqlf.Sprintf("batch_spec_executions.num_resets"), - sqlf.Sprintf("batch_spec_executions.num_failures"), - sqlf.Sprintf(`batch_spec_executions.execution_logs`), - sqlf.Sprintf("batch_spec_executions.worker_hostname"), - sqlf.Sprintf(`batch_spec_executions.created_at`), - sqlf.Sprintf(`batch_spec_executions.updated_at`), - sqlf.Sprintf(`batch_spec_executions.batch_spec`), - sqlf.Sprintf(`batch_spec_executions.batch_spec_id`), - sqlf.Sprintf(`batch_spec_executions.user_id`), - sqlf.Sprintf(`batch_spec_executions.namespace_user_id`), - sqlf.Sprintf(`batch_spec_executions.namespace_org_id`), - sqlf.Sprintf(`batch_spec_executions.cancel`), -} - -var batchSpecExecutionInsertColumns = []*sqlf.Query{ - sqlf.Sprintf("rand_id"), - sqlf.Sprintf("batch_spec"), - sqlf.Sprintf("batch_spec_id"), - sqlf.Sprintf("user_id"), - sqlf.Sprintf("namespace_user_id"), - sqlf.Sprintf("namespace_org_id"), - sqlf.Sprintf("created_at"), - sqlf.Sprintf("updated_at"), -} - -// CreateBatchSpecExecution creates the given BatchSpecExecution. -func (s *Store) CreateBatchSpecExecution(ctx context.Context, b *btypes.BatchSpecExecution) (err error) { - ctx, endObservation := s.operations.createBatchSpecExecution.With(ctx, &err, observation.Args{}) - defer endObservation(1, observation.Args{}) - - if b.CreatedAt.IsZero() { - b.CreatedAt = s.now() - } - - if b.UpdatedAt.IsZero() { - b.UpdatedAt = b.CreatedAt - } - - q, err := createBatchSpecExecutionQuery(b) - if err != nil { - return err - } - return s.query(ctx, q, func(sc scanner) error { return scanBatchSpecExecution(b, sc) }) -} - -var createBatchSpecExecutionQueryFmtstr = ` --- source: enterprise/internal/batches/store/batch_spec_executions.go:CreateBatchSpecExecution -INSERT INTO batch_spec_executions (%s) -VALUES (%s, %s, %s, %s, %s, %s, %s, %s) -RETURNING %s` - -func createBatchSpecExecutionQuery(c *btypes.BatchSpecExecution) (*sqlf.Query, error) { - if c.RandID == "" { - var err error - if c.RandID, err = RandomID(); err != nil { - return nil, errors.Wrap(err, "creating RandID failed") - } - } - - return sqlf.Sprintf( - createBatchSpecExecutionQueryFmtstr, - sqlf.Join(batchSpecExecutionInsertColumns, ", "), - c.RandID, - c.BatchSpec, - nullInt64Column(c.BatchSpecID), - c.UserID, - nullInt32Column(c.NamespaceUserID), - nullInt32Column(c.NamespaceOrgID), - c.CreatedAt, - c.UpdatedAt, - sqlf.Join(BatchSpecExecutionColumns, ", "), - ), nil -} - -// CancelBatchSpecExecution cancels the given BatchSpecExecution. -func (s *Store) CancelBatchSpecExecution(ctx context.Context, randID string) (exec *btypes.BatchSpecExecution, err error) { - ctx, endObservation := s.operations.cancelBatchSpecExecution.With(ctx, &err, observation.Args{LogFields: []log.Field{log.String("randID", randID)}}) - defer endObservation(1, observation.Args{}) - - q := s.cancelBatchSpecExecutionQuery(randID) - - var b btypes.BatchSpecExecution - err = s.query(ctx, q, func(sc scanner) error { return scanBatchSpecExecution(&b, sc) }) - if err != nil { - return nil, err - } - - if b.ID == 0 { - return nil, ErrNoResults - } - - return &b, err -} - -var cancelBatchSpecExecutionQueryFmtstr = ` --- source: enterprise/internal/batches/store/batch_spec_executions.go:CancelBatchSpecExecution -WITH candidate AS ( - SELECT - id - FROM - batch_spec_executions - WHERE - rand_id = %s - AND - -- It must be queued or processing, we cannot cancel jobs that have already completed. - state IN (%s, %s) - FOR UPDATE -) -UPDATE - batch_spec_executions -SET - cancel = TRUE, - -- If the execution is still queued, we directly abort, otherwise we keep the - -- state, so the worker can to teardown and, at some point, mark it failed itself. - state = CASE WHEN batch_spec_executions.state = %s THEN batch_spec_executions.state ELSE %s END, - finished_at = CASE WHEN batch_spec_executions.state = %s THEN batch_spec_executions.finished_at ELSE %s END, - updated_at = %s -WHERE - id IN (SELECT id FROM candidate) -RETURNING %s -` - -func (s *Store) cancelBatchSpecExecutionQuery(randID string) *sqlf.Query { - return sqlf.Sprintf( - cancelBatchSpecExecutionQueryFmtstr, - randID, - btypes.BatchSpecExecutionStateQueued, - btypes.BatchSpecExecutionStateProcessing, - btypes.BatchSpecExecutionStateProcessing, - btypes.BatchSpecExecutionStateFailed, - btypes.BatchSpecExecutionStateProcessing, - s.now(), - s.now(), - sqlf.Join(BatchSpecExecutionColumns, ", "), - ) -} - -// GetBatchSpecExecutionOpts captures the query options needed for getting a BatchSpecExecution. -type GetBatchSpecExecutionOpts struct { - ID int64 - RandID string -} - -// GetBatchSpecExecution gets a BatchSpecExecution matching the given options. -func (s *Store) GetBatchSpecExecution(ctx context.Context, opts GetBatchSpecExecutionOpts) (exec *btypes.BatchSpecExecution, err error) { - ctx, endObservation := s.operations.getBatchSpecExecution.With(ctx, &err, observation.Args{LogFields: []log.Field{ - log.Int("ID", int(opts.ID)), - log.String("randID", opts.RandID), - }}) - defer endObservation(1, observation.Args{}) - - q, err := getBatchSpecExecutionQuery(&opts) - if err != nil { - return nil, err - } - - var b btypes.BatchSpecExecution - err = s.query(ctx, q, func(sc scanner) (err error) { - return scanBatchSpecExecution(&b, sc) - }) - if err != nil { - return nil, err - } - - if b.ID == 0 { - return nil, ErrNoResults - } - - return &b, nil -} - -var getBatchSpecExecutionQueryFmtstr = ` --- source: enterprise/internal/batches/store/batch_spec_executions.go:GetBatchSpecExecution -SELECT %s FROM batch_spec_executions -WHERE %s -LIMIT 1 -` - -func getBatchSpecExecutionQuery(opts *GetBatchSpecExecutionOpts) (*sqlf.Query, error) { - var preds []*sqlf.Query - - if opts.ID != 0 { - preds = append(preds, sqlf.Sprintf("id = %s", opts.ID)) - } - - if opts.RandID != "" { - preds = append(preds, sqlf.Sprintf("rand_id = %s", opts.RandID)) - } - - if len(preds) == 0 { - return nil, errors.New("no predicates given") - } - - return sqlf.Sprintf( - getBatchSpecExecutionQueryFmtstr, - sqlf.Join(BatchSpecExecutionColumns, ", "), - sqlf.Join(preds, "\n AND "), - ), nil -} - -// ListBatchSpecExecutionsOpts captures the query options needed for -// listing batch spec executions. -type ListBatchSpecExecutionsOpts struct { - LimitOpts - Cursor int64 - Cancel *bool - State btypes.BatchSpecExecutionState - WorkerHostname string -} - -// ListBatchSpecExecutions lists batch changes with the given filters. -func (s *Store) ListBatchSpecExecutions(ctx context.Context, opts ListBatchSpecExecutionsOpts) (cs []*btypes.BatchSpecExecution, next int64, err error) { - ctx, endObservation := s.operations.listBatchSpecExecutions.With(ctx, &err, observation.Args{}) - defer endObservation(1, observation.Args{}) - - q := listBatchSpecExecutionsQuery(opts) - - cs = make([]*btypes.BatchSpecExecution, 0, opts.DBLimit()) - err = s.query(ctx, q, func(sc scanner) error { - var c btypes.BatchSpecExecution - if err := scanBatchSpecExecution(&c, sc); err != nil { - return err - } - cs = append(cs, &c) - return nil - }) - - if opts.Limit != 0 && len(cs) == opts.DBLimit() { - next = cs[len(cs)-1].ID - cs = cs[:len(cs)-1] - } - - return cs, next, err -} - -var listBatchSpecExecutionsQueryFmtstr = ` --- source: enterprise/internal/batches/store/batch_spec_execution.go:ListBatchSpecExecutions -SELECT %s FROM batch_spec_executions -WHERE %s -ORDER BY id DESC -` - -func listBatchSpecExecutionsQuery(opts ListBatchSpecExecutionsOpts) *sqlf.Query { - preds := []*sqlf.Query{} - - if opts.Cursor != 0 { - preds = append(preds, sqlf.Sprintf("batch_spec_executions.id <= %s", opts.Cursor)) - } - - if opts.Cancel != nil { - preds = append(preds, sqlf.Sprintf("batch_spec_executions.cancel = %s", *opts.Cancel)) - } - - if opts.State != "" { - preds = append(preds, sqlf.Sprintf("batch_spec_executions.state = %s", opts.State)) - } - - if opts.WorkerHostname != "" { - preds = append(preds, sqlf.Sprintf("batch_spec_executions.worker_hostname = %s", opts.WorkerHostname)) - } - - if len(preds) == 0 { - preds = append(preds, sqlf.Sprintf("TRUE")) - } - - return sqlf.Sprintf( - listBatchSpecExecutionsQueryFmtstr+opts.LimitOpts.ToDB(), - sqlf.Join(BatchSpecExecutionColumns, ", "), - sqlf.Join(preds, "\n AND "), - ) -} - -func scanBatchSpecExecution(b *btypes.BatchSpecExecution, sc scanner) error { - var executionLogs []dbworkerstore.ExecutionLogEntry - - if err := sc.Scan( - &b.ID, - &b.RandID, - &b.State, - &b.FailureMessage, - &b.StartedAt, - &b.FinishedAt, - &b.ProcessAfter, - &b.NumResets, - &b.NumFailures, - pq.Array(&executionLogs), - &b.WorkerHostname, - &b.CreatedAt, - &b.UpdatedAt, - &b.BatchSpec, - &dbutil.NullInt64{N: &b.BatchSpecID}, - &b.UserID, - &dbutil.NullInt32{N: &b.NamespaceUserID}, - &dbutil.NullInt32{N: &b.NamespaceOrgID}, - &b.Cancel, - ); err != nil { - return err - } - - for _, entry := range executionLogs { - b.ExecutionLogs = append(b.ExecutionLogs, workerutil.ExecutionLogEntry(entry)) - } - - return nil -} - -// scanBatchSpecExecutions scans a slice of batch spec executions from the rows. -func scanBatchSpecExecutions(rows *sql.Rows, queryErr error) (_ []*btypes.BatchSpecExecution, err error) { - if queryErr != nil { - return nil, queryErr - } - defer func() { err = basestore.CloseRows(rows, err) }() - - var execs []*btypes.BatchSpecExecution - for rows.Next() { - exec := &btypes.BatchSpecExecution{} - if err := scanBatchSpecExecution(exec, rows); err != nil { - return nil, err - } - - execs = append(execs, exec) - } - - return execs, nil -} - -// ScanFirstBatchSpecExecution scans a slice of batch spec executions from the -// rows and returns the first. -func ScanFirstBatchSpecExecution(rows *sql.Rows, err error) (*btypes.BatchSpecExecution, bool, error) { - execs, err := scanBatchSpecExecutions(rows, err) - if err != nil || len(execs) == 0 { - return &btypes.BatchSpecExecution{}, false, err - } - return execs[0], true, nil -} - -// CountBatchSpecExecutionsOpts captures the query options needed for -// counting batch spec executions. -type CountBatchSpecExecutionsOpts struct { - // Nothing yet. -} - -// CountBatchSpecExecutions returns the number of batch spec executions in the database. -func (s *Store) CountBatchSpecExecutions(ctx context.Context, opts CountBatchSpecExecutionsOpts) (count int, err error) { - return s.queryCount(ctx, countBatchSpecExecutionsQuery(&opts)) -} - -var countBatchSpecExecutionsQueryFmtstr = ` --- source: enterprise/internal/batches/store/batch_spec_execution.go:CountBatchSpecExecutions -SELECT COUNT(batch_spec_executions.id) -FROM batch_spec_executions -WHERE %s -` - -func countBatchSpecExecutionsQuery(opts *CountBatchSpecExecutionsOpts) *sqlf.Query { - // Nothing yet. - return sqlf.Sprintf(countBatchSpecExecutionsQueryFmtstr, "TRUE") -} diff --git a/enterprise/internal/batches/store/batch_spec_execution_test.go b/enterprise/internal/batches/store/batch_spec_execution_test.go deleted file mode 100644 index 85ad8c6af74..00000000000 --- a/enterprise/internal/batches/store/batch_spec_execution_test.go +++ /dev/null @@ -1,280 +0,0 @@ -package store - -import ( - "context" - "strconv" - "testing" - - "github.com/google/go-cmp/cmp" - "github.com/keegancsmith/sqlf" - - ct "github.com/sourcegraph/sourcegraph/enterprise/internal/batches/testing" - btypes "github.com/sourcegraph/sourcegraph/enterprise/internal/batches/types" -) - -func testStoreBatchSpecExecutions(t *testing.T, ctx context.Context, s *Store, clock ct.Clock) { - testBatchSpec := `theSpec: yeah` - - execs := make([]*btypes.BatchSpecExecution, 0, 2) - for i := 0; i < cap(execs); i++ { - c := &btypes.BatchSpecExecution{ - State: btypes.BatchSpecExecutionStateQueued, - BatchSpec: testBatchSpec, - UserID: int32(i + 123), - NamespaceUserID: int32(i + 345), - BatchSpecID: int64(i + 567), - } - - execs = append(execs, c) - } - - t.Run("Create", func(t *testing.T) { - for _, exec := range execs { - if err := s.CreateBatchSpecExecution(ctx, exec); err != nil { - t.Fatal(err) - } - - have := exec - want := &btypes.BatchSpecExecution{ - ID: have.ID, - RandID: have.RandID, - CreatedAt: clock.Now(), - UpdatedAt: clock.Now(), - State: btypes.BatchSpecExecutionStateQueued, - BatchSpec: have.BatchSpec, - UserID: have.UserID, - NamespaceUserID: have.NamespaceUserID, - BatchSpecID: have.BatchSpecID, - } - - if have.ID == 0 { - t.Fatal("ID should not be zero") - } - - if have.RandID == "" { - t.Fatal("RandID should not be empty") - } - - if diff := cmp.Diff(have, want); diff != "" { - t.Fatal(diff) - } - } - }) - - t.Run("Get", func(t *testing.T) { - t.Run("GetByID", func(t *testing.T) { - for i, exec := range execs { - t.Run(strconv.Itoa(i), func(t *testing.T) { - have, err := s.GetBatchSpecExecution(ctx, GetBatchSpecExecutionOpts{ID: exec.ID}) - if err != nil { - t.Fatal(err) - } - - if diff := cmp.Diff(have, exec); diff != "" { - t.Fatal(diff) - } - }) - } - }) - - t.Run("GetByRandID", func(t *testing.T) { - for i, exec := range execs { - t.Run(strconv.Itoa(i), func(t *testing.T) { - have, err := s.GetBatchSpecExecution(ctx, GetBatchSpecExecutionOpts{RandID: exec.RandID}) - if err != nil { - t.Fatal(err) - } - - if diff := cmp.Diff(have, exec); diff != "" { - t.Fatal(diff) - } - }) - } - }) - - t.Run("NoResults", func(t *testing.T) { - opts := GetBatchSpecExecutionOpts{ID: 0xdeadbeef} - - _, have := s.GetBatchSpecExecution(ctx, opts) - want := ErrNoResults - - if have != want { - t.Fatalf("have err %v, want %v", have, want) - } - }) - }) - - t.Run("List", func(t *testing.T) { - execs[0].WorkerHostname = "asdf-host" - execs[0].Cancel = true - execs[0].State = btypes.BatchSpecExecutionStateProcessing - if err := s.Exec(ctx, sqlf.Sprintf("UPDATE batch_spec_executions SET worker_hostname = %s, cancel = %s, state = %s WHERE id = %s", execs[0].WorkerHostname, execs[0].Cancel, execs[0].State, execs[0].ID)); err != nil { - t.Fatal(err) - } - execs[1].WorkerHostname = "nvm-host" - if err := s.Exec(ctx, sqlf.Sprintf("UPDATE batch_spec_executions SET worker_hostname = %s WHERE id = %s", execs[1].WorkerHostname, execs[1].ID)); err != nil { - t.Fatal(err) - } - - // The batch spec execution store returns the executions in reversed order. - reversedBatchSpecExecutions := make([]*btypes.BatchSpecExecution, len(execs)) - for i, c := range execs { - reversedBatchSpecExecutions[len(execs)-i-1] = c - } - - t.Run("All", func(t *testing.T) { - have, _, err := s.ListBatchSpecExecutions(ctx, ListBatchSpecExecutionsOpts{}) - if err != nil { - t.Fatal(err) - } - if diff := cmp.Diff(have, reversedBatchSpecExecutions); diff != "" { - t.Fatalf("invalid executions returned: %s", diff) - } - }) - - t.Run("WorkerHostname", func(t *testing.T) { - for _, exec := range reversedBatchSpecExecutions { - have, _, err := s.ListBatchSpecExecutions(ctx, ListBatchSpecExecutionsOpts{ - WorkerHostname: exec.WorkerHostname, - }) - if err != nil { - t.Fatal(err) - } - if diff := cmp.Diff(have, []*btypes.BatchSpecExecution{exec}); diff != "" { - t.Fatalf("invalid executions returned: %s", diff) - } - } - }) - - t.Run("State", func(t *testing.T) { - for _, exec := range reversedBatchSpecExecutions { - have, _, err := s.ListBatchSpecExecutions(ctx, ListBatchSpecExecutionsOpts{ - State: exec.State, - }) - if err != nil { - t.Fatal(err) - } - if diff := cmp.Diff(have, []*btypes.BatchSpecExecution{exec}); diff != "" { - t.Fatalf("invalid executions returned: %s", diff) - } - } - }) - - t.Run("Cancel", func(t *testing.T) { - for _, exec := range reversedBatchSpecExecutions { - have, _, err := s.ListBatchSpecExecutions(ctx, ListBatchSpecExecutionsOpts{ - Cancel: &exec.Cancel, - }) - if err != nil { - t.Fatal(err) - } - if diff := cmp.Diff(have, []*btypes.BatchSpecExecution{exec}); diff != "" { - t.Fatalf("invalid executions returned: %s", diff) - } - } - }) - - t.Run("With Limit", func(t *testing.T) { - for i := 1; i <= len(reversedBatchSpecExecutions); i++ { - cs, next, err := s.ListBatchSpecExecutions(ctx, ListBatchSpecExecutionsOpts{LimitOpts: LimitOpts{Limit: i}}) - if err != nil { - t.Fatal(err) - } - - { - have, want := next, int64(0) - if i < len(reversedBatchSpecExecutions) { - want = reversedBatchSpecExecutions[i].ID - } - - if have != want { - t.Fatalf("limit: %v: have next %v, want %v", i, have, want) - } - } - - { - have, want := cs, reversedBatchSpecExecutions[:i] - if len(have) != len(want) { - t.Fatalf("listed %d batch changes, want: %d", len(have), len(want)) - } - - if diff := cmp.Diff(have, want); diff != "" { - t.Fatal(diff) - } - } - } - }) - - t.Run("With Cursor", func(t *testing.T) { - var cursor int64 - for i := 1; i <= len(reversedBatchSpecExecutions); i++ { - opts := ListBatchSpecExecutionsOpts{Cursor: cursor, LimitOpts: LimitOpts{Limit: 1}} - have, next, err := s.ListBatchSpecExecutions(ctx, opts) - if err != nil { - t.Fatal(err) - } - - want := reversedBatchSpecExecutions[i-1 : i] - if diff := cmp.Diff(have, want); diff != "" { - t.Fatalf("opts: %+v, diff: %s", opts, diff) - } - - cursor = next - } - }) - - }) - - t.Run("CancelBatchSpecExecution", func(t *testing.T) { - t.Run("Queued", func(t *testing.T) { - record, err := s.CancelBatchSpecExecution(ctx, execs[1].RandID) - if err != nil { - t.Fatal(err) - } - if have, want := record.State, btypes.BatchSpecExecutionStateFailed; have != want { - t.Errorf("invalid state: have=%q want=%q", have, want) - } - if have, want := record.Cancel, true; have != want { - t.Errorf("invalid cancel value: have=%t want=%t", have, want) - } - if record.FinishedAt == nil { - t.Error("finished_at not set") - } else if have, want := *record.FinishedAt, s.now(); !have.Equal(want) { - t.Errorf("invalid finished_at: have=%s want=%s", have, want) - } - if have, want := record.UpdatedAt, s.now(); !have.Equal(want) { - t.Errorf("invalid updated_at: have=%s want=%s", have, want) - } - }) - t.Run("Processing", func(t *testing.T) { - record, err := s.CancelBatchSpecExecution(ctx, execs[0].RandID) - if err != nil { - t.Fatal(err) - } - if have, want := record.State, btypes.BatchSpecExecutionStateProcessing; have != want { - t.Errorf("invalid state: have=%q want=%q", have, want) - } - if have, want := record.Cancel, true; have != want { - t.Errorf("invalid cancel value: have=%t want=%t", have, want) - } - if record.FinishedAt != nil { - t.Error("finished_at set") - } - if have, want := record.UpdatedAt, s.now(); !have.Equal(want) { - t.Errorf("invalid updated_at: have=%s want=%s", have, want) - } - }) - t.Run("Invalid current state", func(t *testing.T) { - if err := s.Exec(ctx, sqlf.Sprintf("UPDATE batch_spec_executions SET state = 'completed' WHERE id = %s", execs[0].ID)); err != nil { - t.Fatal(err) - } - _, err := s.CancelBatchSpecExecution(ctx, execs[0].RandID) - if err == nil { - t.Fatal("got unexpected nil error") - } - if err != ErrNoResults { - t.Fatal(err) - } - }) - }) -} diff --git a/enterprise/internal/batches/store/batch_specs.go b/enterprise/internal/batches/store/batch_specs.go index c2c0fdddc04..1a9d77346af 100644 --- a/enterprise/internal/batches/store/batch_specs.go +++ b/enterprise/internal/batches/store/batch_specs.go @@ -375,9 +375,6 @@ AND NOT EXISTS ( AND NOT EXISTS ( SELECT 1 FROM changeset_specs WHERE batch_spec_id = batch_specs.id ) -AND NOT EXISTS ( - SELECT 1 FROM batch_spec_executions WHERE batch_spec_id = batch_specs.id -); ` func scanBatchSpec(c *btypes.BatchSpec, s scanner) error { diff --git a/enterprise/internal/batches/store/batch_specs_test.go b/enterprise/internal/batches/store/batch_specs_test.go index 8234e584751..b98d9c81a38 100644 --- a/enterprise/internal/batches/store/batch_specs_test.go +++ b/enterprise/internal/batches/store/batch_specs_test.go @@ -290,11 +290,10 @@ func testStoreBatchSpecs(t *testing.T, ctx context.Context, s *Store, clock ct.C overTTL := clock.Now().Add(-btypes.BatchSpecTTL - 1*time.Minute) tests := []struct { - createdAt time.Time - hasBatchChange bool - hasChangesetSpecs bool - hasBatchSpecExecution bool - wantDeleted bool + createdAt time.Time + hasBatchChange bool + hasChangesetSpecs bool + wantDeleted bool }{ {createdAt: underTTL, wantDeleted: false}, {createdAt: overTTL, wantDeleted: true}, @@ -305,11 +304,8 @@ func testStoreBatchSpecs(t *testing.T, ctx context.Context, s *Store, clock ct.C {hasBatchChange: true, hasChangesetSpecs: true, createdAt: underTTL, wantDeleted: false}, {hasBatchChange: true, hasChangesetSpecs: true, createdAt: overTTL, wantDeleted: false}, - {hasBatchSpecExecution: true, createdAt: underTTL, wantDeleted: false}, - {hasBatchSpecExecution: true, createdAt: overTTL, wantDeleted: false}, - - {hasBatchChange: true, hasBatchSpecExecution: true, hasChangesetSpecs: true, createdAt: underTTL, wantDeleted: false}, - {hasBatchChange: true, hasBatchSpecExecution: true, hasChangesetSpecs: true, createdAt: overTTL, wantDeleted: false}, + {hasBatchChange: true, hasChangesetSpecs: true, createdAt: underTTL, wantDeleted: false}, + {hasBatchChange: true, hasChangesetSpecs: true, createdAt: overTTL, wantDeleted: false}, } for _, tc := range tests { @@ -347,16 +343,6 @@ func testStoreBatchSpecs(t *testing.T, ctx context.Context, s *Store, clock ct.C } } - if tc.hasBatchSpecExecution { - batchSpecExecution := &btypes.BatchSpecExecution{ - NamespaceUserID: 1, - BatchSpecID: batchSpec.ID, - } - if err := s.CreateBatchSpecExecution(ctx, batchSpecExecution); err != nil { - t.Fatal(err) - } - } - if err := s.DeleteExpiredBatchSpecs(ctx); err != nil { t.Fatal(err) } diff --git a/enterprise/internal/batches/store/integration_test.go b/enterprise/internal/batches/store/integration_test.go index 2ce32d9c651..a9c231e13a3 100644 --- a/enterprise/internal/batches/store/integration_test.go +++ b/enterprise/internal/batches/store/integration_test.go @@ -34,7 +34,6 @@ func TestIntegration(t *testing.T) { t.Run("UserDeleteCascades", storeTest(db, nil, testUserDeleteCascades)) t.Run("ChangesetJobs", storeTest(db, nil, testStoreChangesetJobs)) t.Run("BulkOperations", storeTest(db, nil, testStoreBulkOperations)) - t.Run("BatchSpecExecutions", storeTest(db, nil, testStoreBatchSpecExecutions)) t.Run("BatchSpecWorkspaces", storeTest(db, nil, testStoreBatchSpecWorkspaces)) t.Run("BatchSpecWorkspaceExecutionJobs", storeTest(db, nil, testStoreBatchSpecWorkspaceExecutionJobs)) t.Run("BatchSpecResolutionJobs", storeTest(db, nil, testStoreBatchSpecResolutionJobs)) diff --git a/enterprise/internal/batches/types/batch_spec_execution.go b/enterprise/internal/batches/types/batch_spec_execution.go deleted file mode 100644 index 033205c792e..00000000000 --- a/enterprise/internal/batches/types/batch_spec_execution.go +++ /dev/null @@ -1,54 +0,0 @@ -package types - -import ( - "strings" - "time" - - "github.com/sourcegraph/sourcegraph/internal/workerutil" -) - -type BatchSpecExecutionState string - -const ( - BatchSpecExecutionStateQueued BatchSpecExecutionState = "queued" - BatchSpecExecutionStateErrored BatchSpecExecutionState = "errored" - BatchSpecExecutionStateFailed BatchSpecExecutionState = "failed" - BatchSpecExecutionStateCompleted BatchSpecExecutionState = "completed" - BatchSpecExecutionStateProcessing BatchSpecExecutionState = "processing" -) - -type BatchSpecExecution struct { - ID int64 - RandID string - State BatchSpecExecutionState - FailureMessage *string - StartedAt *time.Time - FinishedAt *time.Time - ProcessAfter *time.Time - NumResets int64 - NumFailures int64 - ExecutionLogs []workerutil.ExecutionLogEntry - WorkerHostname string - CreatedAt time.Time - UpdatedAt time.Time - BatchSpec string - BatchSpecID int64 - UserID int32 - NamespaceUserID int32 - NamespaceOrgID int32 - Cancel bool -} - -func (e BatchSpecExecution) RecordID() int { - return int(e.ID) -} - -func (e BatchSpecExecution) GQLState() string { - if e.Cancel { - if e.State == BatchSpecExecutionStateFailed { - return "CANCELED" - } - return "CANCELING" - } - return strings.ToUpper(string(e.State)) -} diff --git a/internal/database/schema.md b/internal/database/schema.md index 68827c8c908..a89cfb6fb10 100755 --- a/internal/database/schema.md +++ b/internal/database/schema.md @@ -76,43 +76,6 @@ Indexes: ``` -# Table "public.batch_spec_executions" -``` - Column | Type | Collation | Nullable | Default --------------------+--------------------------+-----------+----------+--------------------------------------------------- - id | bigint | | not null | nextval('batch_spec_executions_id_seq'::regclass) - state | text | | | 'queued'::text - failure_message | text | | | - started_at | timestamp with time zone | | | - finished_at | timestamp with time zone | | | - process_after | timestamp with time zone | | | - num_resets | integer | | not null | 0 - num_failures | integer | | not null | 0 - execution_logs | json[] | | | - worker_hostname | text | | not null | ''::text - created_at | timestamp with time zone | | not null | now() - updated_at | timestamp with time zone | | not null | now() - batch_spec | text | | not null | - batch_spec_id | integer | | | - user_id | integer | | | - namespace_user_id | integer | | | - namespace_org_id | integer | | | - rand_id | text | | not null | - last_heartbeat_at | timestamp with time zone | | | - cancel | boolean | | | false -Indexes: - "batch_spec_executions_pkey" PRIMARY KEY, btree (id) - "batch_spec_executions_rand_id" btree (rand_id) -Check constraints: - "batch_spec_executions_has_1_namespace" CHECK ((namespace_user_id IS NULL) <> (namespace_org_id IS NULL)) -Foreign-key constraints: - "batch_spec_executions_batch_spec_id_fkey" FOREIGN KEY (batch_spec_id) REFERENCES batch_specs(id) DEFERRABLE - "batch_spec_executions_namespace_org_id_fkey" FOREIGN KEY (namespace_org_id) REFERENCES orgs(id) DEFERRABLE - "batch_spec_executions_namespace_user_id_fkey" FOREIGN KEY (namespace_user_id) REFERENCES users(id) DEFERRABLE - "batch_spec_executions_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id) DEFERRABLE - -``` - # Table "public.batch_spec_resolution_jobs" ``` Column | Type | Collation | Nullable | Default @@ -217,7 +180,6 @@ Foreign-key constraints: "batch_specs_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL DEFERRABLE Referenced by: TABLE "batch_changes" CONSTRAINT "batch_changes_batch_spec_id_fkey" FOREIGN KEY (batch_spec_id) REFERENCES batch_specs(id) DEFERRABLE - TABLE "batch_spec_executions" CONSTRAINT "batch_spec_executions_batch_spec_id_fkey" FOREIGN KEY (batch_spec_id) REFERENCES batch_specs(id) DEFERRABLE TABLE "batch_spec_resolution_jobs" CONSTRAINT "batch_spec_resolution_jobs_batch_spec_id_fkey" FOREIGN KEY (batch_spec_id) REFERENCES batch_specs(id) ON DELETE CASCADE DEFERRABLE TABLE "batch_spec_workspaces" CONSTRAINT "batch_spec_workspaces_batch_spec_id_fkey" FOREIGN KEY (batch_spec_id) REFERENCES batch_specs(id) ON DELETE CASCADE DEFERRABLE TABLE "changeset_specs" CONSTRAINT "changeset_specs_batch_spec_id_fkey" FOREIGN KEY (batch_spec_id) REFERENCES batch_specs(id) DEFERRABLE @@ -1440,7 +1402,6 @@ Check constraints: "orgs_name_valid_chars" CHECK (name ~ '^[a-zA-Z0-9](?:[a-zA-Z0-9]|[-.](?=[a-zA-Z0-9]))*-?$'::citext) Referenced by: TABLE "batch_changes" CONSTRAINT "batch_changes_namespace_org_id_fkey" FOREIGN KEY (namespace_org_id) REFERENCES orgs(id) ON DELETE CASCADE DEFERRABLE - TABLE "batch_spec_executions" CONSTRAINT "batch_spec_executions_namespace_org_id_fkey" FOREIGN KEY (namespace_org_id) REFERENCES orgs(id) DEFERRABLE TABLE "cm_monitors" CONSTRAINT "cm_monitors_org_id_fk" FOREIGN KEY (namespace_org_id) REFERENCES orgs(id) ON DELETE CASCADE TABLE "cm_recipients" CONSTRAINT "cm_recipients_org_id_fk" FOREIGN KEY (namespace_org_id) REFERENCES orgs(id) ON DELETE CASCADE TABLE "feature_flag_overrides" CONSTRAINT "feature_flag_overrides_namespace_org_id_fkey" FOREIGN KEY (namespace_org_id) REFERENCES orgs(id) ON DELETE CASCADE @@ -2094,8 +2055,6 @@ Referenced by: TABLE "batch_changes" CONSTRAINT "batch_changes_initial_applier_id_fkey" FOREIGN KEY (initial_applier_id) REFERENCES users(id) ON DELETE SET NULL DEFERRABLE TABLE "batch_changes" CONSTRAINT "batch_changes_last_applier_id_fkey" FOREIGN KEY (last_applier_id) REFERENCES users(id) ON DELETE SET NULL DEFERRABLE TABLE "batch_changes" CONSTRAINT "batch_changes_namespace_user_id_fkey" FOREIGN KEY (namespace_user_id) REFERENCES users(id) ON DELETE CASCADE DEFERRABLE - TABLE "batch_spec_executions" CONSTRAINT "batch_spec_executions_namespace_user_id_fkey" FOREIGN KEY (namespace_user_id) REFERENCES users(id) DEFERRABLE - TABLE "batch_spec_executions" CONSTRAINT "batch_spec_executions_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id) DEFERRABLE TABLE "batch_specs" CONSTRAINT "batch_specs_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL DEFERRABLE TABLE "changeset_jobs" CONSTRAINT "changeset_jobs_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE DEFERRABLE TABLE "changeset_specs" CONSTRAINT "changeset_specs_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL DEFERRABLE diff --git a/migrations/frontend/1528395892_drop_batch_spec_executions.down.sql b/migrations/frontend/1528395892_drop_batch_spec_executions.down.sql new file mode 100644 index 00000000000..d8a8eae06c9 --- /dev/null +++ b/migrations/frontend/1528395892_drop_batch_spec_executions.down.sql @@ -0,0 +1,33 @@ +BEGIN; + +CREATE TABLE IF NOT EXISTS batch_spec_executions ( + id BIGSERIAL PRIMARY KEY, + rand_id TEXT NOT NULL, + + state TEXT DEFAULT 'queued', + failure_message TEXT, + process_after TIMESTAMP WITH TIME ZONE, + started_at TIMESTAMP WITH TIME ZONE, + finished_at TIMESTAMP WITH TIME ZONE, + last_heartbeat_at TIMESTAMP WITH TIME ZONE, + num_resets INTEGER NOT NULL DEFAULT 0, + num_failures INTEGER NOT NULL DEFAULT 0, + execution_logs JSON[], + worker_hostname TEXT NOT NULL DEFAULT '', + cancel BOOL DEFAULT FALSE, + + created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), + updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(), + + batch_spec TEXT NOT NULL, + batch_spec_id integer REFERENCES batch_specs(id) DEFERRABLE, + + user_id INTEGER REFERENCES users(id), + namespace_org_id INTEGER REFERENCES orgs(id), + namespace_user_id INTEGER REFERENCES users(id) +); + +ALTER TABLE IF EXISTS batch_spec_executions ADD CONSTRAINT batch_spec_executions_has_1_namespace CHECK ((namespace_user_id IS NULL) <> (namespace_org_id IS NULL)); +CREATE INDEX IF NOT EXISTS batch_spec_executions_rand_id ON batch_spec_executions USING btree (rand_id); + +COMMIT; diff --git a/migrations/frontend/1528395892_drop_batch_spec_executions.up.sql b/migrations/frontend/1528395892_drop_batch_spec_executions.up.sql new file mode 100644 index 00000000000..23fa74022a0 --- /dev/null +++ b/migrations/frontend/1528395892_drop_batch_spec_executions.up.sql @@ -0,0 +1,5 @@ +BEGIN; + +DROP TABLE IF EXISTS batch_spec_executions; + +COMMIT; diff --git a/sg.config.yaml b/sg.config.yaml index 097f46ed16f..bc9a84284f2 100644 --- a/sg.config.yaml +++ b/sg.config.yaml @@ -430,7 +430,7 @@ commands: cmd: | env TMPDIR="$HOME/.sourcegraph/batches-executor-temp" .bin/executor env: - EXECUTOR_QUEUE_NAME: batch-spec-workspaces + EXECUTOR_QUEUE_NAME: batches SRC_PROF_HTTP: ":6093" # If you want to use this, either start it with `sg run batches-executor-firecracker` or @@ -443,7 +443,7 @@ commands: .bin/executor env: EXECUTOR_USE_FIRECRACKER: true - EXECUTOR_QUEUE_NAME: batch-spec-workspaces + EXECUTOR_QUEUE_NAME: batches SRC_PROF_HTTP: ":6093" minio: