mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 18:51:59 +00:00
This commit contains several smaller pieces: - Run executor-queue as part of enterprise - Make health server port configurable Otherwise, it's impossible to run two executors on the same machine (required for dev when running code intel AND batch changes). - Make port for executor queue configurable - Add batch spec execution DB entity - Overpromise implementation of batches queue in executor-queue - Add shared config for reusing env vars across queues These fields will also be required in the batches queue, so we need to make them sharable. Defining them in both places causes a validation error. - Add batch spec executions queue to executor-queue - Add resetter for executor worker
114 lines
3.4 KiB
Go
114 lines
3.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"log"
|
|
|
|
"github.com/inconshreveable/log15"
|
|
"github.com/opentracing/opentracing-go"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
|
|
"github.com/sourcegraph/sourcegraph/enterprise/cmd/executor-queue/internal/queues/batches"
|
|
"github.com/sourcegraph/sourcegraph/enterprise/cmd/executor-queue/internal/queues/codeintel"
|
|
apiserver "github.com/sourcegraph/sourcegraph/enterprise/cmd/executor-queue/internal/server"
|
|
"github.com/sourcegraph/sourcegraph/internal/conf"
|
|
"github.com/sourcegraph/sourcegraph/internal/database/dbconn"
|
|
"github.com/sourcegraph/sourcegraph/internal/debugserver"
|
|
"github.com/sourcegraph/sourcegraph/internal/env"
|
|
"github.com/sourcegraph/sourcegraph/internal/goroutine"
|
|
"github.com/sourcegraph/sourcegraph/internal/logging"
|
|
"github.com/sourcegraph/sourcegraph/internal/observation"
|
|
"github.com/sourcegraph/sourcegraph/internal/trace"
|
|
"github.com/sourcegraph/sourcegraph/internal/tracer"
|
|
)
|
|
|
|
type config interface {
|
|
Load()
|
|
Validate() error
|
|
}
|
|
|
|
func main() {
|
|
serviceConfig := &Config{}
|
|
codeintelConfig := &codeintel.Config{}
|
|
batchesConfig := &batches.Config{}
|
|
configs := []config{serviceConfig, codeintelConfig, batchesConfig}
|
|
|
|
for _, config := range configs {
|
|
config.Load()
|
|
}
|
|
|
|
env.Lock()
|
|
env.HandleHelpFlag()
|
|
|
|
logging.Init()
|
|
tracer.Init()
|
|
trace.Init(true)
|
|
|
|
for _, config := range configs {
|
|
if err := config.Validate(); err != nil {
|
|
log.Fatalf("failed to load config: %s", err)
|
|
}
|
|
}
|
|
|
|
// Initialize tracing/metrics
|
|
observationContext := &observation.Context{
|
|
Logger: log15.Root(),
|
|
Tracer: &trace.Tracer{Tracer: opentracing.GlobalTracer()},
|
|
Registerer: prometheus.DefaultRegisterer,
|
|
}
|
|
|
|
// Start debug server
|
|
ready := make(chan struct{})
|
|
go debugserver.NewServerRoutine(ready).Start()
|
|
|
|
// Connect to databases
|
|
db := connectToDatabase()
|
|
|
|
// Migrations may take a while, but after they're done we'll immediately
|
|
// spin up a server and can accept traffic. Inform external clients we'll
|
|
// be ready for traffic.
|
|
close(ready)
|
|
|
|
// Initialize queues
|
|
queueOptions := map[string]apiserver.QueueOptions{
|
|
"codeintel": codeintel.QueueOptions(db, codeintelConfig, observationContext),
|
|
"batches": batches.QueueOptions(db, batchesConfig, observationContext),
|
|
}
|
|
|
|
for queueName, options := range queueOptions {
|
|
prometheus.DefaultRegisterer.MustRegister(prometheus.NewGaugeFunc(prometheus.GaugeOpts{
|
|
Name: "src_executor_queue_total",
|
|
Help: "Total number of jobs in the queued state.",
|
|
ConstLabels: map[string]string{"queue": queueName},
|
|
}, func() float64 {
|
|
// TODO(efritz) - do not count soft-deleted code intel index records
|
|
count, err := options.Store.QueuedCount(context.Background(), nil)
|
|
if err != nil {
|
|
log15.Error("Failed to get queued job count", "queue", queueName, "error", err)
|
|
}
|
|
|
|
return float64(count)
|
|
}))
|
|
}
|
|
|
|
server := apiserver.NewServer(serviceConfig.ServerOptions(queueOptions), observationContext)
|
|
goroutine.MonitorBackgroundRoutines(context.Background(), server)
|
|
}
|
|
|
|
func connectToDatabase() *sql.DB {
|
|
postgresDSN := conf.Get().ServiceConnections.PostgresDSN
|
|
conf.Watch(func() {
|
|
if newDSN := conf.Get().ServiceConnections.PostgresDSN; postgresDSN != newDSN {
|
|
log.Fatalf("detected database DSN change, restarting to take effect: %s", newDSN)
|
|
}
|
|
})
|
|
|
|
db, err := dbconn.New(dbconn.Opts{DSN: postgresDSN, DBName: "frontend", AppName: "executor-queue"})
|
|
if err != nil {
|
|
log.Fatalf("failed to initialize store: %s", err)
|
|
}
|
|
|
|
return db
|
|
}
|