quark 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/quark CHANGED
@@ -30,17 +30,26 @@ module Quark
30
30
 
31
31
  # -----------------------------------------------------------------------------
32
32
  opts.on('-S', '--socket FILE', 'Location of the Unix socket to accept commands from') do |file|
33
- Quark::Config.set("quark.socket", file)
33
+ Quark::Config.set("quark.socket.enabled", true)
34
+ Quark::Config.set("quark.socket.path", file)
34
35
  end
35
36
 
36
37
  # -----------------------------------------------------------------------------
37
38
  opts.on('-a', '--address ADDR', 'The IP address for all servers to listen on') do |addr|
38
- Quark::Config.set("quark.address", addr)
39
+ Quark::Config.get("quark",{}).each do |k,v|
40
+ if v.is_a?(Hash) and not v.get(:address).nil?
41
+ Quark::Config.set("quark.#{k}.address", addr)
42
+ end
43
+ end
39
44
  end
40
45
 
41
46
  # -----------------------------------------------------------------------------
42
- opts.on('-p', '--port PORT', 'The TCP/UDP port to listen on') do |port|
43
- Quark::Config.set("quark.port", port.to_i)
47
+ opts.on('-p', '--port PORT', 'The port for all servers to listen on') do |port|
48
+ Quark::Config.get("quark",{}).each do |k,v|
49
+ if v.is_a?(Hash) and not v.get(:port).nil?
50
+ Quark::Config.set("quark.#{k}.port", port.to_i)
51
+ end
52
+ end
44
53
  end
45
54
 
46
55
  # -----------------------------------------------------------------------------
@@ -87,11 +96,13 @@ module Quark
87
96
 
88
97
  # -----------------------------------------------------------------------------
89
98
  opts.on('', '--http-address ADDR', 'The IP address for the HTTP server to listen on') do |addr|
99
+ Quark::Config.set("quark.http.enabled", true)
90
100
  Quark::Config.set("quark.http.address", addr)
91
101
  end
92
102
 
93
103
  # -----------------------------------------------------------------------------
94
104
  opts.on('', '--http-port PORT', 'The HTTP port to listen on') do |port|
105
+ Quark::Config.set("quark.http.enabled", true)
95
106
  Quark::Config.set("quark.http.port", port.to_i)
96
107
  end
97
108
 
@@ -100,6 +111,23 @@ module Quark
100
111
  Quark::Config.set("quark.http.cors", mode)
101
112
  end
102
113
 
114
+ # -----------------------------------------------------------------------------
115
+ opts.on('-W', '--[no-]ws', 'Enable/disable Websocket server') do |mode|
116
+ Quark::Config.set("quark.websocket.enabled", mode)
117
+ end
118
+
119
+ # -----------------------------------------------------------------------------
120
+ opts.on('', '--ws-address ADDR', 'The IP address for the Websocket server to listen on') do |addr|
121
+ Quark::Config.set("quark.websocket.enabled", true)
122
+ Quark::Config.set("quark.websocket.address", addr)
123
+ end
124
+
125
+ # -----------------------------------------------------------------------------
126
+ opts.on('', '--ws-port PORT', 'The Websocket port to listen on') do |port|
127
+ Quark::Config.set("quark.websocket.enabled", true)
128
+ Quark::Config.set("quark.websocket.port", port.to_i)
129
+ end
130
+
103
131
  # -----------------------------------------------------------------------------
104
132
  opts.on('-D', '--debug', 'Enable debug mode') do
105
133
  Quark::Config.set("debug", true)
data/lib/quark.rb CHANGED
@@ -4,219 +4,6 @@ require 'redis'
4
4
  require 'hiredis'
5
5
  require 'em-synchrony'
6
6
  require 'multi_json'
7
+ require 'quark/errors'
7
8
  require 'quark/config'
8
-
9
- module Quark
10
- class Error < Exception; end
11
- class ArgumentError < Error; end
12
- class InvalidCommand < Error; end
13
-
14
- module SocketServer
15
- Dir[File.join(File.dirname(__FILE__), "quark", "commands", "*.rb")].each do |rb|
16
- require "#{rb.gsub(/\.rb$/,'')}"
17
- end
18
-
19
- def post_init()
20
- self.setup()
21
- end
22
-
23
- def receive_data(data)
24
- puts "DEBUG: Received '#{data}'" if Quark::Config.get("debug")
25
- send_json(Quark::SocketServer.process_command(data))
26
- end
27
-
28
- def send_json(data)
29
- send_data(MultiJson.dump(data)+"\n")
30
- end
31
-
32
- def self.setup(redis, prefix='quark')
33
- @redis = redis
34
- @_prefix = prefix
35
- end
36
-
37
- def self.process_command(data)
38
- # if the data perfectly resembles a graphite-formatted metric (without a command prefix)
39
- # then assume the command is "observe"
40
- if Quark::Config.get("quark.graphite_compat") and data =~ /^[\w\.\-]+ -?[\d\.]+ \d{10,13}$/
41
- command = "OBSERVE"
42
- arguments = data.chomp
43
- else
44
- command, arguments = data.chomp.split(' ',2)
45
- end
46
-
47
- begin
48
- if methods.include?(:"process_command_#{command.downcase}")
49
- rv = send(:"process_command_#{command.downcase}", arguments)
50
- if rv.nil?
51
- return {
52
- :success => true
53
- }
54
- else
55
- return {
56
- :success => true,
57
- :command => data.chomp,
58
- :results => rv
59
- }
60
- end
61
- else
62
- raise Quark::InvalidCommand.new("Unknown command '#{command.upcase}'")
63
- end
64
-
65
- rescue Quark::Error => e
66
- return {
67
- :success => false,
68
- :command => data.chomp,
69
- :error => {
70
- :class => e.class.name,
71
- :message => e.message
72
- }
73
- }
74
-
75
- rescue Exception => e
76
- return {
77
- :success => false,
78
- :command => data.chomp,
79
- :error => {
80
- :class => e.class.name,
81
- :message => e.message,
82
- :backtrace => e.backtrace
83
- }
84
- }
85
- end
86
- end
87
-
88
- def unbind()
89
- end
90
- end
91
-
92
- class Server
93
- def self.setup()
94
- Quark::Config.set("quark.address", "127.0.0.1")
95
- Quark::Config.set("quark.port", 12161)
96
- Quark::Config.set("quark.blocksize", 3600000)
97
- Quark::Config.set("quark.tcp.enabled", true)
98
- Quark::Config.set("quark.udp.enabled", false)
99
- Quark::Config.set("quark.http.enabled", false)
100
- Quark::Config.set("quark.http.port", 12180)
101
- Quark::Config.set("quark.http.cors", false)
102
- Quark::Config.set("quark.graphite_compat", true)
103
- Quark::Config.set("debug", false)
104
- nil
105
- end
106
-
107
- def self.connect()
108
- @redis = Redis.new({
109
- :host => Quark::Config.get("redis.host", "127.0.0.1"),
110
- :port => Quark::Config.get("redis.port", 6379).to_i,
111
- :db => Quark::Config.get("redis.db", 0).to_i
112
- })
113
-
114
- @_prefix = Quark::Config.get("redis.prefix", "quark")
115
-
116
- Quark::SocketServer.setup(@redis, @_prefix)
117
- end
118
-
119
- def self.run()
120
- connect() unless defined?(@redis)
121
-
122
- @address = Quark::Config.get("quark.address")
123
- @port = Quark::Config.get("quark.port")
124
- @filename = Quark::Config.get("quark.socket")
125
-
126
- EM.run do
127
- Signal.trap("INT") { Quark::Server.quit() }
128
- Signal.trap("TERM") { Quark::Server.quit() }
129
-
130
- if Quark::Config.get("debug")
131
- puts "Debug mode is ON"
132
- end
133
-
134
- # socket
135
- if not @filename.nil? and File.writable?(File.dirname(@filename))
136
- puts "Starting socket server at #{@filename}..."
137
- EM::start_server(@filename, Quark::SocketServer)
138
- end
139
-
140
- # UDP server
141
- if Quark::Config.get("quark.udp.enabled") === true
142
- @udp_address = Quark::Config.get("quark.udp.address", @address)
143
- @udp_port = Quark::Config.get("quark.udp.port", @port)
144
-
145
- puts "Starting UDP server on #{@udp_address}:#{@udp_port}..."
146
- EM::open_datagram_socket(@udp_address, @udp_port, Quark::SocketServer)
147
- end
148
-
149
- # TCP server
150
- if Quark::Config.get("quark.tcp.enabled") === true
151
- @tcp_address = Quark::Config.get("quark.tcp.address", @address)
152
- @tcp_port = Quark::Config.get("quark.tcp.port", @port)
153
-
154
- puts "Starting TCP server on #{@tcp_address}:#{@tcp_port}..."
155
- EM::start_server(@tcp_address, @tcp_port, Quark::SocketServer)
156
- end
157
-
158
- # HTTP server
159
- if Quark::Config.get("quark.http.enabled") === true
160
- @http_address = Quark::Config.get("quark.http.address", @address)
161
- @http_port = Quark::Config.get("quark.http.port", 12180)
162
-
163
- puts "Starting HTTP server on #{@http_address}:#{@http_port}..."
164
- require 'quark/servers/http'
165
-
166
- Quark::Server::HttpServer.new({
167
- :address => @http_address,
168
- :port => @http_port
169
- }).run()
170
- end
171
-
172
- if Quark::Config.get("quark.graphite_compat")
173
- puts "Graphite compatibility mode enabled: all sockets will accept Graphite-formatted metrics as observations"
174
- end
175
- end
176
- end
177
-
178
- def self.daemonize()
179
- return @_service if defined?(@_service)
180
-
181
- @_service = proc do
182
- self.run()
183
- end
184
-
185
- EM.defer(@_service)
186
- return @_service
187
- end
188
-
189
-
190
- # removes metrics that match keys and (optionally) are older than 'to'
191
- # if 'to' is negative, it is assumed to be n-seconds ago
192
- #
193
- def self.purge(keys, to=nil)
194
- keys = [@_prefix, keys, '*'].join(':') if not keys.start_with?(@_prefix)
195
- now = (Time.now.to_f * 1000).to_i
196
- rv = []
197
-
198
- @redis.keys(keys).each do |key|
199
- x, name, block = key.split(':', 3)
200
- block = block.to_i
201
-
202
- if ((to = Integer(to)) rescue false)
203
- if to < 0
204
- to = now - (-1 * to * 1000)
205
- end
206
- end
207
-
208
- if to.nil? or block < (to/Quark::Config.get("quark.blocksize")).to_i
209
- @redis.del(key)
210
- rv << key
211
- end
212
- end
213
-
214
- rv
215
- end
216
-
217
- def self.quit()
218
- puts "Stopping Quark..."
219
- EM.stop()
220
- end
221
- end
222
- end
9
+ require 'quark/server'
@@ -0,0 +1,13 @@
1
+ module Quark
2
+ class Server
3
+ class BaseServer
4
+ def self.start(options=nil)
5
+ return self.new(options).run()
6
+ end
7
+
8
+ def self.to_s()
9
+ self.name.split('::').last.gsub('Server','').upcase
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,83 @@
1
+ module Quark
2
+ module CommandProcessor
3
+ Dir[File.join(File.dirname(__FILE__), "commands", "*.rb")].each do |cmd|
4
+ cmd = File.basename(cmd, '.rb')
5
+ require "quark/commands/#{cmd}"
6
+ end
7
+
8
+ def post_init()
9
+ end
10
+
11
+ def receive_data(data)
12
+ puts "DEBUG: Received '#{data.chomp.strip}'" if Quark::Config.get("debug")
13
+ data = Quark::CommandProcessor.process_command(data)
14
+ send_json(data)
15
+ data
16
+ end
17
+
18
+ def send_json(data)
19
+ data = MultiJson.dump(data)+"\n"
20
+ puts "DEBUG: Replying with #{data.chomp}" if Quark::Config.get("debug")
21
+ send_data(data)
22
+ end
23
+
24
+ def self.setup(redis, prefix='quark')
25
+ @redis = redis
26
+ @_prefix = prefix
27
+ end
28
+
29
+ def self.process_command(data)
30
+ # if the data perfectly resembles a graphite-formatted metric (without a command prefix)
31
+ # then assume the command is "observe"
32
+ if Quark::Config.get("quark.graphite_compat") and data =~ /^[\w\.\-]+ -?[\d\.]+ \d{10,13}$/
33
+ command = "OBSERVE"
34
+ arguments = data.chomp
35
+ else
36
+ command, arguments = data.chomp.split(' ',2)
37
+ end
38
+
39
+ begin
40
+ if methods.include?(:"process_command_#{command.downcase}")
41
+ rv = send(:"process_command_#{command.downcase}", arguments)
42
+ if rv.nil?
43
+ return {
44
+ :success => true
45
+ }
46
+ else
47
+ return {
48
+ :success => true,
49
+ :command => data.chomp,
50
+ :results => rv
51
+ }
52
+ end
53
+ else
54
+ raise Quark::InvalidCommand.new("Unknown command '#{command.upcase}'")
55
+ end
56
+
57
+ rescue Quark::Error => e
58
+ return {
59
+ :success => false,
60
+ :command => data.chomp,
61
+ :error => {
62
+ :class => e.class.name,
63
+ :message => e.message
64
+ }
65
+ }
66
+
67
+ rescue Exception => e
68
+ return {
69
+ :success => false,
70
+ :command => data.chomp,
71
+ :error => {
72
+ :class => e.class.name,
73
+ :message => e.message,
74
+ :backtrace => e.backtrace
75
+ }
76
+ }
77
+ end
78
+ end
79
+
80
+ def unbind()
81
+ end
82
+ end
83
+ end
@@ -1,5 +1,5 @@
1
1
  module Quark
2
- module SocketServer
2
+ module CommandProcessor
3
3
  def self.process_command_fetch(data)
4
4
  raise Quark::ArgumentError.new("FETCH command requires at least 1 argument") if data.nil? or data.empty?
5
5
 
@@ -1,5 +1,5 @@
1
1
  module Quark
2
- module SocketServer
2
+ module CommandProcessor
3
3
  def self.process_command_observe(data)
4
4
  id, value, timestamp = data.chomp.split(' ')
5
5
  timestamp = timestamp.to_i
@@ -1,6 +1,6 @@
1
1
  module Quark
2
- module SocketServer
3
- def process_command_peek(data)
2
+ module CommandProcessor
3
+ def self.process_command_peek(data)
4
4
  rv = {}
5
5
  keys = @redis.keys("#{@_prefix}:#{data}:*")
6
6
  peek_keys = []
@@ -17,9 +17,11 @@ module Quark
17
17
 
18
18
  # now that we have the most recent bucket, pull the most recent value from that bucket
19
19
  peek_keys.each do |peek|
20
- rv[peek.split(':')[1]] = @redis.hgetall(peek).sort{|a,b|
20
+ data = @redis.hgetall(peek).sort{|a,b|
21
21
  a[0] <=> b[0]
22
22
  }.last
23
+
24
+ rv[peek.split(':')[1]] = [data[0].to_i, data[1].to_f]
23
25
  end
24
26
 
25
27
  return rv
@@ -1,5 +1,5 @@
1
1
  module Quark
2
- module SocketServer
2
+ module CommandProcessor
3
3
  require 'socket'
4
4
 
5
5
  def self.process_command_ping(data)
@@ -0,0 +1,5 @@
1
+ module Quark
2
+ class Error < Exception; end
3
+ class ArgumentError < Error; end
4
+ class InvalidCommand < Error; end
5
+ end
@@ -0,0 +1,111 @@
1
+ require 'quark/base_server'
2
+ require 'quark/command_processor'
3
+
4
+
5
+ module Quark
6
+ class Server
7
+ def self.setup()
8
+ Quark::Config.set("debug", false)
9
+ Quark::Config.set("quark.blocksize", 3600000)
10
+ Quark::Config.set("quark.graphite_compat", true)
11
+ Quark::Config.set("quark.http.address", "127.0.0.1")
12
+ Quark::Config.set("quark.http.cors", false)
13
+ Quark::Config.set("quark.http.enabled", false)
14
+ Quark::Config.set("quark.http.port", 12180)
15
+ Quark::Config.set("quark.socket.path", "/var/run/quark.sock")
16
+ Quark::Config.set("quark.tcp.address", "127.0.0.1")
17
+ Quark::Config.set("quark.tcp.enabled", true)
18
+ Quark::Config.set("quark.tcp.port", 12161)
19
+ Quark::Config.set("quark.udp.address", "127.0.0.1")
20
+ Quark::Config.set("quark.udp.enabled", false)
21
+ Quark::Config.set("quark.udp.port", 12161)
22
+ Quark::Config.set("quark.websocket.address", "127.0.0.1")
23
+ Quark::Config.set("quark.websocket.enabled", false)
24
+ Quark::Config.set("quark.websocket.port", 12181)
25
+ nil
26
+ end
27
+
28
+ def self.connect()
29
+ @redis = Redis.new({
30
+ :host => Quark::Config.get("redis.host", "127.0.0.1"),
31
+ :port => Quark::Config.get("redis.port", 6379).to_i,
32
+ :db => Quark::Config.get("redis.db", 0).to_i
33
+ })
34
+
35
+ @_prefix = Quark::Config.get("redis.prefix", "quark")
36
+
37
+ Quark::CommandProcessor.setup(@redis, @_prefix)
38
+ end
39
+
40
+ def self.run()
41
+ connect() unless defined?(@redis)
42
+
43
+ EM.run do
44
+ Signal.trap("INT") { Quark::Server.quit() }
45
+ Signal.trap("TERM") { Quark::Server.quit() }
46
+
47
+ if Quark::Config.get("debug")
48
+ puts "Debug mode is ON"
49
+ end
50
+
51
+ Dir[File.join(File.dirname(__FILE__), 'servers', '*.rb')].each do |server|
52
+ server = File.basename(server,'.rb')
53
+
54
+ # dynamically load and run all enabled servers
55
+ if Quark::Config.get("quark.#{server.downcase}.enabled") === true
56
+ require "quark/servers/#{server.downcase}"
57
+ Quark::Server.const_get("#{server.capitalize}Server").start()
58
+ end
59
+ end
60
+
61
+ if Quark::Config.get("quark.graphite_compat")
62
+ puts "Graphite compatibility mode enabled: all sockets will accept Graphite-formatted metrics as observations"
63
+ end
64
+ end
65
+ end
66
+
67
+ def self.daemonize()
68
+ return @_service if defined?(@_service)
69
+
70
+ @_service = proc do
71
+ self.run()
72
+ end
73
+
74
+ EM.defer(@_service)
75
+ return @_service
76
+ end
77
+
78
+
79
+ # removes metrics that match keys and (optionally) are older than 'to'
80
+ # if 'to' is negative, it is assumed to be n-seconds ago
81
+ #
82
+ def self.purge(keys, to=nil)
83
+ keys = [@_prefix, keys, '*'].join(':') if not keys.start_with?(@_prefix)
84
+ now = (Time.now.to_f * 1000).to_i
85
+ rv = []
86
+
87
+ @redis.keys(keys).each do |key|
88
+ x, name, block = key.split(':', 3)
89
+ block = block.to_i
90
+
91
+ if ((to = Integer(to)) rescue false)
92
+ if to < 0
93
+ to = now - (-1 * to * 1000)
94
+ end
95
+ end
96
+
97
+ if to.nil? or block < (to/Quark::Config.get("quark.blocksize")).to_i
98
+ @redis.del(key)
99
+ rv << key
100
+ end
101
+ end
102
+
103
+ rv
104
+ end
105
+
106
+ def self.quit()
107
+ puts "Stopping Quark..."
108
+ EM.stop()
109
+ end
110
+ end
111
+ end
@@ -1,6 +1,6 @@
1
1
  module Quark
2
2
  class Server
3
- class HttpServer
3
+ class HttpServer < BaseServer
4
4
  require 'sinatra'
5
5
  require 'sinatra/cross_origin'
6
6
  require 'thin'
@@ -35,15 +35,15 @@ module Quark
35
35
  end
36
36
 
37
37
  get '/call/:command/?*' do
38
- MultiJson.dump(Quark::SocketServer.process_command("#{params[:command].upcase} #{params[:splat].first.gsub('/',' ')}".strip))
38
+ MultiJson.dump(Quark::CommandProcessor.process_command("#{params[:command].upcase} #{params[:splat].first.gsub('/',' ')}".strip))
39
39
  end
40
40
 
41
41
  get '/observe/:metric/:value/?' do
42
- MultiJson.dump(Quark::SocketServer.process_command_observe("#{params[:metric]} #{params[:value]} #{(Time.now.to_f * 1000).to_i}"))
42
+ MultiJson.dump(Quark::CommandProcessor.process_command_observe("#{params[:metric]} #{params[:value]} #{(Time.now.to_f * 1000).to_i}"))
43
43
  end
44
44
 
45
45
  get '/observe/:metric/:value/:timestamp/?' do
46
- MultiJson.dump(Quark::SocketServer.process_command_observe("#{params[:metric]} #{params[:value]} #{params[:timestamp]}"))
46
+ MultiJson.dump(Quark::CommandProcessor.process_command_observe("#{params[:metric]} #{params[:value]} #{params[:timestamp]}"))
47
47
  end
48
48
 
49
49
  def _quark_command(command, payload)
@@ -69,6 +69,8 @@ module Quark
69
69
  end
70
70
 
71
71
  def run()
72
+ puts "Starting #{self.class.to_s} server on #{@_options.get(:address)}:#{@_options.get(:port)}..."
73
+
72
74
  Thin::Logging.silent = true unless Quark::Config.get("debug")
73
75
  Thin::Server.start(@_options.get(:address,'127.0.0.1'), @_options.get(:port, 12180).to_i, Base.new(), {
74
76
  :signals => false,
@@ -0,0 +1,21 @@
1
+
2
+ module Quark
3
+ class Server
4
+ class SocketServer < BaseServer
5
+ require 'eventmachine'
6
+
7
+ def initialize(options=nil)
8
+ @_options = options || Quark::Config.get("quark.socket",{})
9
+ end
10
+
11
+ def run()
12
+ puts "Starting #{self.class.to_s} server at #{@_options.get(:path)}..."
13
+ EM::start_server(@_options.get(:path, "/var/run/quark.sock"), Quark::CommandProcessor)
14
+ end
15
+
16
+ def self.to_s()
17
+ "socket"
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,17 @@
1
+
2
+ module Quark
3
+ class Server
4
+ class TcpServer < BaseServer
5
+ require 'eventmachine'
6
+
7
+ def initialize(options=nil)
8
+ @_options = options || Quark::Config.get("quark.tcp",{})
9
+ end
10
+
11
+ def run()
12
+ puts "Starting #{self.class.to_s} server on #{@_options.get(:address)}:#{@_options.get(:port)}..."
13
+ EM::start_server(@_options.get(:address, '127.0.0.1'), @_options.get(:port, 12161).to_i, Quark::CommandProcessor)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+
2
+ module Quark
3
+ class Server
4
+ class UdpServer < BaseServer
5
+ require 'eventmachine'
6
+
7
+ def initialize(options=nil)
8
+ @_options = options || Quark::Config.get("quark.udp",{})
9
+ end
10
+
11
+ def run()
12
+ puts "Starting #{self.class.to_s} server on #{@_options.get(:address)}:#{@_options.get(:port)}..."
13
+ EM::open_datagram_socket(@_options.get(:address, '127.0.0.1'), @_options.get(:port, 12161).to_i, Quark::CommandProcessor)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,52 @@
1
+
2
+ module Quark
3
+ class Server
4
+ class WebsocketServer < BaseServer
5
+ require 'eventmachine'
6
+ require 'em-websocket'
7
+
8
+ class WebsocketProcessor
9
+ include Quark::CommandProcessor
10
+
11
+ def initialize(ws)
12
+ @ws = ws
13
+ end
14
+
15
+ def send_data(data)
16
+ @ws.send(data)
17
+ end
18
+ end
19
+
20
+ def initialize(options=nil)
21
+ @_options = options || Quark::Config.get("quark.websocket",{})
22
+ end
23
+
24
+ def run()
25
+ puts "Starting #{self.class.to_s} server on #{@_options.get(:address)}:#{@_options.get(:port)}..."
26
+
27
+ EM::WebSocket.run({
28
+ :host => @_options.get(:address, "127.0.0.1"),
29
+ :port => @_options.get(:port, 12181).to_i
30
+ }) do |ws|
31
+ processor = WebsocketProcessor.new(ws)
32
+
33
+ ws.onopen do
34
+ processor.post_init()
35
+ end
36
+
37
+ ws.onclose do
38
+ processor.unbind()
39
+ end
40
+
41
+ ws.onmessage do |data|
42
+ processor.receive_data(data)
43
+ end
44
+ end
45
+ end
46
+
47
+ def self.to_s()
48
+ "Websocket"
49
+ end
50
+ end
51
+ end
52
+ end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quark
3
3
  version: !ruby/object:Gem::Version
4
+ version: 0.2.0
4
5
  prerelease:
5
- version: 0.1.4
6
6
  platform: ruby
7
7
  authors:
8
8
  - Gary Hetzel
@@ -12,149 +12,115 @@ cert_chain: []
12
12
  date: 2014-05-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- type: :runtime
16
- version_requirements: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - '='
19
- - !ruby/object:Gem::Version
20
- version: 1.7.9
21
- none: false
22
- prerelease: false
23
15
  name: multi_json
24
- requirement: !ruby/object:Gem::Requirement
16
+ requirement: &20685860 !ruby/object:Gem::Requirement
17
+ none: false
25
18
  requirements:
26
- - - '='
19
+ - - =
27
20
  - !ruby/object:Gem::Version
28
21
  version: 1.7.9
29
- none: false
30
- - !ruby/object:Gem::Dependency
31
22
  type: :runtime
32
- version_requirements: !ruby/object:Gem::Requirement
33
- requirements:
34
- - - ~>
35
- - !ruby/object:Gem::Version
36
- version: 1.0.0
37
- none: false
38
23
  prerelease: false
24
+ version_requirements: *20685860
25
+ - !ruby/object:Gem::Dependency
39
26
  name: eventmachine
40
- requirement: !ruby/object:Gem::Requirement
27
+ requirement: &20685400 !ruby/object:Gem::Requirement
28
+ none: false
41
29
  requirements:
42
30
  - - ~>
43
31
  - !ruby/object:Gem::Version
44
32
  version: 1.0.0
45
- none: false
46
- - !ruby/object:Gem::Dependency
47
33
  type: :runtime
48
- version_requirements: !ruby/object:Gem::Requirement
49
- requirements:
50
- - - ~>
51
- - !ruby/object:Gem::Version
52
- version: 3.0.0
53
- none: false
54
34
  prerelease: false
35
+ version_requirements: *20685400
36
+ - !ruby/object:Gem::Dependency
55
37
  name: redis
56
- requirement: !ruby/object:Gem::Requirement
38
+ requirement: &20701280 !ruby/object:Gem::Requirement
39
+ none: false
57
40
  requirements:
58
41
  - - ~>
59
42
  - !ruby/object:Gem::Version
60
43
  version: 3.0.0
61
- none: false
62
- - !ruby/object:Gem::Dependency
63
44
  type: :runtime
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ~>
67
- - !ruby/object:Gem::Version
68
- version: 0.5.2
69
- none: false
70
45
  prerelease: false
46
+ version_requirements: *20701280
47
+ - !ruby/object:Gem::Dependency
71
48
  name: hiredis
72
- requirement: !ruby/object:Gem::Requirement
49
+ requirement: &20700820 !ruby/object:Gem::Requirement
50
+ none: false
73
51
  requirements:
74
52
  - - ~>
75
53
  - !ruby/object:Gem::Version
76
54
  version: 0.5.2
77
- none: false
78
- - !ruby/object:Gem::Dependency
79
55
  type: :runtime
80
- version_requirements: !ruby/object:Gem::Requirement
81
- requirements:
82
- - - ~>
83
- - !ruby/object:Gem::Version
84
- version: 1.0.3
85
- none: false
86
56
  prerelease: false
57
+ version_requirements: *20700820
58
+ - !ruby/object:Gem::Dependency
87
59
  name: em-synchrony
88
- requirement: !ruby/object:Gem::Requirement
60
+ requirement: &20700220 !ruby/object:Gem::Requirement
61
+ none: false
89
62
  requirements:
90
63
  - - ~>
91
64
  - !ruby/object:Gem::Version
92
65
  version: 1.0.3
93
- none: false
94
- - !ruby/object:Gem::Dependency
95
66
  type: :runtime
96
- version_requirements: !ruby/object:Gem::Requirement
67
+ prerelease: false
68
+ version_requirements: *20700220
69
+ - !ruby/object:Gem::Dependency
70
+ name: em-websocket
71
+ requirement: &20699700 !ruby/object:Gem::Requirement
72
+ none: false
97
73
  requirements:
98
- - - ! '>='
74
+ - - ~>
99
75
  - !ruby/object:Gem::Version
100
- version: 0.0.35
101
- none: false
76
+ version: 0.5.1
77
+ type: :runtime
102
78
  prerelease: false
79
+ version_requirements: *20699700
80
+ - !ruby/object:Gem::Dependency
103
81
  name: hashlib
104
- requirement: !ruby/object:Gem::Requirement
82
+ requirement: &20699020 !ruby/object:Gem::Requirement
83
+ none: false
105
84
  requirements:
106
85
  - - ! '>='
107
86
  - !ruby/object:Gem::Version
108
87
  version: 0.0.35
109
- none: false
110
- - !ruby/object:Gem::Dependency
111
88
  type: :runtime
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - ! '>='
115
- - !ruby/object:Gem::Version
116
- version: '0'
117
- none: false
118
89
  prerelease: false
90
+ version_requirements: *20699020
91
+ - !ruby/object:Gem::Dependency
119
92
  name: sinatra
120
- requirement: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ! '>='
123
- - !ruby/object:Gem::Version
124
- version: '0'
93
+ requirement: &20698360 !ruby/object:Gem::Requirement
125
94
  none: false
126
- - !ruby/object:Gem::Dependency
127
- type: :runtime
128
- version_requirements: !ruby/object:Gem::Requirement
129
95
  requirements:
130
96
  - - ! '>='
131
97
  - !ruby/object:Gem::Version
132
98
  version: '0'
133
- none: false
99
+ type: :runtime
134
100
  prerelease: false
101
+ version_requirements: *20698360
102
+ - !ruby/object:Gem::Dependency
135
103
  name: sinatra-cross_origin
136
- requirement: !ruby/object:Gem::Requirement
137
- requirements:
138
- - - ! '>='
139
- - !ruby/object:Gem::Version
140
- version: '0'
104
+ requirement: &20697860 !ruby/object:Gem::Requirement
141
105
  none: false
142
- - !ruby/object:Gem::Dependency
143
- type: :runtime
144
- version_requirements: !ruby/object:Gem::Requirement
145
106
  requirements:
146
107
  - - ! '>='
147
108
  - !ruby/object:Gem::Version
148
109
  version: '0'
149
- none: false
110
+ type: :runtime
150
111
  prerelease: false
112
+ version_requirements: *20697860
113
+ - !ruby/object:Gem::Dependency
151
114
  name: thin
152
- requirement: !ruby/object:Gem::Requirement
115
+ requirement: &20697320 !ruby/object:Gem::Requirement
116
+ none: false
153
117
  requirements:
154
118
  - - ! '>='
155
119
  - !ruby/object:Gem::Version
156
120
  version: '0'
157
- none: false
121
+ type: :runtime
122
+ prerelease: false
123
+ version_requirements: *20697320
158
124
  description: A small service for logging and retrieving timeseries metrics into a
159
125
  Redis server
160
126
  email: garyhetzel@gmail.com
@@ -164,12 +130,20 @@ extensions: []
164
130
  extra_rdoc_files: []
165
131
  files:
166
132
  - lib/quark.rb
133
+ - lib/quark/servers/socket.rb
134
+ - lib/quark/servers/websocket.rb
135
+ - lib/quark/servers/udp.rb
167
136
  - lib/quark/servers/http.rb
137
+ - lib/quark/servers/tcp.rb
168
138
  - lib/quark/config.rb
169
- - lib/quark/commands/fetch.rb
170
- - lib/quark/commands/ping.rb
139
+ - lib/quark/command_processor.rb
171
140
  - lib/quark/commands/peek.rb
141
+ - lib/quark/commands/fetch.rb
172
142
  - lib/quark/commands/observe.rb
143
+ - lib/quark/commands/ping.rb
144
+ - lib/quark/errors.rb
145
+ - lib/quark/server.rb
146
+ - lib/quark/base_server.rb
173
147
  - bin/quark
174
148
  homepage: https://github.com/ghetzel/quark
175
149
  licenses: []
@@ -178,20 +152,20 @@ rdoc_options: []
178
152
  require_paths:
179
153
  - lib
180
154
  required_ruby_version: !ruby/object:Gem::Requirement
155
+ none: false
181
156
  requirements:
182
157
  - - ! '>='
183
158
  - !ruby/object:Gem::Version
184
159
  version: '0'
185
- none: false
186
160
  required_rubygems_version: !ruby/object:Gem::Requirement
161
+ none: false
187
162
  requirements:
188
163
  - - ! '>='
189
164
  - !ruby/object:Gem::Version
190
165
  version: '0'
191
- none: false
192
166
  requirements: []
193
167
  rubyforge_project:
194
- rubygems_version: 1.8.28
168
+ rubygems_version: 1.8.11
195
169
  signing_key:
196
170
  specification_version: 3
197
171
  summary: A miniscule timeseries metrics logging service