drone 0.0.3 → 1.0.1

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.
@@ -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