-
Notifications
You must be signed in to change notification settings - Fork 15
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
Feature/auto scaling with usage #47
Conversation
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.
Good, just some changes
watcher/watcher.go
Outdated
@@ -600,75 +588,208 @@ func (w *Watcher) checkState( | |||
roomCount *models.RoomsStatusCount, | |||
scheduler *models.Scheduler, | |||
nowTimestamp int64, | |||
) (bool, bool, bool, error) { //shouldScaleUp, shouldScaleDown, changedState | |||
) (int, bool, bool, bool, error) { //delta, shouldScaleUp, shouldScaleDown, changedState |
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.
5 returns is too much, better create a new struct that contains the int and the three bools, then you return that struct and the error
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.
can't scaleup/down be inferred from the delta sign? if positive we should scaleup and if negative we should scaledown
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.
I agree
watcher/watcher.go
Outdated
|
||
// If usage is above limit, scale up. | ||
if isDown == false && 100*roomCount.Occupied >= roomCount.Total()*trigger.Limit { | ||
w.Logger.Debug("Usage is above limit. Should scale up") |
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.
This can be extracted to another function. The idea is reduce the size of this function and simplify it
watcher/watcher.go
Outdated
if 100*roomCount.Occupied >= roomCount.Total()*autoScalingInfo.Up.Trigger.Limit { | ||
scaleInfo.SendUsage( | ||
w.SchedulerName, | ||
"legacy", point, roomCount.Total(), |
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.
Better to put "legacy" on constants to avoid typos
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.
words of wisdom
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.
Just a few comments
dev-room/app.py
Outdated
@@ -37,6 +48,7 @@ def ping(): | |||
except Exception as ex: | |||
print(str(ex)) | |||
pass | |||
break |
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.
why the pass
and the break
?
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.
it shouldn't have break
. Forgot to take it off =/
watcher/utils.go
Outdated
roomCount *models.RoomsStatusCount, | ||
) int { // delta | ||
usageThreshold := float32(metricTrigger.Usage) / 100 | ||
return int(float32(float32(roomCount.Occupied)-float32(usageThreshold*float32(roomCount.Total()))) / usageThreshold) |
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.
shouldn't we round up instead of just converting to int?
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.
yes
watcher/watcher.go
Outdated
@@ -600,75 +588,208 @@ func (w *Watcher) checkState( | |||
roomCount *models.RoomsStatusCount, | |||
scheduler *models.Scheduler, | |||
nowTimestamp int64, | |||
) (bool, bool, bool, error) { //shouldScaleUp, shouldScaleDown, changedState | |||
) (int, bool, bool, bool, error) { //delta, shouldScaleUp, shouldScaleDown, changedState |
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.
can't scaleup/down be inferred from the delta sign? if positive we should scaleup and if negative we should scaledown
watcher/watcher.go
Outdated
} else if inSync == true { // always send current usage | ||
if len(autoScalingInfo.Down.MetricsTrigger) > 0 { | ||
for _, trigger := range autoScalingInfo.Down.MetricsTrigger { | ||
w.ScaleDownInfo.SendUsage( |
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.
I couldn't find any sendUsage for scale up, it this intended? or am I missing something?
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.
On scaleUp it will call SendUsageAndReturnStatus(). SendUsage() is called here because checkMetricsTrigger will not be called for down scaling if up scaling is needed.
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.
so we have two separate usage metrics, one for scaling up and another for scaling down?
watcher/watcher.go
Outdated
if 100*roomCount.Occupied >= roomCount.Total()*autoScalingInfo.Up.Trigger.Limit { | ||
scaleInfo.SendUsage( | ||
w.SchedulerName, | ||
"legacy", point, roomCount.Total(), |
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.
words of wisdom
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.
Will these changes be backwards compatible? I don't think so but I'm not sure it will be a big problem.
watcher/utils.go
Outdated
@@ -30,6 +31,12 @@ func roomDynamicDelta( | |||
metricTrigger *models.ScalingPolicyMetricsTrigger, | |||
roomCount *models.RoomsStatusCount, | |||
) int { // delta | |||
usageThreshold := float32(metricTrigger.Usage) / 100 | |||
return int(float32(float32(roomCount.Occupied)-float32(usageThreshold*float32(roomCount.Total()))) / usageThreshold) | |||
// [Occupied / (Total + Delta)] = Usage/100 |
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.
much clearer 😌
The changes should be backwards compatible. The only issue is with the redis set that now is the same for both up and down scaling. |
watcher/utils.go
Outdated
) | ||
|
||
func dynamicDelta( | ||
metricTrigger *models.ScalingPolicyMetricsTrigger, |
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.
You could use ScalingPolicyMetricsTrigger as an interface actually, with the methods Metric() and Usage(). Or with the method DynamicDelta(). That way you won't need a switch/case statement.
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.
Will do
watcher/watcher.go
Outdated
) (bool, bool, bool, error) { //shouldScaleUp, shouldScaleDown, changedState | ||
var shouldScaleUp, shouldScaleDown, changedState bool | ||
inSync := true | ||
) (*scaling, error) { //delta, shouldScaleUp, shouldScaleDown, changedState |
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.
We don't need this comment anymore ;)
watcher/watcher.go
Outdated
usage := float32(autoScalingInfo.Up.Trigger.Usage) / 100 | ||
capacity := autoScalingInfo.Up.Trigger.Time / w.AutoScalingPeriod | ||
// Send current usage | ||
if len(autoScalingInfo.Down.MetricsTrigger) > 0 { |
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.
This method is too long. You could separate the ifs into methods whose names are their intention.
watcher/watcher.go
Outdated
return scaling, nil | ||
} | ||
|
||
func (w *Watcher) checkLegacyTrigger( |
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.
There is too much duplicated code with checkMetricsTrigger. Couldn't you merge them? For example, The for loop on checkMetricsTrigger could be extracted and receive the same parameters checkLegacyTrigger uses.
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.
will do
…terminating status)
autoscaler/cpu_and_mem_scaler.go
Outdated
func getMemUsageAndRequests(usage, requests v1.ResourceList) (float32, float32) { | ||
resourceRequests := float32(requests.Memory().ScaledValue(0)) | ||
resourceUsage := float32(usage.Memory().ScaledValue(0)) | ||
fmt.Printf("\nrequests: %v | usage: %v\n", requests.Memory().Value(), usage.Memory().Value()) |
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.
debug logs?
autoscaler/cpu_and_mem_scaler.go
Outdated
usageRatio := currentUtilization / float32(trigger.Usage) / 100 | ||
delta := int(math.Ceil(float64(usageRatio)*float64(roomCount.Available()))) - roomCount.Available() | ||
|
||
fmt.Printf("\ncurrentUtilization: %v | usageRatio: %v | roomCount: %v | delta: %v\n", currentUtilization, usageRatio, roomCount.Available(), delta) |
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.
same
autoscaler/cpu_and_mem_scaler.go
Outdated
|
||
for _, pod := range podList.Items { | ||
for i, container := range pod.Containers { | ||
if container.Name == pod.Name { // Get game room container |
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.
probably this is not the best way to check
api/app.go
Outdated
@@ -56,6 +57,7 @@ type App struct { | |||
DBClient *pg.Client | |||
RedisClient *redis.Client | |||
KubernetesClient kubernetes.Interface | |||
KubernetesMetricsClient metricsClient.Interface |
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.
linter should align this
9ef73ac
to
5289a40
Compare
controller/controller_test.go
Outdated
@@ -538,6 +644,98 @@ portRange: | |||
}) | |||
}) | |||
|
|||
FIt("should return error if autoscaling min > max", func() { |
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.
All tests must be It()
@@ -0,0 +1,32 @@ | |||
import falcon |
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.
@lftakakura this is the best file in the project 🤣
No description provided.