graphite-api 0.0.2.1 → 0.0.3.beta1

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.
@@ -3,6 +3,8 @@ module GraphiteAPI
3
3
 
4
4
  autoload :Version, "#{ROOT}/graphite-api/version"
5
5
  autoload :Client, "#{ROOT}/graphite-api/client"
6
+ autoload :Cache, "#{ROOT}/graphite-api/cache"
7
+ autoload :SafeBuffer, "#{ROOT}/graphite-api/safe_buffer"
6
8
  autoload :Reactor, "#{ROOT}/graphite-api/reactor"
7
9
  autoload :Connector, "#{ROOT}/graphite-api/connector"
8
10
  autoload :Middleware, "#{ROOT}/graphite-api/middleware"
@@ -0,0 +1,5 @@
1
+ module GraphiteAPI
2
+ module Cache
3
+ autoload :Memory, File.expand_path("../cache/memory", __FILE__)
4
+ end
5
+ end
@@ -0,0 +1,33 @@
1
+ module GraphiteAPI
2
+ module Cache
3
+ class Memory
4
+
5
+ def initialize options
6
+ Reactor.every(60) { clean(options[:age]) }
7
+ end
8
+
9
+ def get time, key
10
+ cache[time][key]
11
+ end
12
+
13
+ def set time, key, value
14
+ cache[time][key] = value.to_f
15
+ end
16
+
17
+ def incr *args
18
+ set(value.to_f + get(*args))
19
+ end
20
+
21
+ private
22
+
23
+ def cache
24
+ @cache ||= Hash.new {|h,k| h[k] = Hash.new {|h1,k1| h1[k1] = 0}}
25
+ end
26
+
27
+ def clean age
28
+ cache.delete_if {|t,k| Time.now.to_i - t > age}
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -49,7 +49,7 @@ module GraphiteAPI
49
49
 
50
50
  def initialize opt
51
51
  @options = build_options validate opt.clone
52
- @buffer = GraphiteAPI::Buffer.new options
52
+ @buffer = GraphiteAPI::SafeBuffer.new options
53
53
  @connectors = GraphiteAPI::ConnectorGroup.new options
54
54
 
55
55
  every options.fetch :interval do
@@ -0,0 +1,89 @@
1
+ require 'thread'
2
+ require 'set'
3
+
4
+ module GraphiteAPI
5
+ class SafeBuffer
6
+ include Utils
7
+
8
+ def initialize options
9
+ @options = options
10
+ @queue = Queue.new
11
+ @streamer = Hash.new {|h,k| h[k] = ""}
12
+
13
+ if options[:reanimation_exp]
14
+ @cache = Cache::Memory.new options[:reanimation_exp]
15
+ end
16
+ end
17
+
18
+ private_reader :queue, :options, :streamer, :cache
19
+
20
+ # {:metric => {'a' => 10},:time => today}
21
+ def push hash
22
+ debug [:buffer,:add, hash]
23
+ time = Utils.normalize_time(hash[:time],options[:slice])
24
+ hash[:metric].each { |k,v| queue.push [time,k,v] }
25
+ end
26
+
27
+ alias_method :<<, :push
28
+
29
+ # this method isn't thread safe
30
+ # if you are running with multiple threads
31
+ # use #push instead
32
+ def stream message, client_id = nil
33
+ message.gsub(/\t/,' ').each_char do |char|
34
+ next if invalid_char? char
35
+ streamer[client_id] += char
36
+
37
+ if closed_stream? streamer[client_id]
38
+ if valid_stream_message streamer[client_id]
39
+ push stream_message_to_obj streamer[client_id]
40
+ end
41
+ streamer.delete client_id
42
+ end
43
+ end
44
+ end
45
+
46
+ def pull format = nil
47
+ data = Hash.new { |h,k| h[k] = Hash.new { |h,k| h[k] = 0} }
48
+ while new_records?
49
+ time, key, value = queue.pop
50
+ data[time][key] += value.to_f
51
+ end
52
+ data.map do |time, hash|
53
+ hash.map do |key, value|
54
+ value = cache.incr(time,key,value) if cache
55
+ results = ["#{prefix}#{key}",("%.2f"%value).to_f, time]
56
+ format == :string ? results.join(" ") : results
57
+ end
58
+ end.flatten(1)
59
+ end
60
+
61
+ def new_records?
62
+ !queue.empty?
63
+ end
64
+
65
+ private
66
+
67
+ def stream_message_to_obj message
68
+ parts = message.split
69
+ {:metric => { parts[0] => parts[1] },:time => Time.at(parts[2].to_i) }
70
+ end
71
+
72
+ def invalid_char? char
73
+ ["\r"].include? char
74
+ end
75
+
76
+ def closed_stream? string
77
+ string[-1,1] == "\n"
78
+ end
79
+
80
+ def valid_stream_message message
81
+ message =~ /^[\w|\.]+ \d+(?:\.|\d)* \d+$/
82
+ end
83
+
84
+ def prefix
85
+ @prefix ||= options[:prefix].empty? ? '' : Array(options[:prefix]).join('.') << '.'
86
+ end
87
+
88
+ end
89
+ end
@@ -1,5 +1,5 @@
1
1
  module GraphiteAPI
2
2
  class Version
3
- VERSION = "0.0.2.1"
3
+ VERSION = "0.0.3.beta1"
4
4
  end
5
- end
5
+ end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphite-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2.1
5
- prerelease:
4
+ version: 0.0.3.beta1
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Eran Barak Levi
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-07 00:00:00.000000000 Z
12
+ date: 2013-03-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -39,6 +39,8 @@ files:
39
39
  - bin/graphite-middleware
40
40
  - lib/core-extensions/numeric.rb
41
41
  - lib/graphite-api/buffer.rb
42
+ - lib/graphite-api/cache/memory.rb
43
+ - lib/graphite-api/cache.rb
42
44
  - lib/graphite-api/cli.rb
43
45
  - lib/graphite-api/client.rb
44
46
  - lib/graphite-api/connector.rb
@@ -47,6 +49,7 @@ files:
47
49
  - lib/graphite-api/middleware.rb
48
50
  - lib/graphite-api/reactor.rb
49
51
  - lib/graphite-api/runner.rb
52
+ - lib/graphite-api/safe_buffer.rb
50
53
  - lib/graphite-api/utils.rb
51
54
  - lib/graphite-api/version.rb
52
55
  - lib/graphite-api.rb
@@ -67,12 +70,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
67
70
  required_rubygems_version: !ruby/object:Gem::Requirement
68
71
  none: false
69
72
  requirements:
70
- - - ! '>='
73
+ - - ! '>'
71
74
  - !ruby/object:Gem::Version
72
- version: '0'
75
+ version: 1.3.1
73
76
  requirements: []
74
77
  rubyforge_project: graphite-api
75
- rubygems_version: 1.8.24
78
+ rubygems_version: 1.8.25
76
79
  signing_key:
77
80
  specification_version: 3
78
81
  summary: Graphite Ruby Client