User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the Ruby section within the Web Development category of DaniWeb, a massive community of 332,787 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 2,949 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our Ruby advertiser: SELL YOUR PRODUCT TODAY !
May 9th, 2007
Views: 1,400
I needed a way to spawn multiple threads, have them monitored, and restarted if an error occured. I came up with the following.

This snippet is from a larger program, so if there is a problem please let me know. This is for command line and tested on Linux (well, the larger program).
Last edited : May 12th, 2007.
ruby Syntax
  1. <%
  2.  
  3. #!/usr/bin/env ruby
  4. ## kill some warnings about writable directories
  5. $VERBOSE=nil
  6.  
  7. # we want to parse input, right?
  8. require 'optparse'
  9.  
  10. ## global options (which can and will be changed)
  11. @@options = {
  12. :runtime => "01:00:00",
  13. :total_time => 0,
  14. :threadlist => [],
  15. }
  16.  
  17.  
  18. def parse_input()
  19. ARGV.options do |opts|
  20. opts.banner = "Usage: #{$0} [options] <thread names>"
  21. opts.separator "Threadeds spawning threads, oh my!"
  22. opts.separator ""
  23. opts.separator "Options:"
  24.  
  25. opts.on("-h", "--help", "show this message") {
  26. puts opts
  27. exit
  28. }
  29.  
  30. opts.on("-v", "--version", "show version details") {
  31. version = `grep -m 1 "#(@)" #{$0} | awk '{printf("version: %s (%s)",$3,$2)}'`
  32. puts version
  33. exit
  34. }
  35.  
  36. opts.on("--duration=HH:MM:SS", String, "specify how long to run test (default: #{@@options[:runtime]})") { |@@options[:runtime]| }
  37.  
  38. opts.parse!
  39. end
  40.  
  41. ## validate time
  42. hours, mins, secs = @@options[:runtime].to_s.split(":")
  43. if hours.nil? or mins.nil? or secs.nil?
  44. puts "ERROR -- Invalid time format!"
  45. exit 1
  46. end
  47.  
  48. @@options[:total_time] = (hours.to_i * 60 * 60) + (mins.to_i * 60) + secs.to_i
  49.  
  50. ## thread list, anyone?
  51. if ARGV.length < 1
  52. puts "ERROR! No thread names specified!"
  53. exit 1
  54. else
  55. @@options[:threadlist] = ARGV
  56. end
  57. end
  58.  
  59. @threads = []
  60. @start_time = Time.now
  61.  
  62. ## trap ctrl-c
  63. trap("INT") { threadDestroyAll() }
  64.  
  65. def newPass(threadname)
  66. ## create a new thread and add it to @threads
  67. @threads << Thread.new(threadname) { |myThread|
  68. ## trap that CTRL-C
  69. trap("INT") { threadDestroyAll() }
  70. ## name thread to that of name given. easier management
  71. Thread.current[:name] = "#{myThread}"
  72.  
  73. ## Stuff for thread to do goes here.
  74. }
  75. end
  76.  
  77. ## this is triggered via CTRL-C trap above
  78. # kill all threads and exit
  79. def threadDestroyAll()
  80. puts "***************************"
  81. puts "** Killing all processes **"
  82. puts "***************************"
  83. @threads.each { |thread| thread.kill }
  84. sleep 2
  85. Thread.main.kill
  86. end
  87.  
  88. ## needed a way to watch over all the baby threads
  89. # this will cycle through all threads, gathering a list of
  90. #+ those that are still running (and their names, which are that of the client)
  91. #+ any missing clients are then restarted.
  92. def threadOverlord(threads)
  93. threadList = activeThreads = deadThreads = []
  94. threadList = @@options[:threadlist]
  95. threads.each { |thread| activeThreads << thread[:name] if thread.alive? and keepGoing() }
  96. ## restart baby threads that have died?
  97. # if time limit has been reached, that is a no
  98. if keepGoing()
  99. deadThreads = threadList - activeThreads
  100. deadThreads.each { |threadname| newPass(threadname) }
  101. end
  102. activeThreads = deadThreads = threadList = nil
  103. end
  104.  
  105. ## parent thread
  106. # this is just to trigger threadOverlord every X seconds
  107. #+ and check on the health of client threads
  108. def statusThread()
  109. statusT = Thread.new {
  110. Thread.current[:name] = "Overlord"
  111. loop do
  112. threadOverlord(@threads)
  113. sleep 15
  114. break if !keepGoing()
  115. end
  116. }
  117. statusT.join
  118. end
  119.  
  120. ## returns true if there is still time remaining
  121. def keepGoing()
  122. return true if Time.now.to_i - @start_time.to_i < @@options[:total_time].to_i
  123. false
  124. end
  125.  
  126. parse_input()
  127. statusThread
  128.  
  129. %>
Post Comment

Only community members can submit or comment on code snippets. You must register or log in to contribute.

DaniWeb Marketplace (Sponsored Links)
All times are GMT -4. The time now is 10:00 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC