vector 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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