There is a PHP script on the server which runs about 20 - 30 seconds depending on the size of the file it's working on.
To stop the running instance when a new one ist started I change a session variable. Within the work loop in the script I am checking if this session variable has changed to stop the execution. And this does not work out. Why is this ?
Basically I am starting the session first:
session_start();
Then I generate a random number, assing this to an instance variable, kill the belonging session variable and assign the generated number to that session variable:
$this->number = rand();
unset( $_SESSION[ 'number' ] );
$_SESSION[ 'number' ] = $this->number;
Within the loop I let this $_SESSION[ 'number' ]
being checked for a change which should appear when a new script instance is started:
for( $i = 0 to 1.000.000 ){
$s = $_SESSION[ 'number' ];
if( $this->number !== $s ){
die();
}
So let's say:
script1 starts the session, stores 1 in $_SESSION[ 'number' ]
and checks changes to $_SESSION[ 'number' ]
to die while looping.
script2 starts and stores 2 in $_SESSION[ 'number' ]
At that moment script1 should get aware of this change and stop working
what is does NOT.
Please be so kind and tell me why this does not work out, as I let the script echo the actual $_SESSION[ 'number' ]
on start and see that the see the number generated from the script started before, being changed the by the last started instance.
CodePudding user response:
Changes you are making to the global $_SESSION
will not propagate across different scripts which are already running....
From the definition:
An associative array containing session variables available to the current script
The session is unique to the current running script and its basically an array which is populated when the code is loaded - Even if you are using the same session for multiple scripts they will have a copy of the current values when called. Changes to the stored session values will not reflect unless you re-run the script.
You need to implement another mechanism to "signal" across scripts.
The best ways are (my opinion):
- pcntl_signal
- posix_kill
- DB based stored value which is accessed by the running scripts.
CodePudding user response:
Meanwhile I tried the following:
pcntl signal - The server did not react at all even the pcntl functionality should be included in the webhosting package. I will have to investigate this.
websockets - I tried very simple solutions which endet all in the javascript reporting that no connection could be established. I refer this to the nature of the shared hosting package I am using.
PHP semaphore functions:
https://www.php.net/manual/en/ref.sem.php
msg_send / msg_receive - This showed up to be unfitting because within this php message system the messages are being consumed when read which means a sharing between all running instances of the php script is impossible because the first script reading a message pulls/ deletes it from the stack.
SOLUTION:
Now I am using a Fetch- native object called AbortController
https://javascript.info/fetch-abort
It works, not as fast as I would like it to, yet it works. It aborts asynchronous tasks.
For now this will do..
I will lay an eye on posix_kill. I avoided the db solution as it would produce thousands of thousands of db requests for every user if used in the script loop ( even if used by a timered approach )
Thanks to: @Honk der Hase and @Shlomi Hassid