Slave::Heartbeat (Class)

In: lib/slave.rb
Parent: Object
o Slave TopLevel

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.

Methods

child_start   child_start   new   parent_start   parent_start   start   start   stop   trace  

Public Class methods

[Source]

     # 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

Public Instance methods

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # 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

[Source]

     # File lib/slave.rb, line 525
525:       def trace
526: #--{{{
527:         STDERR.puts(yield) if @debug and STDERR.tty?
528: #--}}}
529:       end

[Validate]