I developed a way to make async tasks with PHP and it's working very well, until now.
The logic based in 3 extensions PCNTL, POSIX e Semaphore.
To have a full control of the master process and child process I must share the status of the task and the PID between them. These 2 variables are shared using shm_attach, the fork uses pcntl_fork.
The problem described in the title of this questions is related to the status of the task and the PID between them. These 2 variables are shared using shm_attach method because there is no more space available to share create a shared memory.
I use it for 2 moments: At constructor to create the shared memory
<?php
//...
final public function __construct() {
self::$shmId = shm_attach((int) (ftok(self::$file, 'A') . self::$line), self::SHARED_MEMORY_SIZE);
$this->var_key_pid = $this->alocatesharedMemory(getmypid(), 112112105100); //112112105100;
$this->var_key_status = $this->alocatesharedMemory('PENDING', 11511697116117115); //11511697116117115;
}
And on the run
method after forking the process
<?php
final public function run($parameters) {
//...
} else { //Frok process
ignore_user_abort(); //I dont know why but must be set again.
$sid = posix_setsid();
self::$shmId = shm_attach((int) (ftok(self::$file, 'A') . self::$line), self::SHARED_MEMORY_SIZE);
NOTE: The code is a little extensive and I put it into a gist https://gist.github.com/LeonanCarvalho/62c6fe0b62db8a478f502f84c5734c83
I think I'm doing something wrong because even though I'm using shm_detach and shm_remove the process sometimes returns the error PHP Warning: "shm_attach" failed for key No space left on the device in when I try to attach a new shared memory.
It is happening because some shared memory is detached and not removed from Shared memory segments, its the result of command ipcs -m
:
The tasks are running for months before start doing this, so the one way to work around this problem I removed all shared memory identifiers with the command
ipcrm --all=shm
But I think it's silently growing and for sure it going to happen again.
How to prevent it?
I think the process may be leaking memory due to objects being created and not destroyed inside the process' memory. one way you can analise this is by reviewing the process' memory usage and which queries are being sent, that may be causing this problem, if you can reproduce the creation and leakage of memory, then it should be possible to figure out a way to delete the created objects. this may be happening due to cursors left open among other factors. Have you considered using RabbitMQ for the async PHP tasks?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With