Press 'c' to toggle code style
Press 's' for speaker notes
4GB / 128 MB = 32 requests
Form 1
Submit form
|
Form 2
Submit form
|
CVE-2019-11037 - my bad
push graphic-context
viewbox 0 0 640 480
fill 'url(https://example.com/image.jpg"|ls "-la)'
pop graphic-context
// Upload as .mvg file
Redis, Gearman, RabbitMQ, Amazon SQS
class ImageJob {
/** @var string */
private $text;
function __construct(string $text) {
$this->text = $text;
}
public function toString(): string {
$data = ['text' => $this->text];
return json_encode_safe($data);
}
public function getText(): string {
return $this->text;
}
public static function fromString(string $string) {
$data = json_decode_safe($string);
return new self($data['text']);
}
}
class RedisImageJobRepo {
public function queueImageJob(ImageJob $imageJob)
{
$this->redis->rpush(
ImageJobKey::getAbsoluteKeyName(),
$imageJob->toString()
);
return true;
}
}
class RedisImageJobRepo
{
function waitForImageJob(int $timeout = 5): ?ImageJob {
$key = ImageJobKey::getAbsoluteKeyName();
// Next line sits and waits for a job
$listElement = $this->redis->blpop([$key], $timeout);
if (count($listElement) === 0) {
return null;
}
$keyReturned = $listElement[0];
$data = $listElement[1];
$imageJob = ImageJob::fromString($data);
return $imageJob;
}
}
class ImageJobKey {
static function getAbsoluteKeyName() : string {
return str_replace('\\', '', __CLASS__);
}
static function getKeyNameForStatus(string $jobId): string {
return str_replace('\\', '', __CLASS__) .
':status:' . $jobId;
}
}
[program:image_generator]
directory=/var/www
command=php cli.php process:image_example
process_name=%(program_name)s_%(process_num)d
user=www-data
numprocs=1
autostart=true
autorestart=true
# also boring log file stuff...
|
|
Actually, no.
256 workers
* 8 business hours a day
* 5 days a week
* 4 weeks a month
* 3600 seconds in an hour
/ 4 seconds to send an email
= 36,864,000 emails a month
function continuallyExecuteCallable($callable, int $maxRunTime)
{
$startTime = microtime(true);
while (true) {
$callable();
if (checkSignalsForExit()) {
break;
}
if ((microtime(true) - $startTime) > $maxRunTime) {
break;
}
}
}
aka listen to signals.
“Upon the receival of the SIGTERM, each container should start a graceful shutdown of the running application and exit.” “If a container doesn’t terminate within the grace period, a SIGKILL signal will be sent and the container violently terminated.”
function checkSignalsForExit()
{
static $initialised = false;
static $needToExit = false;
if ($initialised === false) {
$fnSignalHandler = function ($signalNumber) use (&$needToExit) {
$needToExit = true;
};
pcntl_signal(SIGINT, $fnSignalHandler, false);
pcntl_signal(SIGKILL, $fnSignalHandler, false);
pcntl_signal(SIGQUIT, $fnSignalHandler, false);
pcntl_signal(SIGTERM, $fnSignalHandler, false);
pcntl_signal(SIGHUP, $fnSignalHandler, false);
pcntl_signal(SIGUSR1, $fnSignalHandler, false);
$initialised = true;
}
pcntl_signal_dispatch();
return $needToExit;
}
https://joind.in/talk/e99f1
https://github.com/Danack/example
Twitter: @MrDanack
Some things that need to be processed in an web based application can take a long time to run. Moving this work to be done in a background worker can provide lots of benefits for the user and make your life easier as a developer. Dan's going to talk about this stuff, going through exactly what the problems are, how to implement background workers, and the diverse benefits they give.