drone 0.0.3 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,71 +1,81 @@
1
+ require File.expand_path('../../core', __FILE__)
1
2
 
2
- class ExponentiallyDecayingSample
3
- # 1 hour in ms
4
- RESCALE_THRESHOLD = (1 * 60 * 60 * 1000).freeze
3
+ module Drone
4
+ class ExponentiallyDecayingSample
5
+ # 1 hour in ms
6
+ RESCALE_THRESHOLD = (1 * 60 * 60 * 1000).freeze
5
7
 
6
- def initialize(reservoir_size, alpha)
7
- @values = {}
8
- @alpha = alpha
9
- @reservoir_size = reservoir_size
10
- clear()
11
- end
8
+ def initialize(id, reservoir_size, alpha)
9
+ @id = id
10
+ @values = Drone::request_hash("#{@id}:values")
11
+ @count = Drone::request_number("#{@id}:count", 0)
12
+ @start_time = Drone::request_number("#{@id}:start_time", current_time())
13
+ @next_scale_time = Drone::request_number("#{@id}:next_scale_time", current_time() + RESCALE_THRESHOLD)
14
+
15
+ @alpha = alpha
16
+ @reservoir_size = reservoir_size
17
+ end
12
18
 
13
- def clear
14
- @values.clear()
15
- @count = 0
16
- @start_time = Time.now
17
- @next_scale_time = current_time() + RESCALE_THRESHOLD
18
- end
19
+ def clear
20
+ @values.clear()
21
+ @count.set(0)
22
+ @start_time.set(current_time())
23
+ @next_scale_time.set( current_time() + RESCALE_THRESHOLD )
24
+ end
19
25
 
20
- def size
21
- (@values.size < @count) ? @values.size : @count
22
- end
26
+ def size
27
+ count = @count.get
28
+ (@values.size < count) ? @values.size : count
29
+ end
23
30
 
24
31
 
25
- def update(val, time = Time.now)
26
- priority = weight(time - @start_time) / rand()
27
- @count += 1
28
- if @count <= @reservoir_size
29
- @values[priority] = val
30
- else
31
- first = @values.keys.min
32
- if first < priority
32
+ def update(val, time = current_time)
33
+ priority = weight(time - @start_time.get) / rand()
34
+ count = @count.inc
35
+ if count <= @reservoir_size
33
36
  @values[priority] = val
34
- while @values.delete(first) == nil
35
- first = @values.keys.min
37
+ else
38
+ first = @values.keys.min
39
+ if first < priority
40
+ @values[priority] = val
41
+ while @values.delete(first) == nil
42
+ first = @values.keys.min
43
+ end
36
44
  end
37
45
  end
38
- end
39
46
 
40
- now = current_time()
41
- if now >= @next_scale_time
42
- rescale(now)
47
+ now = current_time()
48
+ if now >= @next_scale_time.get
49
+ rescale(now)
50
+ end
43
51
  end
44
- end
45
52
 
46
- def values
47
- @values.values
48
- end
53
+ def values
54
+ @values.keys.sort.inject([]) do |buff, key|
55
+ buff << @values[key]
56
+ end
57
+ end
49
58
 
50
- def rescale(now)
51
- @next_scale_time = current_time() + RESCALE_THRESHOLD
52
- old_start = @start_time
53
- @start_time = Time.now
59
+ def rescale(now)
60
+ @next_scale_time.set( current_time() + RESCALE_THRESHOLD )
61
+ new_start = current_time()
62
+ old_start = @start_time.get_and_set(new_start)
54
63
 
55
- @values = Hash[ @values.map{ |k,v|
56
- [k * Math.exp(-@alpha * (@start_time - old_start)), v]
57
- }]
64
+ @values = Hash[ @values.map{ |k,v|
65
+ [k * Math.exp(-@alpha * (new_start - old_start)), v]
66
+ }]
58
67
 
59
- end
68
+ end
60
69
 
61
- private
70
+ private
62
71
 
63
- def current_time
64
- Time.now.to_f * 1000
65
- end
72
+ def current_time
73
+ Time.now.to_f * 1000
74
+ end
66
75
 
67
- def weight(n)
68
- Math.exp(@alpha * n)
69
- end
76
+ def weight(n)
77
+ Math.exp(@alpha * n)
78
+ end
70
79
 
80
+ end
71
81
  end
@@ -1,37 +1,52 @@
1
- class UniformSample
1
+ require File.expand_path('../../core', __FILE__)
2
+
3
+ module Drone
4
+ class UniformSample
5
+
6
+ ##
7
+ # Create a new instance.
8
+ #
9
+ # @param [String] id A string which will be used by distributed
10
+ # storage backend to use the same value for all instances with
11
+ # the same id
12
+ # @param [Number] size The size of the requested array
13
+ #
14
+ def initialize(id, size)
15
+ @id = id
16
+ @values = Drone::request_fixed_size_array("#{id}:values", size, 0)
17
+ @count = Drone::request_number("#{id}:count", 0)
18
+ end
2
19
 
3
- def initialize(size)
4
- @values = Array.new(size)
5
- clear()
6
- end
20
+ # def clear
21
+ # @values.size.times do |n|
22
+ # @values[n] = 0
23
+ # end
24
+ #
25
+ # @count.set(0)
26
+ # end
7
27
 
8
- def clear
9
- @values.size.times do |n|
10
- @values[n] = 0
28
+ def size
29
+ c = @count.get
30
+ (c > @values.size) ? @values.size : c
11
31
  end
12
-
13
- @count = 0
14
- end
15
32
 
16
- def size
17
- (@count > @values.size) ? @values.size : @count
18
- end
19
-
20
- def update(val)
21
- @count += 1
22
- if @count <= @values.size
23
- @values[@count - 1] = val
24
- else
25
- r = rand(2**64 - 1) % @count
26
- if r < @values.size
27
- @values[r] = val
33
+ def update(val)
34
+ @count.inc
35
+ count = @count.get
36
+ if count <= @values.size
37
+ @values[count - 1] = val
38
+ else
39
+ r = rand(2**64 - 1) % count
40
+ if r < @values.size
41
+ @values[r] = val
42
+ end
28
43
  end
29
44
  end
30
- end
31
45
 
32
- def values
33
- # only return @count elements
34
- @values[0,@count]
35
- end
46
+ def values
47
+ # only return @count elements
48
+ @values[0,@count.get]
49
+ end
36
50
 
51
+ end
37
52
  end
@@ -1,3 +1,3 @@
1
1
  module Drone
2
- VERSION = "0.0.3"
2
+ VERSION = "1.0.1"
3
3
  end
@@ -1,10 +1,12 @@
1
1
  require File.expand_path('../../common', __FILE__)
2
2
 
3
+ require 'drone/core'
3
4
  require 'drone/metrics/counter'
4
5
  include Drone
5
6
 
6
7
  describe 'Counter Metrics' do
7
8
  before do
9
+ Drone::init_drone()
8
10
  @counter = Metrics::Counter.new('something')
9
11
  end
10
12
 
@@ -11,7 +11,7 @@ EM.describe 'Timer Metrics' do
11
11
 
12
12
  describe "A blank timer" do
13
13
  before do
14
- @timer = Metrics::Timer.new()
14
+ @timer = Metrics::Timer.new('id')
15
15
  end
16
16
 
17
17
  should "have a max of zero" do
@@ -59,7 +59,7 @@ EM.describe 'Timer Metrics' do
59
59
 
60
60
  describe "Timing a series of events" do
61
61
  before do
62
- @timer = Metrics::Timer.new()
62
+ @timer = Metrics::Timer.new('id')
63
63
  @timer.update(10)
64
64
  @timer.update(20)
65
65
  @timer.update(20)
@@ -3,10 +3,13 @@ require File.expand_path('../../common', __FILE__)
3
3
  require 'drone/utils/ewma'
4
4
 
5
5
  describe 'EWMA' do
6
+ before do
7
+ Drone::init_drone
8
+ end
6
9
 
7
10
  describe 'A 1min EWMA with a value of 3' do
8
11
  before do
9
- @ewma = EWMA.one_minute_ewma
12
+ @ewma = Drone::EWMA.one_minute_ewma('id2')
10
13
  @ewma.update(3)
11
14
  @ewma.tick()
12
15
  end
@@ -52,7 +55,7 @@ describe 'EWMA' do
52
55
 
53
56
  describe 'A 5min EWMA with a value of 3' do
54
57
  before do
55
- @ewma = EWMA.five_minutes_ewma
58
+ @ewma = Drone::EWMA.five_minutes_ewma('id1')
56
59
  @ewma.update(3)
57
60
  @ewma.tick()
58
61
  end
@@ -95,7 +98,7 @@ describe 'EWMA' do
95
98
 
96
99
  describe 'A 15min EWMA with a value of 3' do
97
100
  before do
98
- @ewma = EWMA.fifteen_minutes_ewma
101
+ @ewma = Drone::EWMA.fifteen_minutes_ewma('id')
99
102
  @ewma.update(3)
100
103
  @ewma.tick()
101
104
  end
@@ -1,12 +1,15 @@
1
1
  require File.expand_path('../../common', __FILE__)
2
2
 
3
3
  require 'drone/utils/exponentially_decaying_sample'
4
+ include Drone
4
5
 
5
6
  describe 'Exponentially Decaying Sample' do
6
7
  describe "A sample of 100 out of 1000 elements" do
7
8
  before do
9
+ Drone::init_drone(nil, Storage::Memory.new)
10
+
8
11
  @population = (0...100)
9
- @sample = ExponentiallyDecayingSample.new(1000, 0.99)
12
+ @sample = ExponentiallyDecayingSample.new('id1', 1000, 0.99)
10
13
  @population.step(1){|n| @sample.update(n) }
11
14
  end
12
15
 
@@ -27,7 +30,7 @@ describe 'Exponentially Decaying Sample' do
27
30
  describe "A sample of 100 out of 10 elements" do
28
31
  before do
29
32
  @population = (0...10)
30
- @sample = ExponentiallyDecayingSample.new(100, 0.99)
33
+ @sample = ExponentiallyDecayingSample.new('id1', 100, 0.99)
31
34
  @population.step(1){|n| @sample.update(n) }
32
35
  end
33
36
 
@@ -47,7 +50,7 @@ describe 'Exponentially Decaying Sample' do
47
50
  describe "A heavily-biased sample of 100 out of 1000 elements" do
48
51
  before do
49
52
  @population = (0...100)
50
- @sample = ExponentiallyDecayingSample.new(1000, 0.99)
53
+ @sample = ExponentiallyDecayingSample.new('id1', 1000, 0.99)
51
54
  @population.step(1){|n| @sample.update(n) }
52
55
  end
53
56
 
@@ -5,9 +5,13 @@ require 'drone/metrics/histogram'
5
5
  include Drone
6
6
 
7
7
  describe 'Histogram' do
8
+ before do
9
+ Drone::init_drone()
10
+ end
11
+
8
12
  describe "A histogram with zero recorded valeus" do
9
13
  before do
10
- @histogram = Histogram.new(UniformSample.new(100))
14
+ @histogram = Histogram.new("id1", UniformSample.new("id1:sample", 100))
11
15
  end
12
16
 
13
17
  should "have a count of 0" do
@@ -46,7 +50,7 @@ describe 'Histogram' do
46
50
 
47
51
  describe "A histogram of the numbers 1 through 10000" do
48
52
  before do
49
- @histogram = Histogram.new( UniformSample.new(100000) )
53
+ @histogram = Histogram.new("id1", UniformSample.new("id1:sample", 100000) )
50
54
  (1..10000).each{|n| @histogram.update(n) }
51
55
  end
52
56
 
@@ -93,7 +93,7 @@ EM.describe 'Monitoring' do
93
93
 
94
94
  should 'time call with no args' do
95
95
  Drone::Metrics::Timer.any_instance.expects(:update).with{|delay|
96
- delay.should.be.close?(0, 0.001)
96
+ delay.should.be.close?(0, 0.1)
97
97
  true
98
98
  }
99
99
 
@@ -104,7 +104,7 @@ EM.describe 'Monitoring' do
104
104
 
105
105
  should 'time call with args' do
106
106
  Drone::Metrics::Timer.any_instance.expects(:update).with{|delay|
107
- delay.should.be.close?(0, 0.001)
107
+ delay.should.be.close?(0, 0.1)
108
108
  true
109
109
  }
110
110
 
@@ -115,7 +115,7 @@ EM.describe 'Monitoring' do
115
115
 
116
116
  should 'time call with a block' do
117
117
  Drone::Metrics::Timer.any_instance.expects(:update).with{|delay|
118
- delay.should.be.close?(0, 0.001)
118
+ delay.should.be.close?(0, 0.1)
119
119
  true
120
120
  }
121
121
 
@@ -1,12 +1,15 @@
1
1
  require File.expand_path('../../common', __FILE__)
2
2
 
3
3
  require 'drone/utils/uniform_sample'
4
+ include Drone
4
5
 
5
6
  describe 'EWMA' do
6
7
  describe "A sample of 100 out of 1000 elements" do
7
8
  before do
9
+ Drone::init_drone()
10
+
8
11
  @population = (0...1000)
9
- @sample = UniformSample.new(100)
12
+ @sample = UniformSample.new('id1', 100)
10
13
  @population.step(1){|n| @sample.update(n) }
11
14
  end
12
15
 
@@ -24,7 +27,7 @@ describe 'EWMA' do
24
27
  describe "A sample of 100 out of 10 elements" do
25
28
  before do
26
29
  @population = (0...10)
27
- @sample = UniformSample.new(100)
30
+ @sample = UniformSample.new('id1', 100)
28
31
  @population.step(1){|n| @sample.update(n) }
29
32
  end
30
33
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: drone
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.3
5
+ version: 1.0.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Julien Ammous
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-04-22 00:00:00 Z
13
+ date: 2011-05-09 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: eventmachine
@@ -89,6 +89,7 @@ extra_rdoc_files: []
89
89
 
90
90
  files:
91
91
  - .gitignore
92
+ - .rvmrc
92
93
  - .yardopts
93
94
  - Gemfile
94
95
  - LICENSE
@@ -104,9 +105,12 @@ files:
104
105
  - lib/drone/metrics/gauge.rb
105
106
  - lib/drone/metrics/histogram.rb
106
107
  - lib/drone/metrics/meter.rb
108
+ - lib/drone/metrics/metric.rb
107
109
  - lib/drone/metrics/timer.rb
108
110
  - lib/drone/monitoring.rb
109
111
  - lib/drone/schedulers/eventmachine.rb
112
+ - lib/drone/storage/base.rb
113
+ - lib/drone/storage/memory.rb
110
114
  - lib/drone/utils/ewma.rb
111
115
  - lib/drone/utils/exponentially_decaying_sample.rb
112
116
  - lib/drone/utils/uniform_sample.rb