villein 0.4.0 → 0.5.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: af36f01ce7087aedfc374cb6541e40bbb91a8321
4
- data.tar.gz: 83612d9193d206eed0770bcee0fbba3ce773e258
3
+ metadata.gz: 934ae99723282b5d94afb59a6804a1e0b96c1879
4
+ data.tar.gz: d6adab4011f1e4041c606cde13d014eb04e9bef1
5
5
  SHA512:
6
- metadata.gz: 40b1b349f00083a0e2a662c03f4e82a13d1d204f0a95e480197c58879fdf7f79a6d5ba8384b64072b7c84907f053623a021a4aaa371043630329868c19f3ff45
7
- data.tar.gz: 43e8c0e97b37961345414d56b9544d3e93818ed2215ef0b39bebb904072f3c5e04fabb921e1b7793056df45bbdc955b6aac1784034b1247924c64c32e6983871
6
+ metadata.gz: deebc81c352d00408d4361809c4eb976ad6e45fb1275d77c2b10800c8bd9e869bce494411fab677eac50d39615b4fdcb655c278fbaa1b99c191cb2c14cd159bc
7
+ data.tar.gz: a82e4a59374c72dbe5eadf627ae1c8cfe0acdb12c63056ba23b734e9c00685316112be2ac3d905207a274b42125bf025ab784b69cd39fff45edd0c496589a562
@@ -29,6 +29,8 @@ module Villein
29
29
  encrypt: nil, profile: nil, protocol: nil,
30
30
  event_handlers: [], replay: nil,
31
31
  tags: {}, tags_file: nil,
32
+ async_query: true,
33
+ parallel_events: false,
32
34
  log_level: :info, log: File::NULL,
33
35
  villein_handler: EVENT_HANDLER)
34
36
  @serf = serf
@@ -40,6 +42,7 @@ module Villein
40
42
  @encrypt, @profile, @protocol = encrypt, profile, protocol
41
43
  @custom_event_handlers, @replay = event_handlers, replay
42
44
  @initial_tags, @tags_file = tags, tags_file
45
+ @async_query, @parallel_events = async_query, parallel_events
43
46
  @log_level, @log = log_level, log
44
47
  @villein_handler = villein_handler
45
48
 
@@ -228,9 +231,15 @@ module Villein
228
231
  return if @event_listener_thread
229
232
 
230
233
  @event_listener_server = TCPServer.new('localhost', 0)
234
+ @event_queue = Queue.new
231
235
  @event_listener_thread = Thread.new do
232
236
  event_listener_loop
233
237
  end
238
+
239
+ @event_dispatcher_thread = Thread.new do
240
+ event_dispatcher_loop
241
+ end
242
+
234
243
  end
235
244
 
236
245
  def stop_listening_events
@@ -238,59 +247,105 @@ module Villein
238
247
  @event_listener_thread.kill
239
248
  end
240
249
 
250
+ if @event_listener_dispatcher && @event_listener_dispatcher.alive?
251
+ @event_listener_thread.kill
252
+ end
253
+
241
254
  if @event_listener_server && !@event_listener_server.closed?
242
255
  @event_listener_server.close
243
256
  end
244
257
 
245
258
  @event_listener_thread = nil
259
+ @event_listener_dispatcher = nil
260
+ @event_queue = nil
246
261
  @event_listener_server = nil
247
262
  end
248
263
 
249
264
  def event_listener_loop
250
- loop do
251
- Thread.new(@event_listener_server.accept) do |sock|
252
- begin
253
- buf, obuf = "", ""
254
- loop do
255
- socks, _, _ = IO.select([sock], nil, nil, 5)
256
- break unless socks
257
-
258
- socks[0].read_nonblock(2048, obuf)
259
- buf << obuf
260
- break if socks[0].eof?
261
- end
265
+ while sock = @event_listener_server.accept
266
+ sock_delegated = false
267
+ begin
268
+ buf, obuf = "", ""
269
+ loop do
270
+ socks, _, _ = IO.select([sock], nil, nil, 5)
271
+ break unless socks
272
+
273
+ socks[0].read_nonblock(2048, obuf)
274
+ buf << obuf
275
+ break if socks[0].eof?
276
+ end
262
277
 
263
- handle_event buf, sock
264
- ensure
265
- sock.close unless sock.closed?
278
+ event = parse_event(buf)
279
+ next unless event
280
+
281
+ # XXX:
282
+ if event.type == 'query'
283
+ if @async_query
284
+ sock_delegated = true
285
+ Thread.new(event, sock) do |ev, so|
286
+ handle_query ev, so
287
+ end
288
+ else
289
+ handle_query event, sock
290
+ end
291
+ else
292
+ if @parallel_events
293
+ Thread.new(event) do |ev|
294
+ handle_event event
295
+ end
296
+ else
297
+ @event_queue << event
298
+ end
266
299
  end
300
+ ensure
301
+ sock.close if !sock_delegated && !sock.closed?
267
302
  end
268
303
  end
269
304
  end
270
305
 
271
- def handle_event(payload, sock)
306
+ def event_dispatcher_loop
307
+ while event = @event_queue.pop
308
+ handle_event event
309
+ end
310
+ end
311
+
312
+ def parse_event(payload)
272
313
  env_payload, input = payload.split(/\0\0/,2) # ['name=val', 'name=val', '', 'input']
273
314
 
274
315
  env = Hash[env_payload.split(/\0/).map do |line|
275
316
  line.split(/=/,2)
276
317
  end]
277
318
 
278
- event = Event.new(env, payload: input)
319
+ Event.new(env, payload: input)
320
+ rescue JSON::ParserError
321
+ # do nothing
322
+ return nil
323
+ end
279
324
 
325
+ def handle_event(event)
280
326
  @event_received = true
327
+ call_hooks event.type.gsub(/-/, '_'), event
328
+ call_hooks 'event', event
329
+ rescue Exception => e
330
+ $stderr.puts "Exception during handling event: #{event.inspect}"
331
+ $stderr.puts "#{e.class}: #{e.message}"
332
+ $stderr.puts e.backtrace.map { |_| _.prepend("\t") }
333
+ end
281
334
 
335
+ def handle_query(event, sock)
336
+ @event_received = true
282
337
  call_hooks event.type.gsub(/-/, '_'), event
283
338
  call_hooks 'event', event
284
339
 
285
340
  if event.type == 'query' && @responders[event.query_name]
286
341
  sock.write(@responders[event.query_name].call(event))
287
342
  end
288
- rescue JSON::ParserError
289
- # do nothing
290
343
  rescue Exception => e
291
- $stderr.puts "Exception during handling event: #{event.inspect}"
344
+ $stderr.puts "Exception during handling query: #{event.inspect}"
292
345
  $stderr.puts "#{e.class}: #{e.message}"
293
346
  $stderr.puts e.backtrace.map { |_| _.prepend("\t") }
347
+ ensure
348
+ sock.close unless sock.closed?
294
349
  end
295
350
 
296
351
  def hooks_for(name)
@@ -1,3 +1,3 @@
1
1
  module Villein
2
- VERSION = "0.4.0"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -0,0 +1,18 @@
1
+ ## villein: tiny script for performance measuring
2
+
3
+ open 2 shells and run:
4
+
5
+ ```
6
+ $ ruby perf.rb
7
+ ```
8
+
9
+ ```
10
+ $ serf agent &
11
+ $ serf join localhost:17946
12
+ ```
13
+
14
+ then:
15
+
16
+ ```
17
+ $ ruby perf2.rb
18
+ ```
@@ -0,0 +1,17 @@
1
+ require 'villein'
2
+
3
+ agent = Villein::Agent.new(node: 'perf', rpc_addr: '127.0.0.1:17373', bind: "127.0.0.1:17946", parallel_events: !!ARGV[0])
4
+
5
+ agent.on_user_event do |event|
6
+ p event
7
+ end
8
+
9
+ agent.respond('myquery') do |event|
10
+ p event
11
+ Time.now.to_s
12
+ end
13
+
14
+ agent.auto_stop
15
+ agent.start!
16
+
17
+ sleep
@@ -0,0 +1,11 @@
1
+ i = 0
2
+ loop do
3
+ 100.times do
4
+ spawn "serf", "event", "-coalesce=false", "foo", i.to_s, out: File::NULL, err: File::NULL
5
+ spawn "serf", "event", "-coalesce=false", "bar", i.to_s, out: File::NULL, err: File::NULL
6
+ p i
7
+ i += 1
8
+ end
9
+ sleep 2
10
+ Process.waitall
11
+ end
@@ -76,6 +76,26 @@ describe Villein::Agent do
76
76
  expect(received2.type).to eq 'member-join'
77
77
  end
78
78
 
79
+ context "with parallel_events=true" do
80
+ subject(:agent) { described_class.new(rpc_addr: rpc_addr, bind: bind, parallel_events: false) }
81
+
82
+ it "can receive events" do
83
+ received1, received2 = nil, nil
84
+
85
+ agent.on_event { |e| received1 = e }
86
+ agent.on_member_join { |e| received2 = e }
87
+
88
+ agent.start!
89
+ 20.times { break if received1; sleep 0.1 }
90
+ agent.stop!
91
+
92
+ expect(received1).to be_a(Villein::Event)
93
+ expect(received2).to be_a(Villein::Event)
94
+ expect(received1.type).to eq 'member-join'
95
+ expect(received2.type).to eq 'member-join'
96
+ end
97
+ end
98
+
79
99
  it "can respond to queries" do
80
100
  agent.respond("hey") do |e|
81
101
  expect(e).to be_a(Villein::Event)
@@ -88,7 +108,24 @@ describe Villein::Agent do
88
108
  agent.stop!
89
109
 
90
110
  expect(response["Responses"].values.first).to eq("hello")
111
+ end
112
+
113
+ context "with async_query=false" do
114
+ subject(:agent) { described_class.new(rpc_addr: rpc_addr, bind: bind, async_query: false) }
115
+
116
+ it "can respond to queries" do
117
+ agent.respond("hey") do |e|
118
+ expect(e).to be_a(Villein::Event)
119
+ "hello"
120
+ end
121
+
122
+ agent.start!
123
+ Thread.new { agent.wait_for_ready }.join(5)
124
+ response = agent.query("hey", '')
125
+ agent.stop!
91
126
 
127
+ expect(response["Responses"].values.first).to eq("hello")
128
+ end
92
129
  end
93
130
 
94
131
  it "can handle unexpected stop" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: villein
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shota Fukumori (sora_h)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-08-14 00:00:00.000000000 Z
11
+ date: 2014-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -91,6 +91,9 @@ files:
91
91
  - lib/villein/tags.rb
92
92
  - lib/villein/version.rb
93
93
  - misc/villein-event-handler.rb
94
+ - perf/README.md
95
+ - perf/perf.rb
96
+ - perf/perf2.rb
94
97
  - spec/agent_spec.rb
95
98
  - spec/client_spec.rb
96
99
  - spec/event_handler_spec.rb