0

My setup:

My parent batch file executes seven child bat files then sends out an email telling me they've completed :

START "MyProcess1" C:/2oh/100a.bat
PING 127.0.0.1 -n 5 || PING ::1 -n 5
START "MyProcess2" C:/2oh/100b.bat
PING 127.0.0.1 -n 5 || PING ::1 -n 5
START "MyProcess3" C:/2oh/101a.bat
PING 127.0.0.1 -n 5 || PING ::1 -n 5
START "MyProcess4" C:/2oh/101b.bat
PING 127.0.0.1 -n 5 || PING ::1 -n 5
START "MyProcess5" C:/2oh/102.bat
PING 127.0.0.1 -n 5 || PING ::1 -n 5
START "MyProcess6" C:/2oh/103.bat
PING 127.0.0.1 -n 5 || PING ::1 -n 5
START "MyProcess7" C:/2oh/104.bat


:loop
  timeout /t 1 >nul

tasklist /v|find "MyProcess">nul && goto :loop
echo all tasks have finished..

sendEmail -f analyticsqa@gmail.com

The child bat file is a simple call to execute a ruby script like so.

C:/2oh/104.rb
exit

The ruby script is like so:

require_relative "./helper"
require_relative "./tests"
require 'logger'

class Tests < Test::Unit::TestCase
self.test_order = :defined
$stdout.reopen("log.txt", "a")


    def test_average_first_run
    puts "First Run"
    test_first_run  
    end 

So essentially - these seven ruby scripts are writing their contents to a single log file, then the parent batch file is emailing out that log. For whatever reason it seems to always get stuck on one of the batch files. It's done, there's nothing else to execute but the bat file doesn't close, as you can see in this screenshot, it just writes the exit to the screen but doesn't execute the command. So that won't close, which means the parent batch file doesn't close, so no emailed log. There's absolutely no difference in batch files or ruby scripts, they are all identical children. So for the life of me I cannot figure out why the batch file won't exit. If I execute this bat file independently it works just fine.

enter image description here

Jen
  • 109
  • 1
  • 12
  • Why do you need a bat file to execute one ruby file at a time? Why not just call the .rb files all from one .bat? – JLB Mar 21 '16 at 14:33
  • When I execute the ruby files directly from the parent bat file, it doesn't wait for the entire ruby script to complete before it emails out the log. – Jen Mar 21 '16 at 14:38
  • 1
    If you issue a 'start /w' on the .rb file, it should wait until done before returning. – JLB Mar 21 '16 at 14:39
  • That is most likely your issue with calling all the other batches in sequence. At some point you have two or three ruby programs trying to log to the same file at once. start /w is the key. – JLB Mar 21 '16 at 14:40
  • I need all seven children to run simultaneously though, which is what the parent bat file is doing. It's kicking off all seven at the same time (well a five second delay) Would start /w force to complete one child before starting the next child? – Jen Mar 21 '16 at 14:43
  • /w means don't return control to the calling process until complete. Is there a reason that you need them to run simultaneously, rather than consecutively? – JLB Mar 21 '16 at 14:52
  • I confirmed /w doesn't work for me. Yes, there is..I need all seven to complete as quickly as possible. If I run each one consecutively the entire process takes over 50 minutes to complete. Running seven threads knocks me down to 14 minutes. So maybe there's a better way to log or a better setup in general, but I do need all seven to run at the same time. – Jen Mar 21 '16 at 14:55
  • 1
    Then I think you need to log to seven different log files, and combine them into one before e-mailing. Using copy file1 + file2 etc etc should work to combine. – JLB Mar 21 '16 at 14:59
  • Thanks so much again, so far so good after implementing your suggestion! – Jen Mar 22 '16 at 14:08

1 Answers1

2

I am pretty sure that the cause of the problem is a deadlock caused by an attempt of two ruby processes to write to the log file at same time. I don't know ruby enough to suggest a solution for this point, but you may create several log files, one for each active process. If you want that the log file have the output of all processes, you may add the time to the output, combine all logs in one file at end, and sort it by the time column.

I also suggest you to use this method to wait for all ruby processes to end, that is much simpler and efficient:

(
START "MyProcess1" C:/2oh/100a.bat
START "MyProcess2" C:/2oh/100b.bat
START "MyProcess3" C:/2oh/101a.bat
START "MyProcess4" C:/2oh/101b.bat
START "MyProcess5" C:/2oh/102.bat
START "MyProcess6" C:/2oh/103.bat
START "MyProcess7" C:/2oh/104.bat
) | set /P "="

echo all tasks have finished..
sendEmail -f analyticsqa@gmail.com
Community
  • 1
  • 1
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • Yep, I came to the same conclusion about the deadlock and using multiple log files with the help of the other poster so thank you for confirming that, it seems to be working as expected now I think. Also double thanks for helping make my batch file more efficient, I love that! – Jen Mar 21 '16 at 16:26
  • Mmm.. Errr... Why did you cancelled the Best answer selection? – Aacini Mar 21 '16 at 18:24