In: |
lib/slave.rb
|
Parent: | Object |
the Heartbeat class is essentially wrapper over an IPC channel that sends a ping on the channel indicating process health. if either end of the channel is detached the ping will fail and an error will be raised. in this way it is ensured that Slave objects cannot continue to live without their parent being alive.
# File lib/slave.rb, line 394 394: def initialize pulse_rate = 4.2, debug = false 395: #--{{{ 396: @pulse_rate = Float pulse_rate 397: @debug = debug 398: @r, @w = IO::pipe 399: @pid = Process::pid 400: @ppid = Process::ppid 401: @cid = nil 402: @thread = nil 403: @ppid = nil 404: @whoami = nil 405: @beating = nil 406: @pipe = nil 407: #--}}} 408: end
# File lib/slave.rb, line 443 443: def child_start 444: #--{{{ 445: @whoami = 'child' 446: @pid = Process::pid 447: @ppid = Process::ppid 448: @thread = 449: Thread::new(Thread::current) do |cur| 450: begin 451: loop do 452: trace{ "<#{ @whoami }> <#{ @pid }> puts <#{ @pid }>" } 453: @pipe.puts @pid 454: Process::kill 0, @ppid 455: sleep @pulse_rate 456: end 457: rescue => e 458: cur.raise e 459: ensure 460: @pipe.close rescue nil 461: end 462: end 463: #--}}} 464: end
# File lib/slave.rb, line 496 496: def child_start 497: #--{{{ 498: @whoami = 'child' 499: @pid = Process::pid 500: @ppid = Process::ppid 501: @thread = 502: Thread::new(Thread::current) do |cur| 503: begin 504: trace{ "child reading..." } 505: @pipe.read 506: trace{ "child read." } 507: trace{ "child exiting." } 508: exit 509: rescue => e 510: cur.raise e 511: ensure 512: @pipe.close rescue nil 513: end 514: end 515: #--}}} 516: end
# File lib/slave.rb, line 424 424: def parent_start 425: #--{{{ 426: @whoami = 'parent' 427: @thread = 428: Thread::new(Thread::current) do |cur| 429: begin 430: loop do 431: buf = @pipe.gets 432: trace{ "<#{ @whoami }> <#{ @pid }> gets <#{ buf.inspect }>" } 433: @cid = Integer buf.strip if @cid.nil? and buf =~ %/^\s*\d+\s*$/ 434: end 435: rescue => e 436: cur.raise e 437: ensure 438: @pipe.close rescue nil 439: end 440: end 441: #--}}} 442: end
# File lib/slave.rb, line 481 481: def parent_start 482: #--{{{ 483: @whoami = 'parent' 484: @thread = 485: Thread::new(Thread::current) do |cur| 486: begin 487: sleep 488: rescue => e 489: cur.raise e 490: ensure 491: @pipe.close rescue nil 492: end 493: end 494: #--}}} 495: end
# File lib/slave.rb, line 409 409: def start 410: #--{{{ 411: if Process::pid == @pid 412: @w.close 413: @pipe = @r 414: @pipe.fcntl Fcntl::F_SETFD, Fcntl::FD_CLOEXEC 415: parent_start 416: else 417: @r.close 418: @pipe = @w 419: child_start 420: end 421: @beating = true 422: #--}}} 423: end
# File lib/slave.rb, line 466 466: def start 467: #--{{{ 468: if Process::pid == @pid 469: @r.close 470: @pipe = @w 471: @pipe.fcntl Fcntl::F_SETFD, Fcntl::FD_CLOEXEC 472: parent_start 473: else 474: @w.close 475: @pipe = @r 476: child_start 477: end 478: @beating = true 479: #--}}} 480: end
# File lib/slave.rb, line 517 517: def stop 518: #--{{{ 519: raise "not beating" unless @beating 520: @thread.kill 521: @pipe.close rescue nil 522: @beating = false 523: #--}}} 524: end