2020-06-27 17:26:46 +09:00
package controllers
import (
"context"
2020-07-03 09:05:46 +09:00
"errors"
2020-06-27 17:26:46 +09:00
"fmt"
2020-12-14 21:38:01 -08:00
"math"
2020-12-12 15:48:19 -08:00
"strconv"
2020-06-27 17:26:46 +09:00
"strings"
2020-10-07 17:00:44 -07:00
2021-06-22 17:55:06 +09:00
"github.com/actions-runner-controller/actions-runner-controller/api/v1alpha1"
2022-08-15 19:42:00 +05:30
prometheus_metrics "github.com/actions-runner-controller/actions-runner-controller/controllers/metrics"
2022-07-12 09:45:00 +09:00
arcgithub "github.com/actions-runner-controller/actions-runner-controller/github"
2022-08-24 13:08:40 +09:00
"github.com/google/go-github/v47/github"
2022-06-29 20:49:21 +09:00
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
2020-12-12 15:48:19 -08:00
)
const (
defaultScaleUpThreshold = 0.8
defaultScaleDownThreshold = 0.3
defaultScaleUpFactor = 1.3
defaultScaleDownFactor = 0.7
2020-06-27 17:26:46 +09:00
)
2022-07-12 09:45:00 +09:00
func ( r * HorizontalRunnerAutoscalerReconciler ) suggestDesiredReplicas ( ghc * arcgithub . Client , st scaleTarget , hra v1alpha1 . HorizontalRunnerAutoscaler ) ( * int , error ) {
2020-07-19 18:42:06 +09:00
if hra . Spec . MinReplicas == nil {
return nil , fmt . Errorf ( "horizontalrunnerautoscaler %s/%s is missing minReplicas" , hra . Namespace , hra . Name )
} else if hra . Spec . MaxReplicas == nil {
return nil , fmt . Errorf ( "horizontalrunnerautoscaler %s/%s is missing maxReplicas" , hra . Namespace , hra . Name )
2020-06-27 17:26:46 +09:00
}
2020-12-12 15:48:19 -08:00
metrics := hra . Spec . Metrics
2021-05-05 14:27:17 +09:00
numMetrics := len ( metrics )
if numMetrics == 0 {
2022-04-24 13:36:42 +09:00
// We don't default to anything since ARC 0.23.0
// See https://github.com/actions-runner-controller/actions-runner-controller/issues/728
Do not delay min/maxReplicas propagation from HRA to RD due to caching (#406)
As part of #282, I have introduced some caching mechanism to avoid excessive GitHub API calls due to the autoscaling calculation involving GitHub API calls is executed on each Webhook event.
Apparently, it was saving the wrong value in the cache- The value was one after applying `HRA.Spec.{Max,Min}Replicas` so manual changes to {Max,Min}Replicas doesn't affect RunnerDeployment.Spec.Replicas until the cache expires. This isn't what I had wanted.
This patch fixes that, by changing the value being cached to one before applying {Min,Max}Replicas.
Additionally, I've also updated logging so that you observe which number was fetched from cache, and what number was suggested by either TotalNumberOfQueuedAndInProgressWorkflowRuns or PercentageRunnersBusy, and what was the final number used as the desired-replicas(after applying {Min,Max}Replicas).
Follow-up for #282
2021-03-19 12:58:02 +09:00
return nil , nil
2021-05-05 14:27:17 +09:00
} else if numMetrics > 2 {
2021-09-26 07:34:55 +02:00
return nil , fmt . Errorf ( "too many autoscaling metrics configured: It must be 0 to 2, but got %d" , numMetrics )
2021-05-05 14:27:17 +09:00
}
primaryMetric := metrics [ 0 ]
primaryMetricType := primaryMetric . Type
var (
suggested * int
err error
)
switch primaryMetricType {
case v1alpha1 . AutoscalingMetricTypeTotalNumberOfQueuedAndInProgressWorkflowRuns :
2022-07-12 09:45:00 +09:00
suggested , err = r . suggestReplicasByQueuedAndInProgressWorkflowRuns ( ghc , st , hra , & primaryMetric )
2021-05-05 14:27:17 +09:00
case v1alpha1 . AutoscalingMetricTypePercentageRunnersBusy :
2022-07-12 09:45:00 +09:00
suggested , err = r . suggestReplicasByPercentageRunnersBusy ( ghc , st , hra , primaryMetric )
2021-05-05 14:27:17 +09:00
default :
2021-09-26 07:34:55 +02:00
return nil , fmt . Errorf ( "validating autoscaling metrics: unsupported metric type %q" , primaryMetric )
2021-05-05 14:27:17 +09:00
}
if err != nil {
return nil , err
}
if suggested != nil && * suggested > 0 {
return suggested , nil
2020-12-12 15:48:19 -08:00
}
2021-05-05 14:27:17 +09:00
if len ( metrics ) == 1 {
// This is never supposed to happen but anyway-
// Fall-back to `minReplicas + capacityReservedThroughWebhook`.
return nil , nil
}
// At this point, we are sure that there are exactly 2 Metrics entries.
fallbackMetric := metrics [ 1 ]
fallbackMetricType := fallbackMetric . Type
if primaryMetricType != v1alpha1 . AutoscalingMetricTypePercentageRunnersBusy ||
fallbackMetricType != v1alpha1 . AutoscalingMetricTypeTotalNumberOfQueuedAndInProgressWorkflowRuns {
return nil , fmt . Errorf (
"invalid HRA Spec: Metrics[0] of %s cannot be combined with Metrics[1] of %s: The only allowed combination is 0=PercentageRunnersBusy and 1=TotalNumberOfQueuedAndInProgressWorkflowRuns" ,
primaryMetricType , fallbackMetricType ,
)
}
2022-07-12 09:45:00 +09:00
return r . suggestReplicasByQueuedAndInProgressWorkflowRuns ( ghc , st , hra , & fallbackMetric )
2020-12-12 15:48:19 -08:00
}
2022-07-12 09:45:00 +09:00
func ( r * HorizontalRunnerAutoscalerReconciler ) suggestReplicasByQueuedAndInProgressWorkflowRuns ( ghc * arcgithub . Client , st scaleTarget , hra v1alpha1 . HorizontalRunnerAutoscaler , metrics * v1alpha1 . MetricSpec ) ( * int , error ) {
2020-12-12 15:48:19 -08:00
var repos [ ] [ ] string
2021-06-23 20:25:03 +09:00
repoID := st . repo
2020-06-27 17:26:46 +09:00
if repoID == "" {
2021-06-23 20:25:03 +09:00
orgName := st . org
2020-07-03 09:05:46 +09:00
if orgName == "" {
return nil , fmt . Errorf ( "asserting runner deployment spec to detect bug: spec.template.organization should not be empty on this code path" )
}
2021-03-09 15:03:47 +09:00
// In case it's an organizational runners deployment without any scaling metrics defined,
// we assume that the desired replicas should always be `minReplicas + capacityReservedThroughWebhook`.
2021-06-22 17:55:06 +09:00
// See https://github.com/actions-runner-controller/actions-runner-controller/issues/377#issuecomment-793372693
2021-05-05 14:27:17 +09:00
if metrics == nil {
Do not delay min/maxReplicas propagation from HRA to RD due to caching (#406)
As part of #282, I have introduced some caching mechanism to avoid excessive GitHub API calls due to the autoscaling calculation involving GitHub API calls is executed on each Webhook event.
Apparently, it was saving the wrong value in the cache- The value was one after applying `HRA.Spec.{Max,Min}Replicas` so manual changes to {Max,Min}Replicas doesn't affect RunnerDeployment.Spec.Replicas until the cache expires. This isn't what I had wanted.
This patch fixes that, by changing the value being cached to one before applying {Min,Max}Replicas.
Additionally, I've also updated logging so that you observe which number was fetched from cache, and what number was suggested by either TotalNumberOfQueuedAndInProgressWorkflowRuns or PercentageRunnersBusy, and what was the final number used as the desired-replicas(after applying {Min,Max}Replicas).
Follow-up for #282
2021-03-19 12:58:02 +09:00
return nil , nil
2021-03-09 15:03:47 +09:00
}
2021-05-05 14:27:17 +09:00
if len ( metrics . RepositoryNames ) == 0 {
2020-07-03 09:05:46 +09:00
return nil , errors . New ( "validating autoscaling metrics: spec.autoscaling.metrics[].repositoryNames is required and must have one more more entries for organizational runner deployment" )
}
2021-05-05 14:27:17 +09:00
for _ , repoName := range metrics . RepositoryNames {
2020-07-03 09:05:46 +09:00
repos = append ( repos , [ ] string { orgName , repoName } )
}
} else {
repo := strings . Split ( repoID , "/" )
repos = append ( repos , repo )
2020-06-27 17:26:46 +09:00
}
var total , inProgress , queued , completed , unknown int
2020-10-07 17:00:44 -07:00
type callback func ( )
listWorkflowJobs := func ( user string , repoName string , runID int64 , fallback_cb callback ) {
if runID == 0 {
fallback_cb ( )
return
}
2021-12-24 01:12:36 +01:00
opt := github . ListWorkflowJobsOptions { ListOptions : github . ListOptions { PerPage : 50 } }
var allJobs [ ] * github . WorkflowJob
for {
2022-07-12 09:45:00 +09:00
jobs , resp , err := ghc . Actions . ListWorkflowJobs ( context . TODO ( ) , user , repoName , runID , & opt )
2021-12-24 01:12:36 +01:00
if err != nil {
r . Log . Error ( err , "Error listing workflow jobs" )
return //err
}
allJobs = append ( allJobs , jobs . Jobs ... )
if resp . NextPage == 0 {
break
}
opt . Page = resp . NextPage
}
if len ( allJobs ) == 0 {
2020-10-07 17:00:44 -07:00
fallback_cb ( )
} else {
2022-04-24 14:41:34 +09:00
JOB :
2021-12-24 01:12:36 +01:00
for _ , job := range allJobs {
2022-04-28 00:24:21 +09:00
runnerLabels := make ( map [ string ] struct { } , len ( st . labels ) )
for _ , l := range st . labels {
runnerLabels [ l ] = struct { } { }
2022-04-24 14:41:34 +09:00
}
2022-04-28 00:24:21 +09:00
if len ( job . Labels ) == 0 {
// This shouldn't usually happen
r . Log . Info ( "Detected job with no labels, which is not supported by ARC. Skipping anyway." , "labels" , job . Labels , "run_id" , job . GetRunID ( ) , "job_id" , job . GetID ( ) )
2022-04-24 14:41:34 +09:00
continue JOB
}
2022-04-28 00:24:21 +09:00
for _ , l := range job . Labels {
if l == "self-hosted" {
continue
}
if _ , ok := runnerLabels [ l ] ; ! ok {
2022-04-24 14:41:34 +09:00
continue JOB
}
}
2020-10-07 17:00:44 -07:00
switch job . GetStatus ( ) {
case "completed" :
// We add a case for `completed` so it is not counted in `unknown`.
// And we do not increment the counter for completed because
// that counter only refers to workflows. The reason for
// this is because we do not get a list of jobs for
// completed workflows in order to keep the number of API
// calls to a minimum.
case "in_progress" :
inProgress ++
case "queued" :
queued ++
default :
unknown ++
}
}
}
}
2020-06-27 17:26:46 +09:00
2020-07-03 09:05:46 +09:00
for _ , repo := range repos {
user , repoName := repo [ 0 ] , repo [ 1 ]
2022-07-12 09:45:00 +09:00
workflowRuns , err := ghc . ListRepositoryWorkflowRuns ( context . TODO ( ) , user , repoName )
2020-07-03 09:05:46 +09:00
if err != nil {
return nil , err
}
2021-02-09 10:13:53 +09:00
for _ , run := range workflowRuns {
2020-07-03 09:05:46 +09:00
total ++
// In May 2020, there are only 3 statuses.
// Follow the below links for more details:
// - https://developer.github.com/v3/actions/workflow-runs/#list-repository-workflow-runs
// - https://developer.github.com/v3/checks/runs/#create-a-check-run
2020-10-07 17:00:44 -07:00
switch run . GetStatus ( ) {
2020-07-03 09:05:46 +09:00
case "completed" :
completed ++
case "in_progress" :
2020-10-07 17:00:44 -07:00
listWorkflowJobs ( user , repoName , run . GetID ( ) , func ( ) { inProgress ++ } )
2020-07-03 09:05:46 +09:00
case "queued" :
2020-10-07 17:00:44 -07:00
listWorkflowJobs ( user , repoName , run . GetID ( ) , func ( ) { queued ++ } )
2020-07-03 09:05:46 +09:00
default :
unknown ++
}
2020-06-27 17:26:46 +09:00
}
}
necessaryReplicas := queued + inProgress
2022-08-15 19:42:00 +05:30
prometheus_metrics . SetHorizontalRunnerAutoscalerQueuedAndInProgressWorkflowRuns (
hra . ObjectMeta ,
st . enterprise ,
st . org ,
st . repo ,
st . kind ,
st . st ,
necessaryReplicas ,
completed ,
inProgress ,
queued ,
unknown ,
)
2020-06-27 17:26:46 +09:00
r . Log . V ( 1 ) . Info (
Do not delay min/maxReplicas propagation from HRA to RD due to caching (#406)
As part of #282, I have introduced some caching mechanism to avoid excessive GitHub API calls due to the autoscaling calculation involving GitHub API calls is executed on each Webhook event.
Apparently, it was saving the wrong value in the cache- The value was one after applying `HRA.Spec.{Max,Min}Replicas` so manual changes to {Max,Min}Replicas doesn't affect RunnerDeployment.Spec.Replicas until the cache expires. This isn't what I had wanted.
This patch fixes that, by changing the value being cached to one before applying {Min,Max}Replicas.
Additionally, I've also updated logging so that you observe which number was fetched from cache, and what number was suggested by either TotalNumberOfQueuedAndInProgressWorkflowRuns or PercentageRunnersBusy, and what was the final number used as the desired-replicas(after applying {Min,Max}Replicas).
Follow-up for #282
2021-03-19 12:58:02 +09:00
fmt . Sprintf ( "Suggested desired replicas of %d by TotalNumberOfQueuedAndInProgressWorkflowRuns" , necessaryReplicas ) ,
2020-06-27 17:26:46 +09:00
"workflow_runs_completed" , completed ,
"workflow_runs_in_progress" , inProgress ,
"workflow_runs_queued" , queued ,
"workflow_runs_unknown" , unknown ,
2021-02-16 12:44:51 +09:00
"namespace" , hra . Namespace ,
2021-06-23 20:25:03 +09:00
"kind" , st . kind ,
"name" , st . st ,
2021-02-16 12:44:51 +09:00
"horizontal_runner_autoscaler" , hra . Name ,
2020-06-27 17:26:46 +09:00
)
Do not delay min/maxReplicas propagation from HRA to RD due to caching (#406)
As part of #282, I have introduced some caching mechanism to avoid excessive GitHub API calls due to the autoscaling calculation involving GitHub API calls is executed on each Webhook event.
Apparently, it was saving the wrong value in the cache- The value was one after applying `HRA.Spec.{Max,Min}Replicas` so manual changes to {Max,Min}Replicas doesn't affect RunnerDeployment.Spec.Replicas until the cache expires. This isn't what I had wanted.
This patch fixes that, by changing the value being cached to one before applying {Min,Max}Replicas.
Additionally, I've also updated logging so that you observe which number was fetched from cache, and what number was suggested by either TotalNumberOfQueuedAndInProgressWorkflowRuns or PercentageRunnersBusy, and what was the final number used as the desired-replicas(after applying {Min,Max}Replicas).
Follow-up for #282
2021-03-19 12:58:02 +09:00
return & necessaryReplicas , nil
2020-06-27 17:26:46 +09:00
}
2020-12-12 15:48:19 -08:00
2022-07-12 09:45:00 +09:00
func ( r * HorizontalRunnerAutoscalerReconciler ) suggestReplicasByPercentageRunnersBusy ( ghc * arcgithub . Client , st scaleTarget , hra v1alpha1 . HorizontalRunnerAutoscaler , metrics v1alpha1 . MetricSpec ) ( * int , error ) {
2020-12-12 15:48:19 -08:00
ctx := context . Background ( )
scaleUpThreshold := defaultScaleUpThreshold
scaleDownThreshold := defaultScaleDownThreshold
scaleUpFactor := defaultScaleUpFactor
scaleDownFactor := defaultScaleDownFactor
if metrics . ScaleUpThreshold != "" {
sut , err := strconv . ParseFloat ( metrics . ScaleUpThreshold , 64 )
if err != nil {
return nil , errors . New ( "validating autoscaling metrics: spec.autoscaling.metrics[].scaleUpThreshold cannot be parsed into a float64" )
}
scaleUpThreshold = sut
}
if metrics . ScaleDownThreshold != "" {
sdt , err := strconv . ParseFloat ( metrics . ScaleDownThreshold , 64 )
if err != nil {
return nil , errors . New ( "validating autoscaling metrics: spec.autoscaling.metrics[].scaleDownThreshold cannot be parsed into a float64" )
}
scaleDownThreshold = sdt
}
2021-02-16 17:16:26 +09:00
scaleUpAdjustment := metrics . ScaleUpAdjustment
if scaleUpAdjustment != 0 {
if metrics . ScaleUpAdjustment < 0 {
return nil , errors . New ( "validating autoscaling metrics: spec.autoscaling.metrics[].scaleUpAdjustment cannot be lower than 0" )
}
if metrics . ScaleUpFactor != "" {
return nil , errors . New ( "validating autoscaling metrics: spec.autoscaling.metrics[]: scaleUpAdjustment and scaleUpFactor cannot be specified together" )
}
} else if metrics . ScaleUpFactor != "" {
2020-12-12 15:48:19 -08:00
suf , err := strconv . ParseFloat ( metrics . ScaleUpFactor , 64 )
if err != nil {
return nil , errors . New ( "validating autoscaling metrics: spec.autoscaling.metrics[].scaleUpFactor cannot be parsed into a float64" )
}
scaleUpFactor = suf
}
2021-02-16 17:16:26 +09:00
scaleDownAdjustment := metrics . ScaleDownAdjustment
if scaleDownAdjustment != 0 {
if metrics . ScaleDownAdjustment < 0 {
return nil , errors . New ( "validating autoscaling metrics: spec.autoscaling.metrics[].scaleDownAdjustment cannot be lower than 0" )
}
if metrics . ScaleDownFactor != "" {
return nil , errors . New ( "validating autoscaling metrics: spec.autoscaling.metrics[]: scaleDownAdjustment and scaleDownFactor cannot be specified together" )
}
} else if metrics . ScaleDownFactor != "" {
2020-12-12 15:48:19 -08:00
sdf , err := strconv . ParseFloat ( metrics . ScaleDownFactor , 64 )
if err != nil {
return nil , errors . New ( "validating autoscaling metrics: spec.autoscaling.metrics[].scaleDownFactor cannot be parsed into a float64" )
}
scaleDownFactor = sdf
}
2021-06-23 20:25:03 +09:00
runnerMap , err := st . getRunnerMap ( )
2021-03-05 10:15:39 +09:00
if err != nil {
return nil , err
}
2021-03-11 20:16:36 +09:00
2021-02-16 12:44:51 +09:00
var (
2021-06-23 20:25:03 +09:00
enterprise = st . enterprise
organization = st . org
repository = st . repo
2021-02-16 12:44:51 +09:00
)
2020-12-12 15:48:19 -08:00
// ListRunners will return all runners managed by GitHub - not restricted to ns
2022-07-12 09:45:00 +09:00
runners , err := ghc . ListRunners (
2021-02-16 12:44:51 +09:00
ctx ,
enterprise ,
organization ,
repository )
2020-12-12 15:48:19 -08:00
if err != nil {
return nil , err
}
2021-03-05 10:21:20 +09:00
var desiredReplicasBefore int
2021-06-23 20:25:03 +09:00
if v := st . replicas ; v == nil {
2021-03-05 10:21:20 +09:00
desiredReplicasBefore = 1
} else {
desiredReplicasBefore = * v
}
var (
numRunners int
numRunnersRegistered int
numRunnersBusy int
2022-06-29 20:49:21 +09:00
numTerminatingBusy int
2021-03-05 10:21:20 +09:00
)
2021-06-23 20:25:03 +09:00
numRunners = len ( runnerMap )
2021-03-05 10:21:20 +09:00
2022-06-29 20:49:21 +09:00
busyTerminatingRunnerPods := map [ string ] struct { } { }
kindLabel := LabelKeyRunnerDeploymentName
if hra . Spec . ScaleTargetRef . Kind == "RunnerSet" {
kindLabel = LabelKeyRunnerSetName
}
var runnerPodList corev1 . PodList
if err := r . Client . List ( ctx , & runnerPodList , client . InNamespace ( hra . Namespace ) , client . MatchingLabels ( map [ string ] string {
kindLabel : hra . Spec . ScaleTargetRef . Name ,
} ) ) ; err != nil {
return nil , err
}
for _ , p := range runnerPodList . Items {
if p . Annotations [ AnnotationKeyUnregistrationFailureMessage ] != "" {
busyTerminatingRunnerPods [ p . Name ] = struct { } { }
}
}
2020-12-12 15:48:19 -08:00
for _ , runner := range runners {
2021-03-05 10:21:20 +09:00
if _ , ok := runnerMap [ * runner . Name ] ; ok {
numRunnersRegistered ++
if runner . GetBusy ( ) {
numRunnersBusy ++
2022-06-29 20:49:21 +09:00
} else if _ , ok := busyTerminatingRunnerPods [ * runner . Name ] ; ok {
numTerminatingBusy ++
2021-03-05 10:21:20 +09:00
}
2022-06-29 20:49:21 +09:00
delete ( busyTerminatingRunnerPods , * runner . Name )
2020-12-12 15:48:19 -08:00
}
}
2022-06-29 20:49:21 +09:00
// Remaining busyTerminatingRunnerPods are runners that were not on the ListRunners API response yet
for range busyTerminatingRunnerPods {
numTerminatingBusy ++
}
2020-12-12 15:48:19 -08:00
var desiredReplicas int
2022-06-29 20:49:21 +09:00
fractionBusy := float64 ( numRunnersBusy + numTerminatingBusy ) / float64 ( desiredReplicasBefore )
2020-12-12 15:48:19 -08:00
if fractionBusy >= scaleUpThreshold {
2021-02-16 17:16:26 +09:00
if scaleUpAdjustment > 0 {
2021-03-05 10:21:20 +09:00
desiredReplicas = desiredReplicasBefore + scaleUpAdjustment
2021-02-16 17:16:26 +09:00
} else {
2021-03-05 10:21:20 +09:00
desiredReplicas = int ( math . Ceil ( float64 ( desiredReplicasBefore ) * scaleUpFactor ) )
2021-02-16 17:16:26 +09:00
}
2020-12-12 15:48:19 -08:00
} else if fractionBusy < scaleDownThreshold {
2021-02-16 17:16:26 +09:00
if scaleDownAdjustment > 0 {
2021-03-05 10:21:20 +09:00
desiredReplicas = desiredReplicasBefore - scaleDownAdjustment
2021-02-16 17:16:26 +09:00
} else {
2021-03-05 10:21:20 +09:00
desiredReplicas = int ( float64 ( desiredReplicasBefore ) * scaleDownFactor )
2021-02-16 17:16:26 +09:00
}
2020-12-12 15:48:19 -08:00
} else {
2021-06-23 20:25:03 +09:00
desiredReplicas = * st . replicas
2020-12-12 15:48:19 -08:00
}
2021-01-24 10:58:35 +09:00
2021-03-05 10:21:20 +09:00
// NOTES for operators:
//
// - num_runners can be as twice as large as replicas_desired_before while
// the runnerdeployment controller is replacing RunnerReplicaSet for runner update.
2022-08-15 19:42:00 +05:30
prometheus_metrics . SetHorizontalRunnerAutoscalerPercentageRunnersBusy (
hra . ObjectMeta ,
st . enterprise ,
st . org ,
st . repo ,
st . kind ,
st . st ,
desiredReplicas ,
numRunners ,
numRunnersRegistered ,
numRunnersBusy ,
numTerminatingBusy ,
)
2021-03-05 10:21:20 +09:00
2020-12-12 15:48:19 -08:00
r . Log . V ( 1 ) . Info (
Do not delay min/maxReplicas propagation from HRA to RD due to caching (#406)
As part of #282, I have introduced some caching mechanism to avoid excessive GitHub API calls due to the autoscaling calculation involving GitHub API calls is executed on each Webhook event.
Apparently, it was saving the wrong value in the cache- The value was one after applying `HRA.Spec.{Max,Min}Replicas` so manual changes to {Max,Min}Replicas doesn't affect RunnerDeployment.Spec.Replicas until the cache expires. This isn't what I had wanted.
This patch fixes that, by changing the value being cached to one before applying {Min,Max}Replicas.
Additionally, I've also updated logging so that you observe which number was fetched from cache, and what number was suggested by either TotalNumberOfQueuedAndInProgressWorkflowRuns or PercentageRunnersBusy, and what was the final number used as the desired-replicas(after applying {Min,Max}Replicas).
Follow-up for #282
2021-03-19 12:58:02 +09:00
fmt . Sprintf ( "Suggested desired replicas of %d by PercentageRunnersBusy" , desiredReplicas ) ,
2021-03-05 10:21:20 +09:00
"replicas_desired_before" , desiredReplicasBefore ,
"replicas_desired" , desiredReplicas ,
2020-12-12 15:48:19 -08:00
"num_runners" , numRunners ,
2021-03-05 10:21:20 +09:00
"num_runners_registered" , numRunnersRegistered ,
2020-12-12 15:48:19 -08:00
"num_runners_busy" , numRunnersBusy ,
2022-06-29 20:49:21 +09:00
"num_terminating_busy" , numTerminatingBusy ,
2021-02-16 12:44:51 +09:00
"namespace" , hra . Namespace ,
2021-06-23 20:25:03 +09:00
"kind" , st . kind ,
"name" , st . st ,
2021-02-16 12:44:51 +09:00
"horizontal_runner_autoscaler" , hra . Name ,
"enterprise" , enterprise ,
"organization" , organization ,
"repository" , repository ,
2020-12-12 15:48:19 -08:00
)
Do not delay min/maxReplicas propagation from HRA to RD due to caching (#406)
As part of #282, I have introduced some caching mechanism to avoid excessive GitHub API calls due to the autoscaling calculation involving GitHub API calls is executed on each Webhook event.
Apparently, it was saving the wrong value in the cache- The value was one after applying `HRA.Spec.{Max,Min}Replicas` so manual changes to {Max,Min}Replicas doesn't affect RunnerDeployment.Spec.Replicas until the cache expires. This isn't what I had wanted.
This patch fixes that, by changing the value being cached to one before applying {Min,Max}Replicas.
Additionally, I've also updated logging so that you observe which number was fetched from cache, and what number was suggested by either TotalNumberOfQueuedAndInProgressWorkflowRuns or PercentageRunnersBusy, and what was the final number used as the desired-replicas(after applying {Min,Max}Replicas).
Follow-up for #282
2021-03-19 12:58:02 +09:00
return & desiredReplicas , nil
2020-12-12 15:48:19 -08:00
}