-
Notifications
You must be signed in to change notification settings - Fork 27
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
Reduce getworkflowjobbyid gh requests #253
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 | ||
---|---|---|---|---|
|
@@ -131,7 +131,7 @@ | |||
keyMux *keyMutex | ||||
} | ||||
|
||||
func (r *basePoolManager) HandleWorkflowJob(job params.WorkflowJob) error { | ||||
if err := r.ValidateOwner(job); err != nil { | ||||
return errors.Wrap(err, "validating owner") | ||||
} | ||||
|
@@ -139,6 +139,23 @@ | |||
var jobParams params.Job | ||||
var err error | ||||
var triggeredBy int64 | ||||
|
||||
// especially on an enterprise level we get a lot of webhooks that are not meant for us. | ||||
// if there is no pool that matches the labels, we should ignore the job and return earlier. | ||||
potentialPools, err := r.store.FindPoolsMatchingAllTags(r.ctx, r.entity.EntityType, r.entity.ID, jobParams.Labels) | ||||
if err != nil { | ||||
slog.With(slog.Any("error", err)).ErrorContext( | ||||
r.ctx, "failed to find pools matching tags; not recording job", | ||||
"requested_tags", strings.Join(jobParams.Labels, ", ")) | ||||
return errors.Wrap(err, "getting pools matching tags") | ||||
} | ||||
if len(potentialPools) == 0 { | ||||
slog.WarnContext( | ||||
r.ctx, "no pools matching tags; not recording job", | ||||
"requested_tags", strings.Join(jobParams.Labels, ", ")) | ||||
return errors.New("no pools matching tags") | ||||
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. Do we need to return an error? Not having a pool to handle a job isn't really an error. We could get all sorts of webhooks we don't really need, even for jobs meant for the builtin github runners. We can just return 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. you're right, but i used an error here to be able to identify it within the TBH, during implementation i didn't liked it that much but i decided to do a first impl. that way and wait for your feedback :-) - will do something different here 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. In the current implementation from That being said, we still need to transition the job status correctly. If a I think that the current implementation of Regarding the issue at hand of too many attempts to I am curious what state the job is in when this actually does get called. We may be able to tweak the logic to not look up the runner name. We may even decide to remove that whole block of code altogether if it doesn't even make sense to try and get the runner name. Would it be possible to log the job itself and get that info in your env? 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. okay, I found why we still make API calls needlessly. Line 903 in 7538f4a
I used the US English form of |
||||
} | ||||
|
||||
defer func() { | ||||
// we're updating the job in the database, regardless of whether it was successful or not. | ||||
// or if it was meant for this pool or not. Github will send the same job data to all hierarchies | ||||
|
@@ -156,20 +173,6 @@ | |||
"job_id", jobParams.ID) | ||||
return | ||||
} | ||||
// This job is new to us. Check if we have a pool that can handle it. | ||||
potentialPools, err := r.store.FindPoolsMatchingAllTags(r.ctx, r.entity.EntityType, r.entity.ID, jobParams.Labels) | ||||
if err != nil { | ||||
slog.With(slog.Any("error", err)).ErrorContext( | ||||
r.ctx, "failed to find pools matching tags; not recording job", | ||||
"requested_tags", strings.Join(jobParams.Labels, ", ")) | ||||
return | ||||
} | ||||
if len(potentialPools) == 0 { | ||||
slog.WarnContext( | ||||
r.ctx, "no pools matching tags; not recording job", | ||||
"requested_tags", strings.Join(jobParams.Labels, ", ")) | ||||
return | ||||
} | ||||
} | ||||
|
||||
if _, jobErr := r.store.CreateOrUpdateJob(r.ctx, jobParams); jobErr != nil { | ||||
|
@@ -210,6 +213,20 @@ | |||
return errors.Wrap(err, "converting job to params") | ||||
} | ||||
|
||||
// Runner name was not set in WorkflowJob by github. We can still attempt to fetch the info we need, | ||||
// using the workflow run ID, from the API. | ||||
if job.WorkflowJob.RunnerName == "" { | ||||
// We may still get no runner name. In situations such as jobs being cancelled before a runner had the chance | ||||
// to pick up the job, the runner name is not available from the API. | ||||
if job.WorkflowJob.Conclusion != "skipped" && job.WorkflowJob.Conclusion != "canceled" { | ||||
runnerInfo, err := r.getRunnerDetailsFromJob(job) | ||||
if err != nil && !errors.Is(err, runnerErrors.ErrNotFound) { | ||||
return errors.Wrap(err, "fetching runner details") | ||||
} | ||||
jobParams.RunnerName = runnerInfo.Name | ||||
} | ||||
} | ||||
|
||||
// update instance workload state. | ||||
if _, err := r.setInstanceRunnerStatus(jobParams.RunnerName, params.RunnerTerminated); err != nil { | ||||
if errors.Is(err, runnerErrors.ErrNotFound) { | ||||
|
@@ -246,6 +263,20 @@ | |||
return errors.Wrap(err, "converting job to params") | ||||
} | ||||
|
||||
// Runner name was not set in WorkflowJob by github. We can still attempt to fetch the info we need, | ||||
// using the workflow run ID, from the API. | ||||
if job.WorkflowJob.RunnerName == "" { | ||||
// We may still get no runner name. In situations such as jobs being cancelled before a runner had the chance | ||||
// to pick up the job, the runner name is not available from the API. | ||||
if job.WorkflowJob.Conclusion != "skipped" && job.WorkflowJob.Conclusion != "canceled" { | ||||
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. There is very little chance that a workflow job that is Long story short, I think we can drop this check and just leave the one in the case where the job is Maybe just error our if the name is empty. 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. Was already wondering about this condition, tbh. |
||||
runnerInfo, err := r.getRunnerDetailsFromJob(job) | ||||
if err != nil && !errors.Is(err, runnerErrors.ErrNotFound) { | ||||
return errors.Wrap(err, "fetching runner details") | ||||
} | ||||
jobParams.RunnerName = runnerInfo.Name | ||||
} | ||||
} | ||||
|
||||
// update instance workload state. | ||||
instance, err := r.setInstanceRunnerStatus(jobParams.RunnerName, params.RunnerActive) | ||||
if err != nil { | ||||
|
@@ -954,6 +985,7 @@ | |||
StartedAt: job.WorkflowJob.StartedAt, | ||||
CompletedAt: job.WorkflowJob.CompletedAt, | ||||
Name: job.WorkflowJob.Name, | ||||
RunnerName: job.WorkflowJob.RunnerName, | ||||
GithubRunnerID: job.WorkflowJob.RunnerID, | ||||
RunnerGroupID: job.WorkflowJob.RunnerGroupID, | ||||
RunnerGroupName: job.WorkflowJob.RunnerGroupName, | ||||
|
@@ -962,23 +994,6 @@ | |||
Labels: job.WorkflowJob.Labels, | ||||
} | ||||
|
||||
runnerName := job.WorkflowJob.RunnerName | ||||
if job.Action != "queued" && runnerName == "" { | ||||
if job.WorkflowJob.Conclusion != "skipped" && job.WorkflowJob.Conclusion != "canceled" { | ||||
// Runner name was not set in WorkflowJob by github. We can still attempt to fetch the info we need, | ||||
// using the workflow run ID, from the API. | ||||
// We may still get no runner name. In situations such as jobs being cancelled before a runner had the chance | ||||
// to pick up the job, the runner name is not available from the API. | ||||
runnerInfo, err := r.getRunnerDetailsFromJob(job) | ||||
if err != nil && !errors.Is(err, runnerErrors.ErrNotFound) { | ||||
return jobParams, errors.Wrap(err, "fetching runner details") | ||||
} | ||||
runnerName = runnerInfo.Name | ||||
} | ||||
} | ||||
|
||||
jobParams.RunnerName = runnerName | ||||
|
||||
switch r.entity.EntityType { | ||||
case params.GithubEntityTypeEnterprise: | ||||
jobParams.EnterpriseID = &asUUID | ||||
|
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.
Not sure this is needed given the comment bellow.