patternphpMinor
Simple One Way IPC Implementation for pcntl_fork
Viewed 0 times
simplepcntl_forkwayoneipcforimplementation
Problem
It is a common task for me to need to run many nearly identical child processes. Not often but sometimes I need those child processes to communicate their results back to the parent process. I have created the following implementation to avoid boiler plate
I will in line my questions with the relative components.
1) Is the
2) Is there a preferred way to initialize class members in PHP? default arguments to the constructor, initialize the variables when they are declared or initialize in the constructor?
3) Should I be using
```
class IPC {
// indented properly in the file, just trying to avoid horizontal scroll
private $pWorker, $cWorkers, $maxChildren, $maxWaitTime;
function __construct(ParentWorker $pWorker, array / ChildWorker / $cWorkers) {
$this->pWorker = $pWorker;
$this->cWorkers = $cWorkers;
$this->maxChildren = 0;
$this->maxWaitT
pcntl_fork() calls, and standardize the client code.I will in line my questions with the relative components.
<?php namespace robbmj;
/* The MIT License (MIT) */
interface ChildWorker {
/**
* produce must return a string
*/
function produce();
}
interface ParentWorker {
/**
* $input will always be a string
*/
function consume($input);
}1) Is the
SocketPair class over engineering, I could easily just use an array?2) Is there a preferred way to initialize class members in PHP? default arguments to the constructor, initialize the variables when they are declared or initialize in the constructor?
class SocketPair {
private $clientSock, $serverSock, $createTime;
function __construct($clientSock, $serverSock, $createTime = null) {
$this->clientSock = $clientSock;
$this->serverSock = $serverSock;
$this->createTime = isset($createTime) ? $createTime : time();
}
function passedAllotedTime($allotedTime) {
return $this->createTime + $allotedTime clientSock;
}
function serverSock() {
return $this->serverSock;
}
function closeClient() {
socket_close($this->clientSock);
}
function closeServer() {
socket_close($this->serverSock);
}
}3) Should I be using
bean style method names setMaxChildren instead maxChildren? ```
class IPC {
// indented properly in the file, just trying to avoid horizontal scroll
private $pWorker, $cWorkers, $maxChildren, $maxWaitTime;
function __construct(ParentWorker $pWorker, array / ChildWorker / $cWorkers) {
$this->pWorker = $pWorker;
$this->cWorkers = $cWorkers;
$this->maxChildren = 0;
$this->maxWaitT
Solution
1) Is the SocketPair class over engineering, I could easily just use an array?
It's not over-engineering, it's actually a really good idea.
An array is too generic,
for example you would need additional checks to ensure size == 2.
Using a dedicated object is explicit and clear, definitely a good thing.
2) Is there a preferred way to initialize class members in PHP? default arguments to the constructor, initialize the variables when they are declared or initialize in the constructor?
I don't know PHP well enough, but I would guess it's a matter of personal preference.
I prefer to initialize in the constructor,
as it makes future extensions easier:
Both of these will involve less typing and rewriting if I initialize in the constructor rather than at declaration.
In any case, it doesn't make much difference either way.
You can simplify this:
If you have PHP >= 5.3, this is easier:
3) Should I be using bean style method names setMaxChildren instead maxChildren?
I think that's a matter of taste. I prefer
4) Should the start method be reporting errors to the caller? Or would that be an example of a leaked implementation detail?
You're probably talking about the
Yeah that won't help anyone:
doesn't give a chance to caller to recover gracefully, or log and print a helpful error message.
It would be better to raise an exception.
To avoid leaking implementation detail you can use a custom exception,
using a vocabulary that's appropriate for the level of abstraction and not revealing implementation details.
6) Should I be trimming the output of $cWorker->produce()
A well-behaving
rather forcing each of its callers to remember and do it.
Add to the interface documentation that the method should returned strings that don't need trimming.
7) Should this makeSocketPair be static, should it be moved to the SocketPair?
it contains a pair.
Moving this logic there would be an additional responsibility.
Maybe a static method in a
Is that line in the middle inserted between the operations on
// Sarcastic comment: ☑ ;-)
And this review wouldn't be complete without a picture of a unicorn:
It's not over-engineering, it's actually a really good idea.
An array is too generic,
for example you would need additional checks to ensure size == 2.
Using a dedicated object is explicit and clear, definitely a good thing.
2) Is there a preferred way to initialize class members in PHP? default arguments to the constructor, initialize the variables when they are declared or initialize in the constructor?
I don't know PHP well enough, but I would guess it's a matter of personal preference.
I prefer to initialize in the constructor,
as it makes future extensions easier:
- adding another constructor later
- adding factory methods later
Both of these will involve less typing and rewriting if I initialize in the constructor rather than at declaration.
In any case, it doesn't make much difference either way.
You can simplify this:
$this->createTime = isset($createTime) ? $createTime : time();If you have PHP >= 5.3, this is easier:
$this->createTime = $createTime ?: time();3) Should I be using bean style method names setMaxChildren instead maxChildren?
I think that's a matter of taste. I prefer
get / set to make the intention explicit.4) Should the start method be reporting errors to the caller? Or would that be an example of a leaked implementation detail?
You're probably talking about the
exit(0); in the middle.Yeah that won't help anyone:
doesn't give a chance to caller to recover gracefully, or log and print a helpful error message.
It would be better to raise an exception.
To avoid leaking implementation detail you can use a custom exception,
using a vocabulary that's appropriate for the level of abstraction and not revealing implementation details.
6) Should I be trimming the output of $cWorker->produce()
A well-behaving
$cWorker->produce() should do the trimming itself,rather forcing each of its callers to remember and do it.
Add to the interface documentation that the method should returned strings that don't need trimming.
7) Should this makeSocketPair be static, should it be moved to the SocketPair?
SocketPair has a single responsibility now:it contains a pair.
Moving this logic there would be an additional responsibility.
Maybe a static method in a
SocketPairFactory class would be better.$output = $cWorker->produce();
socket_set_nonblock($socketPair->serverSock());
$output = ($output) ? trim($output) : '';Is that line in the middle inserted between the operations on
$output just to confuse readers and make them wonder if socket_set_nonblock might magically have some impact on $output?// Sarcastic comment: ☑ ;-)
And this review wouldn't be complete without a picture of a unicorn:
Code Snippets
$this->createTime = isset($createTime) ? $createTime : time();$this->createTime = $createTime ?: time();$output = $cWorker->produce();
socket_set_nonblock($socketPair->serverSock());
$output = ($output) ? trim($output) : '';Context
StackExchange Code Review Q#70636, answer score: 2
Revisions (0)
No revisions yet.