event-shipper 0.2.0 → 0.2.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.
data/HISTORY CHANGED
@@ -4,6 +4,13 @@
4
4
  + Proper framing of transmissions; transmissions are now versioned and
5
5
  should work even in environments where server and client are not the same
6
6
  gem. This is the case for versions >= 0.2.
7
+ + Handles corrupt messages by dropping them.
8
+ + Statistics output on SIGINFO; most OSs have that on Ctrl+T.
9
+ + All events have the tag 'shipped'
10
+
11
+ . Infrastructure for annotating JSON hash with transport information. Not
12
+ so sure where to take this.
13
+ . Infrastructure for sender-controlled queueing. Not sure if this is needed.
7
14
 
8
15
  = 0.1
9
16
 
@@ -13,7 +13,7 @@ module EventShipper
13
13
  :host => host, :path => path)
14
14
  @message = line.chomp.strip
15
15
  @fields = {}
16
- @tags = []
16
+ @tags = %w(shipped)
17
17
  end
18
18
 
19
19
  def to_hash
@@ -80,7 +80,7 @@ module EventShipper::Filter
80
80
  h[user] = AES256.new(pwd); h }
81
81
  end
82
82
 
83
- def de encrypted_string
83
+ def de encrypted_string, attributes={}
84
84
  message = parse_encrypted(encrypted_string)
85
85
 
86
86
  if algo = @user_db[message.user]
@@ -89,7 +89,9 @@ module EventShipper::Filter
89
89
  message.iv,
90
90
  message.ciphertext)
91
91
 
92
- return transmission
92
+ attributes[:encrypting_user] = message.user
93
+
94
+ return transmission, attributes
93
95
  else
94
96
  warn "No such user #{message.user} in database; cannot decrypt."
95
97
  return nil
@@ -10,13 +10,10 @@ module EventShipper::Filter
10
10
  class Transmission
11
11
  include EventShipper::Protocol
12
12
 
13
- def en hash
14
- transmission(
15
- event(
16
- queue: 'queue',
17
- json: hash.to_json)).serialize_to_string
13
+ def en event
14
+ transmission(event).serialize_to_string
18
15
  end
19
- def de string
16
+ def de string, attributes={}
20
17
  transmission = parse_transmission(string)
21
18
 
22
19
  if transmission.version != 1
@@ -24,7 +21,12 @@ module EventShipper::Filter
24
21
  end
25
22
 
26
23
  event = transmission.events.first
27
- JSON.parse(event.json)
24
+ attributes[:queue] = event.queue
25
+
26
+ return JSON.parse(event.json), attributes
27
+
28
+ rescue ProtocolBuffers::DecodeError
29
+ return nil
28
30
  end
29
31
  end
30
32
  end
@@ -2,6 +2,8 @@
2
2
  require_relative 'protocol/v1.pb.rb'
3
3
 
4
4
  module EventShipper::Protocol
5
+
6
+ module_function
5
7
  def transmission *events
6
8
  Transmission.new(
7
9
  version: 1,
@@ -33,6 +33,8 @@ module EventShipper
33
33
  host: redis_config['host'],
34
34
  port: redis_config['port'])
35
35
 
36
+ trap('SIGINFO') { puts transport.stats }
37
+
36
38
  transport.dispatch { |queue, message|
37
39
  # puts message }
38
40
  redis.lpush queue, message }
@@ -31,6 +31,8 @@ module EventShipper
31
31
  tailer
32
32
  end
33
33
 
34
+ trap('SIGINFO') { puts transport.stats }
35
+
34
36
  # Block until everyone exits.
35
37
  tailers.each do |tailer|
36
38
  tailer.join
@@ -0,0 +1,29 @@
1
+
2
+ module EventShipper
3
+ class Stats
4
+ def initialize
5
+ reset
6
+ end
7
+
8
+ def count_message
9
+ @messages += 1
10
+ end
11
+ def count_failure
12
+ @failures += 1
13
+ end
14
+
15
+ def reset
16
+ @period_start = Time.now
17
+ @messages = @failures = 0
18
+ end
19
+
20
+ def to_s
21
+ seconds = Time.now - @period_start
22
+
23
+ mps = @messages / Float(seconds)
24
+ fps = @failures / Float(seconds)
25
+
26
+ "#{mps} messages/s, #{fps} failures/s"
27
+ end
28
+ end
29
+ end
@@ -1,9 +1,12 @@
1
1
  require 'socket'
2
2
 
3
3
  require_relative 'filters'
4
+ require_relative 'stats'
4
5
 
5
6
  module EventShipper
6
7
  class UDP
8
+ attr_reader :stats
9
+
7
10
  def initialize host, port
8
11
  @host, @port = host, port
9
12
  @socket = UDPSocket.new
@@ -13,18 +16,7 @@ module EventShipper
13
16
  @filters = []
14
17
  wrap Filter::Transmission.new
15
18
 
16
- @messages_per_period = 0
17
- @period_start = Time.now
18
- Thread.start do
19
- loop do
20
- puts "total #{(@messages_per_period / (Time.now - @period_start)).round(3)} msgs/s"
21
-
22
- @messages_per_period = 0
23
- @period_start = Time.now
24
-
25
- sleep 10
26
- end
27
- end
19
+ @stats = Stats.new
28
20
  end
29
21
 
30
22
  def wrap filter
@@ -38,24 +30,44 @@ module EventShipper
38
30
  @filters.reverse.inject(obj) { |o, f| f.de(o) }
39
31
  end
40
32
 
41
- def send hash
42
- @messages_per_period += 1
43
- @socket.send encode(hash),
33
+ # Sends messages via UDP to a central proxy. Using the queue argument, the
34
+ # caller can decide which redis queue events end up in.
35
+ #
36
+ # @param hash [Hash] Attributes of the event to send.
37
+ # @param queue [String] Queue to put events into on the other end
38
+ def send hash, queue='queue'
39
+ event = Protocol.event(
40
+ queue: queue,
41
+ json: hash.to_json)
42
+
43
+ @socket.send encode(event),
44
44
  0, # flags...
45
45
  @host, @port
46
46
  end
47
47
 
48
+ # Handles a single message; decoding it and passing it to the caller.
49
+ #
50
+ def handle_message string
51
+ msg, attributes = decode(string)
52
+
53
+ if msg
54
+ @stats.count_message
55
+
56
+ queue = attributes[:queue]
57
+ yield queue, msg
58
+ else
59
+ @stats.count_failure
60
+ end
61
+ end
62
+
48
63
  # Enters a loop, receiving messages, yielding them to the block.
49
64
  #
50
65
  def dispatch
51
66
  @socket.bind @host, @port
52
67
  loop do
53
68
  datagram, source_info = @socket.recvfrom(10 * 1024)
54
- @messages_per_period += 1
55
-
56
- hash = decode(datagram)
57
69
 
58
- yield nil, hash
70
+ handle_message(datagram)
59
71
  end
60
72
  end
61
73
  end
@@ -0,0 +1,29 @@
1
+
2
+ module EventShipper
3
+ class Stats
4
+ def initialize
5
+ reset
6
+ end
7
+
8
+ def count_message
9
+ @messages += 1
10
+ end
11
+ def count_failure
12
+ @failures += 1
13
+ end
14
+
15
+ def reset
16
+ @period_start = Time.now
17
+ @messages = @failures = 0
18
+ end
19
+
20
+ def to_s
21
+ seconds = Time.now - @period_start
22
+
23
+ mps = @messages / Float(seconds)
24
+ fps = @failures / Float(seconds)
25
+
26
+ "#{mps} messages/s, #{fps} failures/s"
27
+ end
28
+ end
29
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: event-shipper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -131,8 +131,10 @@ files:
131
131
  - lib/event_shipper/protocol.rb
132
132
  - lib/event_shipper/proxy.rb
133
133
  - lib/event_shipper/shipper.rb
134
+ - lib/event_shipper/stats.rb
134
135
  - lib/event_shipper/udp.rb
135
136
  - lib/event_shipper.rb
137
+ - lib/stats.rb
136
138
  - bin/bench
137
139
  - bin/esproxy
138
140
  - bin/esshipper