vector 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -115,6 +115,12 @@ renewals - the group will not be scaled down.
115
115
  one, or else it's possible Vector may never find eligible nodes for
116
116
  scaledown and never scaledown.)
117
117
 
118
+ ### Integration with Predictive Scaling
119
+
120
+ Before scaling down, and if Predictive Scaling is in effect, Vector will
121
+ check to see if the size **after** scaling down would trigger Predictive
122
+ Scaling. If it would, the scaling policy will not be executed.
123
+
118
124
  ## Requirements
119
125
 
120
126
  * Auto Scaling groups must have the GroupInServiceInstances metric
@@ -28,29 +28,40 @@ module Vector
28
28
  end
29
29
  end
30
30
 
31
+ ps = nil
31
32
  if @config[:predictive_scaling][:enabled]
32
33
  psconf = @config[:predictive_scaling]
33
-
34
34
  ps = Vector::Function::PredictiveScaling.new(
35
35
  { :cloudwatch => cloudwatch }.merge(psconf))
36
-
37
- groups.each do |group|
38
- begin
39
- ps.run_for(group)
40
- rescue => e
41
- puts "error performing Predictive Scaling on #{group.name}: #{e.inspect}\n#{e.backtrace.join "\n"}"
42
- end
43
- end
44
36
  end
45
37
 
38
+ fds = nil
46
39
  if @config[:flexible_down_scaling][:enabled]
47
40
  fdsconf = @config[:flexible_down_scaling]
48
-
49
41
  fds = Vector::Function::FlexibleDownScaling.new(
50
42
  { :cloudwatch => cloudwatch }.merge(fdsconf))
43
+ end
44
+
45
+ groups.each do |group|
46
+ begin
47
+ ps_check_procs = nil
48
+
49
+ if ps
50
+ ps_result = ps.run_for(group)
51
+ ps_check_procs = ps_result[:check_procs]
52
+
53
+ if ps_result[:triggered]
54
+ # Don't need to evaluate for scaledown if we triggered a scaleup
55
+ next
56
+ end
57
+ end
58
+
59
+ if fds
60
+ fds.run_for(group, ps_check_procs)
61
+ end
51
62
 
52
- groups.each do |group|
53
- fds.run_for(group)
63
+ rescue => e
64
+ puts "error for #{group.name}: #{e.inspect}\n#{e.backtrace.join "\n"}"
54
65
  end
55
66
  end
56
67
  end
@@ -12,19 +12,21 @@ module Vector
12
12
  @max_sunk_cost = options[:max_sunk_cost]
13
13
  end
14
14
 
15
- def run_for(group)
15
+ def run_for(group, ps_check_procs)
16
+ result = { :triggered => false }
17
+
16
18
  hlog_ctx("group: #{group.name}") do
17
19
  # don't check if no config was specified
18
20
  if @up_down_cooldown.nil? && @down_down_cooldown.nil?
19
21
  hlog("No cooldown periods specified, exiting")
20
- return nil
22
+ return result
21
23
  end
22
24
 
23
25
  # don't bother checking for a scaledown if desired capacity is
24
26
  # already at the minimum size...
25
27
  if group.desired_capacity == group.min_size
26
28
  hlog("Group is already at minimum size, exiting")
27
- return nil
29
+ return result
28
30
  end
29
31
 
30
32
  scaledown_policies = group.scaling_policies.select do |policy|
@@ -33,6 +35,14 @@ module Vector
33
35
 
34
36
  scaledown_policies.each do |policy|
35
37
  hlog_ctx("policy: #{policy.name}") do
38
+ # TODO: support adjustment types other than ChangeInCapacity here
39
+ if policy.adjustment_type == "ChangeInCapacity" &&
40
+ ps_check_procs.any? {|ps_check_proc|
41
+ ps_check_proc.call(group.desired_capacity + policy.scaling_adjustment) }
42
+ hlog("Predictive scaleup would trigger a scaleup if group were shrunk")
43
+ next
44
+ end
45
+
36
46
  alarms = policy.alarms.keys.map do |alarm_name|
37
47
  @cloudwatch.alarms[alarm_name]
38
48
  end
@@ -61,11 +71,15 @@ module Vector
61
71
  hlog("Executing policy")
62
72
  policy.execute(:honor_cooldown => true)
63
73
 
74
+ result[:triggered] = true
75
+
64
76
  # no need to evaluate other scaledown policies
65
- return
77
+ return result
66
78
  end
67
79
  end
68
80
  end
81
+
82
+ result
69
83
  end
70
84
 
71
85
  protected
@@ -12,8 +12,10 @@ module Vector
12
12
  end
13
13
 
14
14
  def run_for(group)
15
+ result = { :check_procs => [], :triggered => false }
16
+
15
17
  hlog_ctx "group: #{group.name}" do
16
- return if @lookback_windows.length == 0
18
+ return result if @lookback_windows.length == 0
17
19
 
18
20
  scaleup_policies = group.scaling_policies.select do |policy|
19
21
  policy.scaling_adjustment > 0
@@ -70,15 +72,22 @@ module Vector
70
72
 
71
73
  # now take the past total load and divide it by the
72
74
  # current number of instances to get the predicted value
73
- predicted_value = past_load.to_f / now_num
74
- hlog "Predicted #{alarm.metric.name}: #{predicted_value}"
75
+ check_proc = Proc.new do |num_nodes|
76
+ predicted_value = past_load.to_f / num_nodes
77
+ hlog "Predicted #{alarm.metric.name}: #{predicted_value} (#{num_nodes} nodes)"
78
+
79
+ check_alarm_threshold(alarm, predicted_value)
80
+ end
81
+ result[:check_procs] << check_proc
75
82
 
76
- if check_alarm_threshold(alarm, predicted_value)
83
+ if check_proc.call(now_num)
77
84
  hlog "Executing policy"
78
85
  policy.execute(honor_cooldown: true)
79
86
 
87
+ result[:triggered] = true
88
+
80
89
  # don't need to evaluate further windows or policies on this group
81
- return
90
+ return result
82
91
  end
83
92
  end
84
93
  end
@@ -87,6 +96,8 @@ module Vector
87
96
  end
88
97
  end
89
98
  end
99
+
100
+ result
90
101
  end
91
102
 
92
103
  protected
@@ -1,3 +1,3 @@
1
1
  module Vector
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-09 00:00:00.000000000 Z
12
+ date: 2013-07-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: aws-sdk