quark 0.1.4 → 0.2.0

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/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