pulse-meter 0.4.2 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
data/lib/cmd.rb CHANGED
@@ -157,5 +157,15 @@ module Cmd
157
157
  end
158
158
  end
159
159
 
160
+ desc "udp_proxy HOST PORT", "Start UDP proxy for sensor data"
161
+ common_options
162
+ def udp_proxy(host, port)
163
+ with_redis do
164
+ puts 'Starting UDP server'
165
+ server = PulseMeter::UDPServer.new(host, port)
166
+ server.start
167
+ end
168
+ end
169
+
160
170
  end
161
171
  end
data/lib/pulse-meter.rb CHANGED
@@ -10,6 +10,9 @@ require "pulse-meter/sensor/configuration"
10
10
 
11
11
  require "pulse-meter/command_aggregator/async"
12
12
  require "pulse-meter/command_aggregator/sync"
13
+ require "pulse-meter/command_aggregator/udp"
14
+
15
+ require "pulse-meter/udp_server"
13
16
 
14
17
  module PulseMeter
15
18
  @@redis = nil
@@ -37,7 +40,7 @@ module PulseMeter
37
40
  @@command_aggregator = case command_aggregator
38
41
  when :sync; PulseMeter::CommandAggregator::Sync.instance
39
42
  when :async; PulseMeter::CommandAggregator::Async.instance
40
- else raise ArgumentError
43
+ else command_aggregator
41
44
  end
42
45
  end
43
46
 
@@ -0,0 +1,42 @@
1
+ require 'socket'
2
+
3
+ module PulseMeter
4
+ module CommandAggregator
5
+ class UDP
6
+
7
+ def initialize(host, port)
8
+ @host, @port = host, port
9
+ @buffer = []
10
+ @in_multi = false
11
+ end
12
+
13
+ def multi
14
+ @in_multi = true
15
+ yield
16
+ ensure
17
+ @in_multi = false
18
+ send_buffer
19
+ end
20
+
21
+ def method_missing(*args)
22
+ @buffer << args
23
+ send_buffer unless @in_multi
24
+ end
25
+
26
+ private
27
+
28
+ def send_buffer
29
+ data = @buffer.to_json
30
+ sock = UDPSocket.new
31
+ sock.send(data, 0, @host, @port)
32
+ sock.close
33
+ rescue StandardError
34
+ PulseMeter.error "error sending data: #{e}, #{e.backtrace.join("\n")}"
35
+ ensure
36
+ @buffer = []
37
+ end
38
+
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,43 @@
1
+ require 'socket'
2
+ require 'timeout'
3
+
4
+ module PulseMeter
5
+ class UDPServer
6
+ MAX_PACKET = 1024
7
+
8
+ def initialize(host, port)
9
+ @socket = UDPSocket.new
10
+ @socket.do_not_reverse_lookup = true
11
+ @socket.bind(host, port)
12
+ end
13
+
14
+ def start(max_packets = nil)
15
+ while true do
16
+ if max_packets
17
+ break if max_packets <= 0
18
+ max_packets -= 1
19
+ end
20
+ process_packet
21
+ end
22
+ end
23
+
24
+ private
25
+
26
+ def process_packet
27
+ raw_data, _ = @socket.recvfrom(MAX_PACKET)
28
+ data = parse_data(raw_data)
29
+ data.each do |command|
30
+ PulseMeter.redis.send(*command)
31
+ end
32
+ rescue StandardError => e
33
+ PulseMeter.error "Error processing packet: #{e}"
34
+ end
35
+
36
+ def parse_data(data)
37
+ JSON.parse(data)
38
+ rescue
39
+ PulseMeter.error "Bad redis data: #{data.inspect}"
40
+ []
41
+ end
42
+ end
43
+ end
@@ -1,3 +1,3 @@
1
1
  module PulseMeter
2
- VERSION = "0.4.2"
2
+ VERSION = "0.4.3"
3
3
  end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe PulseMeter::CommandAggregator::UDP do
4
+ let(:host){'127.0.0.1'}
5
+ let(:port){33333}
6
+ let(:udp_sock){mock(:socket)}
7
+ before do
8
+ UDPSocket.stub!(:new).and_return(udp_sock)
9
+ udp_sock.stub!(:close).and_return(nil)
10
+ @ca = described_class.new(host, port)
11
+ end
12
+
13
+ describe "#multi" do
14
+ it "should accumulate redis commands and send them in a bulk" do
15
+ data = [
16
+ ["set", "xxxx", "zzzz"],
17
+ ["set", "yyyy", "zzzz"]
18
+ ].to_json
19
+ udp_sock.should_receive(:send).with(data, 0, host, port).and_return(0)
20
+ @ca.multi do
21
+ @ca.set("xxxx", "zzzz")
22
+ @ca.set("yyyy", "zzzz")
23
+ end
24
+ end
25
+ end
26
+
27
+ describe "any other redis instance method" do
28
+ it "should send data imediately" do
29
+ data = [
30
+ ["set", "xxxx", "zzzz"]
31
+ ].to_json
32
+ udp_sock.should_receive(:send).with(data, 0, host, port).and_return(0)
33
+ @ca.set("xxxx", "zzzz")
34
+ end
35
+ end
36
+
37
+ end
38
+
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe PulseMeter::UDPServer do
4
+ let(:host){'127.0.0.1'}
5
+ let(:port){33333}
6
+ let(:udp_sock){mock(:socket)}
7
+ let(:redis){PulseMeter.redis}
8
+ before do
9
+ UDPSocket.should_receive(:new).and_return(udp_sock)
10
+ udp_sock.should_receive(:bind).with(host, port).and_return(nil)
11
+ udp_sock.should_receive("do_not_reverse_lookup=").with(true).and_return(nil)
12
+ @server = described_class.new(host, port)
13
+ end
14
+
15
+ describe "#start" do
16
+ let(:data){
17
+ [
18
+ ["set", "xxxx", "zzzz"],
19
+ ["set", "yyyy", "zzzz"]
20
+ ].to_json
21
+ }
22
+ it "should process proper incoming commands" do
23
+ udp_sock.should_receive(:recvfrom).with(described_class::MAX_PACKET).and_return(data)
24
+ @server.start(1)
25
+ redis.get("xxxx").should == "zzzz"
26
+ redis.get("yyyy").should == "zzzz"
27
+ end
28
+
29
+ it "should suppress JSON errors" do
30
+ udp_sock.should_receive(:recvfrom).with(described_class::MAX_PACKET).and_return("xxx")
31
+ expect{ @server.start(1) }.not_to raise_exception
32
+ end
33
+ end
34
+
35
+ end
36
+
@@ -27,8 +27,9 @@ describe PulseMeter do
27
27
  end
28
28
  end
29
29
  context "otherwise" do
30
- it "should raise ArgumentError" do
31
- expect{ PulseMeter.command_aggregator = :xxx }.to raise_exception(ArgumentError)
30
+ it "should set command_aggregator to the passed value" do
31
+ PulseMeter.command_aggregator = :xxx
32
+ PulseMeter.command_aggregator.should == :xxx
32
33
  end
33
34
  end
34
35
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pulse-meter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.4.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-02-02 00:00:00.000000000 Z
13
+ date: 2013-02-08 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: gon-sinatra
@@ -415,6 +415,7 @@ files:
415
415
  - lib/pulse-meter.rb
416
416
  - lib/pulse-meter/command_aggregator/async.rb
417
417
  - lib/pulse-meter/command_aggregator/sync.rb
418
+ - lib/pulse-meter/command_aggregator/udp.rb
418
419
  - lib/pulse-meter/extensions/enumerable.rb
419
420
  - lib/pulse-meter/mixins/cmd.rb
420
421
  - lib/pulse-meter/mixins/dumper.rb
@@ -447,6 +448,7 @@ files:
447
448
  - lib/pulse-meter/server/command_line_options.rb
448
449
  - lib/pulse-meter/server/config_options.rb
449
450
  - lib/pulse-meter/server/sensors.rb
451
+ - lib/pulse-meter/udp_server.rb
450
452
  - lib/pulse-meter/version.rb
451
453
  - lib/pulse-meter/visualize/app.rb
452
454
  - lib/pulse-meter/visualize/base.rb
@@ -537,6 +539,7 @@ files:
537
539
  - pulse-meter.gemspec
538
540
  - spec/pulse_meter/command_aggregator/async_spec.rb
539
541
  - spec/pulse_meter/command_aggregator/sync_spec.rb
542
+ - spec/pulse_meter/command_aggregator/udp_spec.rb
540
543
  - spec/pulse_meter/extensions/enumerable_spec.rb
541
544
  - spec/pulse_meter/mixins/cmd_spec.rb
542
545
  - spec/pulse_meter/mixins/dumper_spec.rb
@@ -562,6 +565,7 @@ files:
562
565
  - spec/pulse_meter/sensor/timelined/percentile_spec.rb
563
566
  - spec/pulse_meter/sensor/timelined/uniq_counter_spec.rb
564
567
  - spec/pulse_meter/sensor/uniq_counter_spec.rb
568
+ - spec/pulse_meter/udp_server_spec.rb
565
569
  - spec/pulse_meter/visualize/app_spec.rb
566
570
  - spec/pulse_meter/visualize/dsl/layout_spec.rb
567
571
  - spec/pulse_meter/visualize/dsl/page_spec.rb
@@ -607,9 +611,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
607
611
  - - ! '>='
608
612
  - !ruby/object:Gem::Version
609
613
  version: '0'
610
- segments:
611
- - 0
612
- hash: -1795310197501122422
613
614
  requirements: []
614
615
  rubyforge_project:
615
616
  rubygems_version: 1.8.23
@@ -620,6 +621,7 @@ summary: Lightweight Redis-based metrics aggregator and processor with CLI and s
620
621
  test_files:
621
622
  - spec/pulse_meter/command_aggregator/async_spec.rb
622
623
  - spec/pulse_meter/command_aggregator/sync_spec.rb
624
+ - spec/pulse_meter/command_aggregator/udp_spec.rb
623
625
  - spec/pulse_meter/extensions/enumerable_spec.rb
624
626
  - spec/pulse_meter/mixins/cmd_spec.rb
625
627
  - spec/pulse_meter/mixins/dumper_spec.rb
@@ -645,6 +647,7 @@ test_files:
645
647
  - spec/pulse_meter/sensor/timelined/percentile_spec.rb
646
648
  - spec/pulse_meter/sensor/timelined/uniq_counter_spec.rb
647
649
  - spec/pulse_meter/sensor/uniq_counter_spec.rb
650
+ - spec/pulse_meter/udp_server_spec.rb
648
651
  - spec/pulse_meter/visualize/app_spec.rb
649
652
  - spec/pulse_meter/visualize/dsl/layout_spec.rb
650
653
  - spec/pulse_meter/visualize/dsl/page_spec.rb