Skip to content

feat(api): add asynchronous benchmark run creation - #25

Merged
amh1k merged 3 commits into
mainfrom
feat/benchmark-run-api
Sep 28, 2026
Merged

amh1k merged 3 commits into
mainfrom
feat/benchmark-run-api

Conversation

@amh1k

@amh1k amh1k commented Sep 25, 2026

Copy link
Copy Markdown
Collaborator

Summary

Adds POST /api/runs to create PostgreSQL benchmark runs asynchronously against OpenEverest-managed databases.

Changes

  • Validate authorization headers, JSON requests, targets, and benchmark settings.
  • Resolve connection details using the caller’s OpenEverest authorization.
  • Create an in-memory run record and return 202 Accepted with its ID.
  • Execute the coordinator in the background and retain results and completion status.
  • Limit execution to two concurrent runs, returning 429 when capacity is full.
  • Use an injected lifecycle context for background execution.

Testing

  • go test ./...
  • go test -race ./internal/api

Tests cover request validation, credential lookup, error handling, and asynchronous execution.

Remaining work

Backend startup and route wiring in main.go are still pending. Status/result retrieval and bounded retention are covered by the second subissue.

Signed-off-by: amh1k <abdulmoizx97@gmail.com>
Signed-off-by: amh1k <abdulmoizx97@gmail.com>
@amh1k
amh1k force-pushed the feat/benchmark-run-api branch from 60c2d8e to fa4cbc1 Compare September 25, 2026 06:29
@amh1k
amh1k requested review from spron-in and a lite review from Copilot September 25, 2026 15:00
@amh1k
amh1k removed the request for review from Copilot September 25, 2026 15:02
result, err := a.runner.Run(ctx, connection, options)
status, message := RunStatusSucceeded, ""
if err != nil {
status, message = RunStatusFailed, "benchmark execution failed"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not good. if job fails you just right down this error and nothing is logged. it is impossible to debug what happened. need a bit more love to logging.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense have implemented basic logging in the new commit

Comment on lines +170 to +175
if err := a.store.Complete(id, status, result, message); err != nil {
// A lost run record cannot be repaired here, but the execution goroutine
// must still release its concurrency slot.
return
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The slot is already released by the defer, so the comment above it is misleading. Replace it with a log line.

Comment on lines +232 to +235
for _, credentials := range []*everest.Credentials{
{Host: "postgres.example.com", Port: "5432", Username: "user", Password: "secret", Provider: "provider-mongodb", Type: "mongodb"},
{Host: "postgres.example.com", Port: "5432", Username: "user", URI: "postgres://user:secret@host/db", Provider: "provider-cloudnative-pg", Type: "postgresql"},
} {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is ok for MVP, but hardcoding provider names is a no go for a long run

Comment on lines +19 to +25
type API struct {
getCredentials CredentialLookup
runner BenchmarkRunner
store *RunStore
lifecycleCtx context.Context
runSlots chan struct{}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing waits for the background runs. Cancelling lifecycleCtx does start cleanup, since the coordinator uses WithoutCancel plus a timeout. But main can return before the Job and the Secret holding the DB password are deleted. Please track the runs and expose a Shutdown method so the wiring PR can wait for them.

A bare WaitGroup isn't enough: calling Add while Wait is in progress is a race. The Add and the "closing" flag need to share one mutex.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

implemented a fix for this in the commit

Comment thread backend/internal/api/runs.go Outdated
token, err := extractBearerToken(r)
if err != nil {
w.Header().Set("WWW-Authenticate", "Bearer")
http.Error(w, err.Error(), http.StatusUnauthorized)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http.Error returns text/plain, but the existing main.go handlers return JSON {"error": "..."} through writeJSON. The UI shouldn't have to handle both. Please add one helper in the api package and use it everywhere.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

created a new helper function for writing errors

Signed-off-by: amh1k <abdulmoizx97@gmail.com>
@amh1k
amh1k requested a review from spron-in September 28, 2026 14:22
@amh1k
amh1k merged commit e1b70b1 into main Sep 28, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants