riser 0.1.2 → 0.1.3

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
  SHA256:
3
- metadata.gz: cb038d800b97433c3499cb880acc77e0513d6dab1d18eace369137a98870cd8b
4
- data.tar.gz: e4b2a6ab5cc93fa3e84c0dcdd53038e879d54e51ee2007f702a1afeb10c45409
3
+ metadata.gz: 4ac8260579321a152af6b38fe4305936934ede2893c1b9ede48a1c85563aad8d
4
+ data.tar.gz: 93a8e6145c9d53e94ed3443d46dc64c55460638a60eab2097bc563eff9f2b724
5
5
  SHA512:
6
- metadata.gz: 4b5fdb35eb7ea3c7f9b535e5d857acb7bb85b671db989ed90123ead48d1079606afbe35a9f0c970a4ddfe62c21c32246468406c33739fad5a037b5e61b92d525
7
- data.tar.gz: 71a67816a2048bd849eb12801a40c8114b446bafbbde210e253c172af915026d524c976f6068472ebf747af2b9a0ad6b79d9e3344b74b58bf96c874337db3368
6
+ metadata.gz: 59148c981335471f2c57d0caca09b1b8272008180fbe045e2f5f13988996c020741930419c4df73570811d148bd66df89f2c5aa260767852df6fd8627f711bb3
7
+ data.tar.gz: f0ba2792523825f164376e19a841274c685aca4dab7c8f32a5b88a496c97dcbb5eb5a077a36b417029ad3cf1db885df300c096164b840b3c06b3387c91a5ad8a
data/lib/riser/daemon.rb CHANGED
@@ -270,6 +270,65 @@ module Riser
270
270
  end
271
271
  private :server_stop_forced
272
272
 
273
+ def server_socket_option(server_socket, server_address)
274
+ if (server_address.backlog) then
275
+ if (@sysop.listen(server_socket, server_address.backlog)) then
276
+ @logger.info("server socket backlog: #{server_address.backlog}")
277
+ else
278
+ @logger.warn('server socket backlog is not changed.')
279
+ end
280
+ else
281
+ @logger.info('server socket backlog is default.')
282
+ end
283
+
284
+ if (server_address.type == :unix) then
285
+ if (server_address.mode) then
286
+ if (@sysop.chmod(server_address.mode, server_address.path)) then
287
+ @logger.info("unix domain server socket mode: #{'%04o' % server_address.mode}")
288
+ else
289
+ @logger.warn('unix domain server socket mode is not changed.')
290
+ end
291
+ else
292
+ @logger.info('unix domain server socket mode is default.')
293
+ end
294
+
295
+ if (server_address.owner || server_address.group) then
296
+ if (@sysop.chown(server_address.owner, server_address.group, server_address.path)) then
297
+ @logger.info("unix domain server socket ownership: <#{server_address.owner}> <#{server_address.group}>")
298
+ else
299
+ @logger.warn('unix domain server socket ownership is not changed.')
300
+ end
301
+ else
302
+ @logger.info('unix domain server socket ownership is default.')
303
+ end
304
+ end
305
+
306
+ nil
307
+ end
308
+ private :server_socket_option
309
+
310
+ def server_socket_close(server_socket, server_address)
311
+ # get local_address before close(2)
312
+ server_socket_local_address = server_socket.local_address
313
+
314
+ if (@sysop.close(server_socket)) then
315
+ @logger.info("close server socket: #{server_socket_local_address.inspect_sockaddr}")
316
+ else
317
+ @logger.warn("failed to close server socket: #{server_socket_local_address.inspect_sockaddr}")
318
+ end
319
+
320
+ if (server_address.type == :unix) then
321
+ if (@sysop.unlink(server_address.path)) then
322
+ @logger.info("delete unix server socket: #{server_address}")
323
+ else
324
+ @logger.warn("failed to delete unix server socket: #{server_address}")
325
+ end
326
+ end
327
+
328
+ nil
329
+ end
330
+ private :server_socket_close
331
+
273
332
  def run_server(server_socket)
274
333
  read_write = @sysop.pipe
275
334
  unless (read_write) then
@@ -357,37 +416,7 @@ module Riser
357
416
  @logger.info("open server socket: #{server_socket.local_address.inspect_sockaddr}")
358
417
 
359
418
  begin
360
- if (server_address.backlog) then
361
- if (@sysop.listen(server_socket, server_address.backlog)) then
362
- @logger.info("server socket backlog: #{server_address.backlog}")
363
- else
364
- @logger.warn('server socket backlog is not changed.')
365
- end
366
- else
367
- @logger.info('server socket backlog is default.')
368
- end
369
-
370
- if (server_address.type == :unix) then
371
- if (server_address.mode) then
372
- if (@sysop.chmod(server_address.mode, server_address.path)) then
373
- @logger.info("unix domain server socket mode: #{'%04o' % server_address.mode}")
374
- else
375
- @logger.warn('unix domain server socket mode is not changed.')
376
- end
377
- else
378
- @logger.info('unix domain server socket mode is default.')
379
- end
380
-
381
- if (server_address.owner || server_address.group) then
382
- if (@sysop.chown(server_address.owner, server_address.group, server_address.path)) then
383
- @logger.info("unix domain server socket ownership: <#{server_address.owner}> <#{server_address.group}>")
384
- else
385
- @logger.warn('unix domain server socket ownership is not changed.')
386
- end
387
- else
388
- @logger.info('unix domain server socket ownership is default.')
389
- end
390
- end
419
+ server_socket_option(server_socket, server_address)
391
420
 
392
421
  unless (server_pid = run_server(server_socket)) then
393
422
  @logger.fatal('failed to start daemon.')
@@ -426,19 +455,7 @@ module Riser
426
455
  else
427
456
  if (next_server_socket = @sysop.get_server_socket(next_server_address)) then
428
457
  @logger.info("open server socket: #{next_server_socket.local_address.inspect_sockaddr}")
429
- server_socket_local_address = server_socket.local_address # get local_address before close(2)
430
- if (@sysop.close(server_socket)) then
431
- @logger.info("close server socket: #{server_socket_local_address.inspect_sockaddr}")
432
- else
433
- @logger.warn("failed to close server socket: #{server_socket_local_address.inspect_sockaddr}")
434
- end
435
- if (server_address.type == :unix) then
436
- if (@sysop.unlink(server_address.path)) then
437
- @logger.info("delete unix server socket: #{server_address}")
438
- else
439
- @logger.warn("failed to delete unix server socket: #{server_address}")
440
- end
441
- end
458
+ server_socket_close(server_socket, server_address)
442
459
  server_socket = next_server_socket
443
460
  server_address = next_server_address
444
461
  else
@@ -448,38 +465,7 @@ module Riser
448
465
  else
449
466
  @logger.warn("server socket continue: #{server_socket.local_address.inspect_sockaddr}")
450
467
  end
451
-
452
- if (server_address.backlog) then
453
- if (@sysop.listen(server_socket, server_address.backlog)) then
454
- @logger.info("server socket backlog: #{server_address.backlog}")
455
- else
456
- @logger.warn('server socket backlog is not changed.')
457
- end
458
- else
459
- @logger.info('server socket backlog is default.')
460
- end
461
-
462
- if (server_address.type == :unix) then
463
- if (server_address.mode) then
464
- if (@sysop.chmod(server_address.mode, server_address.path)) then
465
- @logger.info("unix domain server socket mode: #{'%04o' % server_address.mode}")
466
- else
467
- @logger.warn('unix domain server socket mode is not changed.')
468
- end
469
- else
470
- @logger.info('unix domain server socket mode is default.')
471
- end
472
-
473
- if (server_address.owner || server_address.group) then
474
- if (@sysop.chown(server_address.owner, server_address.group, server_address.path)) then
475
- @logger.info("unix domain server socket ownership: <#{server_address.owner}> <#{server_address.group}>")
476
- else
477
- @logger.warn('unix domain server socket ownership is not changed.')
478
- end
479
- else
480
- @logger.info('unix domain server socket ownership is default.')
481
- end
482
- end
468
+ server_socket_option(server_socket, server_address)
483
469
 
484
470
  case (sig_ope)
485
471
  when :restart_graceful
@@ -579,19 +565,7 @@ module Riser
579
565
  @logger.warn('no server to stop.')
580
566
  end
581
567
  ensure
582
- server_socket_local_address = server_socket.local_address # get local_address before close(2)
583
- if (@sysop.close(server_socket)) then
584
- @logger.info("close server socket: #{server_socket_local_address.inspect_sockaddr}")
585
- else
586
- @logger.warn("failed to close server socket: #{server_socket_local_address.inspect_sockaddr}")
587
- end
588
- if (server_address.type == :unix) then
589
- if (@sysop.unlink(server_address.path)) then
590
- @logger.info("delete unix server socket: #{server_address}")
591
- else
592
- @logger.warn("failed to delete unix server socket: #{server_address}")
593
- end
594
- end
568
+ server_socket_close(server_socket, server_address)
595
569
  end
596
570
 
597
571
  @logger.info('daemon stop.')
@@ -628,7 +602,7 @@ module Riser
628
602
 
629
603
  DEFAULT = {
630
604
  daemonize: true,
631
- daemon_name: 'ruby',
605
+ daemon_name: 'ruby'.freeze,
632
606
  daemon_debug: $DEBUG,
633
607
  daemon_nochdir: true,
634
608
  status_file: nil,
data/lib/riser/server.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'io/wait'
4
4
  require 'socket'
5
+ require 'tempfile'
5
6
 
6
7
  module Riser
7
8
  class TimeoutSizedQueue
@@ -173,6 +174,35 @@ module Riser
173
174
  SIGNAL_RESTART_FORCED = :QUIT
174
175
  end
175
176
 
177
+ module AcceptTimeout
178
+ module ServerSocketMethod
179
+ end
180
+ ::TCPServer.class_eval{ include ServerSocketMethod }
181
+ ::UNIXServer.class_eval{ include ServerSocketMethod }
182
+
183
+ refine ServerSocketMethod do
184
+ def accept_timeout(timeout_seconds)
185
+ begin
186
+ socket = accept_nonblock(exception: false)
187
+ if (socket != :wait_readable) then
188
+ socket
189
+ else
190
+ if (wait_readable(timeout_seconds) != nil) then
191
+ socket = accept_nonblock(exception: false)
192
+ # to ignore conflicting accept(2) at server restart overlap
193
+ if (socket != :wait_readable) then
194
+ socket
195
+ end
196
+ end
197
+ end
198
+ rescue Errno::EINTR # EINTR is not captured by `exception: false'
199
+ nil
200
+ end
201
+ end
202
+ end
203
+ end
204
+ using AcceptTimeout
205
+
176
206
  class SocketThreadDispatcher
177
207
  def initialize(thread_queue_name)
178
208
  @thread_num = nil
@@ -307,10 +337,10 @@ module Riser
307
337
  queue = TimeoutSizedQueue.new(@thread_queue_size, name: @thread_queue_name)
308
338
  begin
309
339
  thread_list = []
310
- @thread_num.times{|i|
311
- thread_list << Thread.new{
340
+ @thread_num.times do |i|
341
+ thread_list << Thread.start(i) {|thread_number|
312
342
  begin
313
- Thread.current[:number] = i
343
+ Thread.current[:number] = thread_number
314
344
  while (socket = queue.pop)
315
345
  begin
316
346
  @dispatch.call(socket)
@@ -324,7 +354,7 @@ module Riser
324
354
  }
325
355
  end
326
356
  }
327
- }
357
+ end
328
358
 
329
359
  catch (:end_of_server) {
330
360
  while (true)
@@ -475,6 +505,11 @@ module Riser
475
505
  nil
476
506
  end
477
507
 
508
+ SEND_CMD = "SEND\n".freeze # :nodoc:
509
+ SEND_LEN = SEND_CMD.length # :nodoc:
510
+ RADY_CMD = "RADY\n".freeze # :nodoc:
511
+ RADY_LEN = RADY_CMD.length # :nodoc:
512
+
478
513
  def start(server_socket)
479
514
  case (server_socket)
480
515
  when TCPServer, UNIXServer
@@ -483,10 +518,17 @@ module Riser
483
518
  socket_class = IO
484
519
  end
485
520
 
521
+ parent_latch_file = Tempfile.open('riser_latch_')
522
+ child_latch_file = File.open(parent_latch_file.path, File::RDWR)
523
+ child_latch_file.flock(File::LOCK_EX | File::LOCK_NB) or raise "internal error: failed to lock latch file: #{parent_latch_file.path}"
524
+ parent_latch_file.unlink
525
+
486
526
  process_list = []
487
527
  @process_num.times do |pos|
488
528
  child_io, parent_io = UNIXSocket.socketpair
489
529
  pid = Process.fork{
530
+ parent_latch_file.close
531
+
490
532
  parent_io.close
491
533
  pos.times do |i|
492
534
  process_list[i].io.close
@@ -506,12 +548,12 @@ module Riser
506
548
 
507
549
  thread_dispatcher.accept{
508
550
  if (child_io.wait_readable(@process_send_io_polling_timeout_seconds) != nil) then
509
- command = child_io.read(5)
510
- command == "SEND\n" or raise "internal error: unknown command <#{command.inspect}>"
551
+ command = child_io.read(SEND_LEN)
552
+ command == SEND_CMD or raise "internal error: unknown command <#{command.inspect}>"
511
553
  child_io.recv_io(socket_class)
512
554
  end
513
555
  }
514
- thread_dispatcher.accept_return{ child_io.write("RADY\n") }
556
+ thread_dispatcher.accept_return{ child_io.write(RADY_CMD) }
515
557
  thread_dispatcher.dispatch(&@dispatch)
516
558
 
517
559
  Signal.trap(SIGNAL_STOP_GRACEFUL) { thread_dispatcher.signal_stop_graceful }
@@ -520,8 +562,10 @@ module Riser
520
562
  Signal.trap(SIGNAL_STAT_GET_NO_RESET) { thread_dispatcher.signal_stat_get(reset: false) }
521
563
  Signal.trap(SIGNAL_STAT_STOP) { thread_dispatcher.signal_stat_stop }
522
564
 
565
+ # release flock(2)
566
+ child_latch_file.close
567
+
523
568
  begin
524
- child_io.write("RADY\n")
525
569
  @at_fork.call
526
570
  thread_dispatcher.start
527
571
  ensure
@@ -533,10 +577,9 @@ module Riser
533
577
  process_list << SocketProcess.new(pid, parent_io)
534
578
  end
535
579
 
536
- for process in process_list
537
- response = process.io.read(5)
538
- response == "RADY\n" or raise "internal error: unknown response <#{response.inspect}>"
539
- end
580
+ child_latch_file.close
581
+ parent_latch_file.flock(File::LOCK_EX) # wait to release flock(2) at child processes
582
+ parent_latch_file.close
540
583
 
541
584
  setup unless @process_dispatcher
542
585
  @process_dispatcher.thread_num = @process_num
@@ -576,21 +619,15 @@ module Riser
576
619
  @process_dispatcher.postprocess(&NO_CALL)
577
620
 
578
621
  @process_dispatcher.accept{
579
- if (server_socket.wait_readable(@accept_polling_timeout_seconds) != nil) then
580
- begin
581
- server_socket.accept_nonblock
582
- rescue IO::WaitReadable
583
- nil # to avoid conflicting accept(2) at server restart overlap
584
- end
585
- end
622
+ server_socket.accept_timeout(@accept_polling_timeout_seconds)
586
623
  }
587
624
  @process_dispatcher.accept_return(&NO_CALL)
588
625
  @process_dispatcher.dispatch{|socket|
589
626
  process = process_list[Thread.current[:number]]
590
- process.io.write("SEND\n")
627
+ process.io.write(SEND_CMD)
591
628
  process.io.send_io(socket)
592
- response = process.io.read(5)
593
- response == "RADY\n" or raise "internal error: unknown response <#{response.inspect}>"
629
+ response = process.io.read(RADY_LEN)
630
+ response == RADY_CMD or raise "internal error: unknown response <#{response.inspect}>"
594
631
  }
595
632
  @process_dispatcher.start
596
633
 
@@ -736,13 +773,7 @@ module Riser
736
773
  @dispatcher.preprocess(&@preprocess)
737
774
  @dispatcher.postprocess(&@postprocess)
738
775
  @dispatcher.accept{
739
- if (server_socket.wait_readable(@accept_polling_timeout_seconds) != nil) then
740
- begin
741
- server_socket.accept_nonblock
742
- rescue IO::WaitReadable
743
- nil # to avoid conflicting accept(2) at server restart overlap
744
- end
745
- end
776
+ server_socket.accept_timeout(@accept_polling_timeout_seconds)
746
777
  }
747
778
  @dispatcher.accept_return(&NO_CALL)
748
779
  @dispatcher.dispatch(&@dispatch)
data/lib/riser/version.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
 
3
3
  module Riser
4
- VERSION = '0.1.2'
4
+ VERSION = '0.1.3'.freeze
5
5
  end
6
6
 
7
7
  # Local Variables:
data/lib/riser.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  require 'riser/version'
4
4
 
5
5
  module Riser
6
+ autoload :AcceptTimeout, 'riser/server'
6
7
  autoload :DRbServiceCall, 'riser/services'
7
8
  autoload :DRbServiceServer, 'riser/services'
8
9
  autoload :DRbServices, 'riser/services'
data/misc/run_curls.sh ADDED
@@ -0,0 +1,34 @@
1
+ #!/bin/sh
2
+
3
+ sleep_seconds="${1:-1}"
4
+ num_curl="${2:-4}"
5
+
6
+ job_pid_list=''
7
+
8
+ run_curl() {
9
+ (
10
+ while true; do
11
+ curl --silent -- "$1"/ >/dev/null
12
+ done
13
+ ) &
14
+ job_pid_list="${job_pid_list} $!"
15
+ echo "run curl $!"
16
+ }
17
+
18
+ cmd() {
19
+ echo "$*"
20
+ "$@"
21
+ }
22
+
23
+ echo "GET URL: ${GET_URL:=http://localhost:8080}"
24
+
25
+ for i in $(yes | head -"${num_curl}"); do
26
+ run_curl "${GET_URL}"
27
+ done
28
+
29
+ cmd sleep "${sleep_seconds}"
30
+
31
+ for pid in $job_pid_list; do
32
+ cmd kill "${pid}"
33
+ wait "${pid}"
34
+ done
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riser
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - TOKI Yoshinori
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-02-09 00:00:00.000000000 Z
11
+ date: 2019-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -104,6 +104,7 @@ files:
104
104
  - lib/riser/temppath.rb
105
105
  - lib/riser/test.rb
106
106
  - lib/riser/version.rb
107
+ - misc/run_curls.sh
107
108
  - riser.gemspec
108
109
  homepage: https://github.com/y10k/riser
109
110
  licenses: