0

Following the good advice on this link: How to keep checking for a file until it exists, then provide a link to it

The loop will never end if the file will never be created. In a perfect system, it should not happen, but if it does how would one exit from that loop?

I have a similar case:

/* More codes above */
  // writing on the file
  $csvfile = $foldername.$date.$version.".csv";
  $csv = fopen( $csvfile, 'w+' );

  foreach ($_POST['lists'] as $pref) {
    fputcsv($csv, $pref, ";");
  }

  // close and wait IO creation
  fclose($csv);
  sleep(1);

  // Running the Java
  $exec = shell_exec("/usr/bin/java -jar $app $csvfile");
  sleep(3);

  $xmlfile = preg_replace('/\\.[^.\\s]{3,4}$/', '.xml', $csvfile);
  if (file_exists("$csvfile") && (file_exists("$xmlfile"))){
      header("Location:index.php?msg");
exit;
      }
      else if (!file_exists("$csvfile")){
          header("Location:index.php?msgf=".basename($csvfile)." creation failed!");
exit;
      }
      else if (!file_exists("$xmlfile")){
          header("Location:index.php?msgf=".basename($xmlfile)." creation failed!");
exit;
      }
      //exit;
} // Just the end
?>

( Yes, bad idea to pass variables in the url.. I got that covered )

I use sleep(N); because I know the java takes short to create the file, same for the csv on the php.

How can I improve the check on the file, to wait the necessary time before reporting the status OK or NOT ok if the file was not created?

Community
  • 1
  • 1
aPugLife
  • 989
  • 2
  • 14
  • 25
  • well for one thing, you should add `exit;` to each of your headers and the keyword here is "exit". – Funk Forty Niner Jan 31 '17 at 16:07
  • @Fred-ii- True, the exit is at the end of the php, just didn't think of pasting it here - I guess I will - Thanks – aPugLife Jan 31 '17 at 16:07
  • even though you say it's at the end, header could keep on wanting to execute if they're not added to each header. – Funk Forty Niner Jan 31 '17 at 16:08
  • @Fred-ii- to each header. Ok i'll fix that, thanks (:! – aPugLife Jan 31 '17 at 16:10
  • `else if` is unnecessary, it only increases the cyclomatic complexity. Where's your loop? – Gabriel Heming Jan 31 '17 at 16:16
  • The code after `shell_exec()` will not execute until the `java` call has completed, so the file has either been created or it failed. – AbraCadaver Jan 31 '17 at 16:17
  • @GabrielHeming well that is correct, not good to use many if, would be just a waste of time and resources, and in my case it probably does. I just wrote the first code that got to my mind, I'm still testing it so I probably will fix this too. That's why I was looking for the best loop, this part is to fix – aPugLife Jan 31 '17 at 16:19
  • @AbraCadaver if it is true, i don't even need to `sleep();` here. Honestly, I haven't tried with a infinite-java-loop and see when the next php code will be executed. Well, it seems I do not need a loop that check if the file exist, then! – aPugLife Jan 31 '17 at 16:24

1 Answers1

1

After reading your comments, I think "the best loop" isn't a good question to get a better answer.

The linked script just give a good approach when the script expects a file. That script will wait until the file is created or forever (but the creator ensures about the file creation).

Better than that, you could give a particular period to ensure if the file exists or not.

If after the shell_exec the java script didn't create the file (which I think is almost impossible, but is just a thought), you could use a code like above:

$cycles = 0;
while (!($isFileCreated = file_exists($filename)) && $cycles > 1000) { 
    $cycles++;
    usleep(1);
}

if (!$isFileCreated)
{
    //some action
    //throw new RuntimeException("File doesn't exists");
}

//another action

The script above will wait until the file is created or until reach a particular amount of cycles (it's better to call cycles than microseconds, because I can't ensure that each cycle will be execute in one microsecond). The number of cycles can be changed if you need more time.

Gabriel Heming
  • 1,100
  • 10
  • 30
  • The file will always be created if the content of the csv will always match the classes wrote in the Java. When A new *someting* will be inserted in the csv and the Java is not ready for that (perhaps an upgrade, I use the marshall class for converting a csv to xml), then the Java will fail and the file won't be created. I am reading your code, clear enough! let me test it (: ps. $cycles is expressed in seconds...? so a timeout of 10 second is better than one of 1000 seconds.. – aPugLife Jan 31 '17 at 16:39
  • Oh, You're right. I was thinking about `usleep`. It's correct now. `sleep` is in seconds, `usleep` is in micro seconds – Gabriel Heming Jan 31 '17 at 16:42
  • If you need to use this verification on more than one place, wrap it into a function. – Gabriel Heming Jan 31 '17 at 16:44
  • Ok let me test it a bit and I'll upvote/comment when i have some results (: thanks! – aPugLife Jan 31 '17 at 16:50
  • Ok so, im not using usleep because for my needs the sleep is good already, therefore my cicles are not 1000 but reduced to just 5. I only need 5 seconds to know if the file exists or not. the command OR does not work, I thought it was a AND, so I modified it: `while (!($isFileCreated = file_exists($xmlfile)) && $cycles < 5) { $cycles++; sleep(1); }` To be honest, what the comments on my post say are true, `shell_exec()` is released only after the -java- complete its job. So I actually do not need a loop. But I thank you for your code! and if you tell me it is right the `&&` I *** – aPugLife Jan 31 '17 at 17:04
  • The approach about the usleep, is to give less time between the verification (which is just a measurement). You're right (again) about the conditional operator, it's must be AND. Correct now. – Gabriel Heming Jan 31 '17 at 17:07
  • Well usleep is probably the best choice because less "time" to wait between seconds. Good job (: – aPugLife Jan 31 '17 at 17:09