This is more a question about nohup than my PHP script although I will include code for you guys to see. I am using a script what is designed to never end, meaning script termination should never take place. In an ideal world the script would run forever. This is achieved with <?php while (true) {} ?> which I am led to believe is the correct way of doing this?
However I am finding my script is terminating for reasons unknown every few days. The longest the script has run for is 4 days. I am left baffled and unable to reproduce test case scenarios without the aid of having the output from the process at the time of termination. Does nohup allow you to see what happens when the process terminates?
I can see the process running when I do ps aux and once the script has finished execution it disappears from the ps aux list, suggesting that the problem is with the she'll environment the script is run in rather than any portion of my code?
Can anybody help. Any debugging tools for this would be appreciated.
EDIT: I am looking for tools to debug this scenario any help appreciated.
The problem here was with MySQL. MySQL needed to be configured not to die after a long session. (or re-establish periodically)
Use show variables like 'wait_timeout'; to see what your setup is configured for.
Related
I have a terminal application that is currently written in Bash, about 20,000 SLOC. One thing that I like about the way that it's set up is that it is quite modular. Different components are spread across different files, which can be executed at run time. This means that parts of the system can be "hot swapped" or updated during runtime without needing to kill the main program and re-execute it.
The disadvantage is there is a lot of database I/O, which makes it super janky since Bash is really not suited for this. Currently, it interfaces with HTTP APIs which spawn PHP.
I'd like to rewrite it natively in PHP (CLI) to cut out the middleman layer, so the application can communicate directly with the database, making maintenance much easier. One problem I've been pondering though is how to replicate the same modularity with Bash. With Bash, if I call script A, and I make a change to script B, and then I enter script B from script A (assuming it's in a conditional block somewhere, not right at the top of the file), the changes are picked up without needing to re-execute script A, since script B isn't interpreted until it gets executed.
I'm struggling to figure out how to achieve this with PHP. For instance, this will not work:
include('script.php');
The reason is that includes are all executed when the script is interpreted, not when it is executed at run time.
A similar question has been asked already, but it doesn't specifically address this aspect, just how to launch another script in general. I want to basically be able to spawn the script anew at runtime, when the application decides it should be executed. shell_exec and passthru seem to be all that is built into PHP that would be similar, but I'm not sure this is right since that's just spawning another system shell and doing it there, so it's not as "direct" as with Bash.
What would be the proper equivalent in PHP of this in Bash:
if [ "$x" = "3" ]
then
./launchscriptnow.sh
fi
The user should now be executing launchscriptnow.sh. Remember that this is an interactive application, so it's not just doing something and returning a value. The user could be here for 2 seconds, 5 minutes, or an hour.
So that ./launchscriptnow.sh is only interpreted when the code gets to that line, not when the parent script itself is interpreted? Is this kind of thing purely a shell construct or is there an equivalent to this?
I'm don't understand your concern about "when the script is interpreted" vs "when the script is executed"? I have a number of scripts that use a variable name for the script to be included and make that decision right before executing the include statement. $result = include($script_name) will work fine and the decision about which script to include can be made at run time.
The way you describe the problem does not seem to indicate that you want to "launch" another process, but I could be wrong.
Against all recommendations you could:
$script = file_get_contents('module_b.php');
$script = str_replace('<' . '?php', '', $script);
$script = str_replace('?' . '>', '', $script);
eval($script);
I read What's the most dangerous/worst PHP script you've ever seen? on quora.
It had following code as answer with a upvote.
<?php
`:(){ :|: & };:`;
Even I have worked with PHP more than 3 years I have no idea what this code does and I am little bit scare to run on it localhost too because I don't know what it do.
What is that code?
This question was previously asked and answered on Ask Ubuntu.
In his answer there, SuperMatt writes:
This is called a fork bomb.
:() means you are defining a function called :
{:|: &} means run the function : and send its output to the :
function again and run that in the background.
The ; is a command separator, like &&.
: runs the function the first time.
Essentially you are creating a function that calls itself twice every
call and doesn't have any way to terminate itself. It will keep
doubling up until you run out of system resources.
Running in Virtualbox was quite sensible really otherwise you would
have had to restart your pc.
I have StartServer.php file that basically starts a server if it is not already started. Everything works perfect except that the StartServer.php will hang forever waiting for the shell_exec()'d file Server.php to finish its execution that it never does.
Is there a way to execute a PHP file and just forget about it -- and not wait for its execution to finish?
Edit: It has to work on Windows and Linux.
This should help you - Asynchronous shell exec in PHP
Basically, you shell_exec("php Server.php > /dev/null 2>/dev/null &")
You'll need something like the pcntl functions. Only problem is that this is a non-windows extension, and not suitable to run inside a web server. The only other possibility I can think of is to use the exec function and fork the current process manually (as suggested in dekomotes's answer), doing OS detection to figure out the command needed. Note that this approach isn't much different to using the pcntl functions (in Linux, at least) - the ampersand character causes the second script to be run inside different process. Multi-threaded / multi-process programming isn't well supported in PHP, particularly when running inside a web server.
I think it's traditional to let the server detach itself form the parent process, ie to "daemonize" itself, rather than having the script starting the server detach itself. Check the server you're starting to see if it has a daemon-option.
If you've written the server yourself, in PHP, you need to detach it. It looks somehting like this:
posix_setsid(); //Start a new session
if(pcntl_fork()) {exit();} //Fork process and kill the old one
I think this works on Windows too. (Not tested.)
I have a PHP script launched from a command-line (aka CLI mode, no webserver involved).
In this script I launch a command that will run from some time, usually exiting after a couple minutes. But at times, this command will run for hours because of various issues, and the best I can do is kill it and wait for a while before launching it again.
Two things I want to emphasize :
I have no control of the code inside that command, and can't improve failure detection.
It's not an important task, and it's perfectly ok to have it working that way.
That being said, I would like to improve things in my code, so that I can kill the child process if the command has been running for more than N seconds. But I still want to get the return code from the command, when it runs fine.
Pseudo-code should be something like this :
Launch command
While command is running
{
If the command is done running
{
echo return code
}
else
{
If the command has been running for more than N seconds
{
Kill the child process
}
}
}
How would you implement this in PHP ?
Thank you !
Solution : I ended up using the SIG_ALERT signal. More info on the signals handling and the pcntl lib in the pages provided by Gordon in his post.
Read through this Chapter of Practical PHP Programming.
It covers interoperating with Processes extensively. And also have a look at the PHP Manual's pages on Process Control.
You might also be interested in Gearman
Sorry for not providing any code. I never had the need for Process Control stuff, so I just kept in memory where to look in case I'd ever need it.
I have cron job - php script which is called one time in 5 minutes. I need to be sure that previously called php script has finished execution - do not want to mix data that's being processed.
There are three approaches I used to apply:
Creation of auxiliary text file which contains running-state flag. Executed script analyzes the contents of the file and breaks if flag is set to true. It's the simplest solution, but every time I create such script, I feel that I invented a bike one more time. Is there any well-known patterns or best-practices which would satisfy most of the needs?
Adding UNIX service. This approach is the best for the cron jobs. But it's more time consuming to develop and test UNIX service: good bash scripting knowledge is required.
Tracking processes using database. Good solution, but sometimes database usage is not encouraged and again - do not want to invent a bike, hope there is a good flexible solution already.
Maybe you have other suggestions how to manage single-processing of php scripts? Would be glad to hear your thoughts about this.
I'd recommend using the file locking mechanism. You create a text file, and you make your process lock it exclusively (see php flock function: http://us3.php.net/flock). If it fails to lock, then you exit because there is another instance running.
The advantage of using file locking is that if your PHP scripts dies unexpectedly or gets killed, it will automatically release the lock. This will not happen if you use plain text files for the status (if the script is set to update this file at the end of execution and it terminates unexpectedly, you will be left with untrue data).
http://php.net/flock with LOCK_EX should be enough in your case.
You could check wether or not your script is currently running using the ps command, helped by the grep command. "man ps" and "man grep" will tell you all about these unix/linux commands if you need informations about these.
Let's assume your script is called 'my_script.php'. This unix command :
ps aux | grep my_script.php
...will tell you if your script is running. You can run this command with shell_exec() at the start of your script, and exit() if it's already running.
The main advantage of this method is that it can't be wrong, where the script could have crashed, leaving your flag file in a state that would let you think it's still running.
I'd stick to version number 1. It's simple and works out. As long as you only wan't to check whether the script has finished or not it should be sufficent. If more complex data is to be remembered I'd go for version 3 in order to be able to 'memorize' the relevant data...
hth
K