Comments (13)
Multiple processes still work. It just spawns child processes. Why is pcntl important to you?
from parallel.
You can use the new Process
API instead. It launches a completely separate PHP process, free of any state that may have been forked from the parent.
Prior you might have had code like this:
$fork = Fork::spawn(function () {
// $this bound to an instance of Channel.
// Do blocking things.
return $result;
});
$result = yield $fork->join();
In 0.2.x you write the code for the child process in a separate PHP file.
<?php // child.php
// You don't have to use $argc or $argv, just showing they're available.
return function (Channel $channel) use ($argc, $argv) {
// Use the instance of Channel provided as first argument.
// Do blocking things.
return $result;
}
// parent.php
$process = Process::run(__DIR__ . "/child.php");
$result = yield $process->join();
I would also have a look at the Task
and Worker::enqueue()
API, as this may fit your needs and make writing your code even simpler.
Also check out the examples directory, particularly the process.php example that runs the code in blocking-process.php. You'll also find some simple examples using workers in that directory.
@soullivaneuh If you have further usage questions don't hesitate to ask, especially since I haven't written any formal docs for this library yet.
from parallel.
Why is pcntl important to you?
@kelunik Because I can't install pthread on my server, this is the only solution so far.
But I'll try @trowski sample.
from parallel.
BTW @trowski, here is my full usage:
$serviceResult = null;
Loop::run(function () use ($containerId, &$serviceResult, $sizeProcess, $currentSize) {
$waitContext = Fork::spawn(function (ContainerManager $containerManager, string $containerId) {
$waitResult = $containerManager->wait($containerId);
return $waitResult->getStatusCode();
}, $this->docker->getContainerManager(), $containerId);
$timer = Loop::repeat(
1000,
function () use ($waitContext, &$serviceResult, $containerId, $sizeProcess, $currentSize): void {
if ((int) $sizeProcess->clearOutput()->mustRun()->getOutput() - $currentSize
> static::MAX_SPACE_USAGE) {
$this->docker->getContainerManager()->kill($containerId);
$waitContext->kill();
$serviceResult = 'Suspicious huge file writing detected.';
Loop::stop();
}
}
);
$delayer = Loop::delay(
static::SERVICE_TIMEOUT * 1000,
function () use ($waitContext, &$serviceResult, $containerId): void {
$this->docker->getContainerManager()->kill($containerId);
$waitContext->kill();
$serviceResult = 'Timeout of '.static::SERVICE_TIMEOUT.' seconds reached.';
Loop::stop();
}
);
try {
$serviceResult = yield $waitContext->join();
} finally {
$waitContext->kill();
Loop::cancel($timer);
Loop::cancel($delayer);
}
});
In a nutshell, I run a docker api command under a child process to be able to look at the execution time and disk space usage.
Will your example fit with my need according to you?
from parallel.
@soullivaneuh pthreads isn't the only alternative to forking, the default was and still is multiple processes if pthreads isn't available, see:
parallel/lib/Worker/DefaultWorkerFactory.php
Lines 42 to 52 in 0d40e6d
You don't need pthreads for amphp/parallel
.
from parallel.
In 0.2.x you write the code for the child process in a separate PHP file.
@trowski This is wrong for my case, my code is under an anonymous function as described in #33 (comment)
@kelunik Thanks for the help but it's hard to understand. What change should I do on my current code to make this working?
from parallel.
Something like the following should work. If $containerManager
is serializeable, you can also send it via the channel.
Parent
$serviceResult = null;
Loop::run(function () use ($containerId, &$serviceResult, $sizeProcess, $currentSize) {
$waitContext = Process::run(__DIR__ . "/child.php");
$waitContext->send($containerId);
$timer = Loop::repeat(
1000,
function () use ($waitContext, &$serviceResult, $containerId, $sizeProcess, $currentSize): void {
if ((int) $sizeProcess->clearOutput()->mustRun()->getOutput() - $currentSize
> static::MAX_SPACE_USAGE) {
$this->docker->getContainerManager()->kill($containerId);
$waitContext->kill();
$serviceResult = 'Suspicious huge file writing detected.';
Loop::stop();
}
}
);
$delayer = Loop::delay(
static::SERVICE_TIMEOUT * 1000,
function () use ($waitContext, &$serviceResult, $containerId): void {
$this->docker->getContainerManager()->kill($containerId);
$waitContext->kill();
$serviceResult = 'Timeout of '.static::SERVICE_TIMEOUT.' seconds reached.';
Loop::stop();
}
);
try {
$serviceResult = yield $waitContext->join();
} finally {
$waitContext->kill();
Loop::cancel($timer);
Loop::cancel($delayer);
}
});
Child
return function (Amp\Parallel\Sync\Channel $channel) {
// Create $containerManager here
$containerId = yield $channel->receive();
$waitResult = $containerManager->wait($containerId);
return $waitResult->getStatusCode();
};
from parallel.
@kelunik This might work. But what if the container manager throws an exception on the child process? Will it be thrown to the parent?
from parallel.
It won't throw the same exception, but throw a TaskException
instead, as exceptions can't be serialized.
from parallel.
I finally found a way withou parallel:
Loop::run(function () use ($containerId, &$serviceResult, $sizeProcess, $currentSize): void {
$delayer = Loop::delay(
static::SERVICE_TIMEOUT * 1000,
function () use (&$serviceResult, $containerId): void {
$this->docker->getContainerManager()->kill($containerId);
$serviceResult = 'Timeout of '.static::SERVICE_TIMEOUT.' seconds reached.';
Loop::stop();
}
);
Loop::repeat(
1000,
function ($timer) use (&$serviceResult, $containerId, $sizeProcess, $currentSize, $delayer): void {
$running = $this->docker->getContainerManager()->find($containerId)->getState()->getRunning();
$this->logger->info('Docker running state update', [
'running' => $running,
]);
if (!$running) {
$serviceResult = $this->docker->getContainerManager()->find($containerId)->getState()->getExitCode();
Loop::cancel($timer);
Loop::cancel($delayer);
Loop::stop();
}
if ((int) $sizeProcess->clearOutput()->mustRun()->getOutput() - $currentSize
> static::MAX_SPACE_USAGE) {
$this->docker->getContainerManager()->kill($containerId);
$serviceResult = 'Suspicious huge file writing detected.';
Loop::cancel($timer);
Loop::cancel($delayer);
Loop::stop();
}
}
);
});
But I'm note sure of my loop usage. What do you think?
from parallel.
What worries you?
from parallel.
I'm going to close this, as the question seems to be answered. If you have further questions or input, please respond so we can reopen or open new issues for unrelated questions.
from parallel.
@kelunik Sorry for the long delay. I finally managed my need without the loop and parallel system.
from parallel.
Related Issues (20)
- amphp/parallel + ssh2 HOT 6
- Is there a way to output the STDOUT of the child process to STDOUT of the parent process? HOT 4
- The nested use of pools HOT 1
- Measure the running time of a thread HOT 1
- Performance degradation in v2.2.0 HOT 18
- Parallel task(s) keep on running since v2.2 HOT 3
- Awaiting multiple channels HOT 7
- Migrate from parallel-function HOT 3
- Sock files are piling up in tmp folder. They are not getting cleared up automatically. HOT 1
- Under XAMPP 8.2.4 the first example program freeze HOT 2
- Expected a valid stream HOT 6
- How to await for tasks in progress? HOT 2
- Do I need to use "readonly" in "FetchTask.php" when "main.php" contains several "$urls" in my case ??? HOT 1
- Hang when using ext-uv and JIT HOT 4
- Dealing with Zombies processes HOT 5
- Parcel (or analog) to data exchange between Parent and Child processes HOT 1
- communication between parallel worker HOT 1
- The pool was shut down HOT 3
- Forwarding User Interaction and Feedback in CLI app HOT 1
- Queue-based pool HOT 8
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from parallel.