-
Notifications
You must be signed in to change notification settings - Fork 11
chore: job created event #700
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -3,20 +3,64 @@ package jobs | |||||||||
| import ( | ||||||||||
| "context" | ||||||||||
| "encoding/json" | ||||||||||
| "errors" | ||||||||||
| "fmt" | ||||||||||
| "time" | ||||||||||
|
|
||||||||||
| "workspace-engine/pkg/events/handler" | ||||||||||
| "workspace-engine/pkg/kafka/producer" | ||||||||||
| "workspace-engine/pkg/oapi" | ||||||||||
| "workspace-engine/pkg/workspace" | ||||||||||
| "workspace-engine/pkg/workspace/releasemanager/deployment/jobs" | ||||||||||
|
|
||||||||||
| "github.com/charmbracelet/log" | ||||||||||
| "github.com/google/uuid" | ||||||||||
| "go.opentelemetry.io/otel" | ||||||||||
| "go.opentelemetry.io/otel/attribute" | ||||||||||
| "go.opentelemetry.io/otel/trace" | ||||||||||
| ) | ||||||||||
|
|
||||||||||
| var tracer = otel.Tracer("events/handler/jobs") | ||||||||||
|
|
||||||||||
| func isStringUUID(s string) bool { | ||||||||||
| _, err := uuid.Parse(s) | ||||||||||
| return err == nil | ||||||||||
| } | ||||||||||
|
|
||||||||||
| func dispatchAndNotifyJob(ctx context.Context, ws *workspace.Workspace, job *oapi.Job) { | ||||||||||
| err := ws.ReleaseManager().JobDispatcher().DispatchJob(ctx, job) | ||||||||||
| if err == nil || errors.Is(err, jobs.ErrUnsupportedJobAgent) { | ||||||||||
| return | ||||||||||
| } | ||||||||||
|
|
||||||||||
| log.Error("error dispatching job to integration", "error", err.Error()) | ||||||||||
| job.Status = oapi.InvalidIntegration | ||||||||||
| job.UpdatedAt = time.Now() | ||||||||||
|
|
||||||||||
| kafkaProducer, err := producer.NewProducer() | ||||||||||
| if err != nil { | ||||||||||
| log.Error("error creating kafka producer", "error", err.Error()) | ||||||||||
| return | ||||||||||
| } | ||||||||||
| defer kafkaProducer.Close() | ||||||||||
|
|
||||||||||
| jobUpdateEvent := &oapi.JobUpdateEvent{ | ||||||||||
| AgentId: &job.JobAgentId, | ||||||||||
| ExternalId: job.ExternalId, | ||||||||||
| FieldsToUpdate: &[]oapi.JobUpdateEventFieldsToUpdate{ | ||||||||||
| oapi.JobUpdateEventFieldsToUpdate("status"), | ||||||||||
| }, | ||||||||||
| Id: &job.Id, | ||||||||||
| Job: *job, | ||||||||||
| } | ||||||||||
|
|
||||||||||
| err = kafkaProducer.ProduceEvent("job.updated", ws.ID, jobUpdateEvent) | ||||||||||
| if err != nil { | ||||||||||
| log.Error("error producing job updated event", "error", err.Error()) | ||||||||||
| return | ||||||||||
| } | ||||||||||
| } | ||||||||||
|
|
||||||||||
| func getInternalReleaseID(ws *workspace.Workspace, jobUpdateEvent *oapi.JobUpdateEvent) string { | ||||||||||
| eventReleaseID := jobUpdateEvent.Job.ReleaseId | ||||||||||
| if eventReleaseID == "" { | ||||||||||
|
|
@@ -36,6 +80,45 @@ func getInternalReleaseID(ws *workspace.Workspace, jobUpdateEvent *oapi.JobUpdat | |||||||||
| return "" | ||||||||||
| } | ||||||||||
|
|
||||||||||
| func HandleJobCreated( | ||||||||||
| ctx context.Context, | ||||||||||
| ws *workspace.Workspace, | ||||||||||
| event handler.RawEvent, | ||||||||||
| ) error { | ||||||||||
| ctx, span := tracer.Start(ctx, "HandleJobCreated") | ||||||||||
| defer span.End() | ||||||||||
|
|
||||||||||
| var job *oapi.Job | ||||||||||
| if err := json.Unmarshal(event.Data, &job); err != nil { | ||||||||||
| return err | ||||||||||
| } | ||||||||||
|
|
||||||||||
| span.SetAttributes( | ||||||||||
| attribute.Bool("job.created", true), | ||||||||||
| attribute.String("job.id", job.Id), | ||||||||||
| attribute.String("job.status", string(job.Status)), | ||||||||||
| attribute.String("workspace.id", ws.ID), | ||||||||||
| ) | ||||||||||
|
|
||||||||||
| ws.Jobs().Upsert(ctx, job) | ||||||||||
|
|
||||||||||
| if ws.Store().IsReplay() { | ||||||||||
| span.SetAttributes(attribute.Bool("job.replay", true)) | ||||||||||
| span.AddEvent("Skipping job creation in replay mode", trace.WithAttributes( | ||||||||||
| attribute.String("job.id", job.Id), | ||||||||||
| attribute.String("job.status", string(job.Status)), | ||||||||||
| attribute.String("workspace.id", ws.ID), | ||||||||||
| )) | ||||||||||
| return nil | ||||||||||
| } | ||||||||||
|
|
||||||||||
| if job.Status != oapi.InvalidJobAgent { | ||||||||||
| go dispatchAndNotifyJob(ctx, ws, job) | ||||||||||
|
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. 🧩 Analysis chainContext passed to goroutine may be cancelled prematurely The parent context Consider this approach: if job.Status != oapi.InvalidJobAgent {
- go dispatchAndNotifyJob(ctx, ws, job)
+ go dispatchAndNotifyJob(context.Background(), ws, job)
}Or if you need to preserve tracing context (Go 1.21+): if job.Status != oapi.InvalidJobAgent {
- go dispatchAndNotifyJob(ctx, ws, job)
+ go dispatchAndNotifyJob(context.WithoutCancel(ctx), ws, job)
}Length of output: 1311 🏁 Script executed: #!/bin/bash
# Find the dispatchAndNotifyJob function definition
rg -n "func.*dispatchAndNotifyJob" apps/workspace-engine/Length of output: 145 🏁 Script executed: #!/bin/bash
# Check Go version in the project
if [ -f "go.mod" ]; then
head -3 go.mod
fiLength of output: 0 🏁 Script executed: #!/bin/bash
# Search for other goroutine patterns passing ctx to understand codebase conventions
rg -n "go.*\(ctx" apps/workspace-engine/ -A 2 -B 2 | head -n 100Length of output: 760 Length of output: 1354 🏁 Script executed: #!/bin/bash
# Get full go.mod for version info
cat go.mod | head -20Length of output: 38 🏁 Script executed: #!/bin/bash
# Check the parent handler function to understand context lifecycle
sed -n '95,130p' apps/workspace-engine/pkg/events/handler/jobs/jobs.goLength of output: 883 Length of output: 30 🏁 Script executed: #!/bin/bash
# Check if there's a go version file or workspace setting
ls -la apps/workspace-engine/ | grep -E "go\.|versions"Length of output: 115 🏁 Script executed: #!/bin/bash
# Look for go directives in the jobs handler file or nearby
rg "go 1\." apps/workspace-engine/ --max-count 3Length of output: 38 Use The if job.Status != oapi.InvalidJobAgent {
- go dispatchAndNotifyJob(ctx, ws, job)
+ go dispatchAndNotifyJob(context.WithoutCancel(ctx), ws, job)
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||
| } | ||||||||||
|
|
||||||||||
| return nil | ||||||||||
| } | ||||||||||
|
|
||||||||||
| func HandleJobUpdated( | ||||||||||
| ctx context.Context, | ||||||||||
| ws *workspace.Workspace, | ||||||||||
|
|
||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Check for Upsert errors
The
Upsertcall at line 103 can fail, but the error is neither checked nor logged. This could result in silent failures when persisting the job to the store.Apply this diff to handle errors:
🤖 Prompt for AI Agents