Skip to content

Commit

Permalink
Defer text message sends until FastCGI response is sent for real calls
Browse files Browse the repository at this point in the history
Not deferring dummy calls because we can't tell that they were made if
we do so, as error_logs don't get piped back to nginx after finishing
the response.
  • Loading branch information
iansltx committed Sep 12, 2018
1 parent 0a6e320 commit b8249a1
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 5 deletions.
36 changes: 32 additions & 4 deletions bootstrap/services.php
Expand Up @@ -131,6 +131,28 @@ public function isAuthorized(Request $req, $id) {
}
}

class TaskQueue implements Countable
{
protected $tasks = [];

public function push($task)
{
$this->tasks[] = $task;
}

public function count()
{
return count($this->tasks);
}

public function __invoke()
{
foreach ($this->tasks as $task) {
$task();
}
}
}

return function(\Slim\Container $container, $env) {
$container['view'] = function() {return new View(__DIR__ . '/../templates');};
$container['raffleService'] = function($c) use ($env) {return new RaffleService(
Expand All @@ -139,17 +161,23 @@ public function isAuthorized(Request $req, $id) {
);};
$container['auth'] = function(\Slim\Container $c) {return new Auth($c->get('raffleService'));};

$container['sms'] = function() use ($env) {
$container['taskQueue'] = function() { return new TaskQueue(); };

$container['sms'] = function($c) use ($env) {
if (isset($env['DUMMY_SMS_WAIT_MS'])) { // not deferring because error_log is turned off after fcgi disconnects
return new DummySMS($env['DUMMY_SMS_WAIT_MS']);
}

return new DeferredSMS((function($env) : SMS
{
if (isset($env['TWILIO_SID'])) {
return new TwilioSMS($env['TWILIO_SID'], $env['TWILIO_TOKEN'], $env['PHONE_NUMBER']);
}
if (isset($env['NEXMO_KEY'])) {
return new NexmoSMS($env['NEXMO_KEY'], $env['NEXMO_SECRET'], $env['PHONE_NUMBER']);
}
if (isset($env['DUMMY_SMS_WAIT_MS'])) {
return new DummySMS($env['DUMMY_SMS_WAIT_MS']);
}
throw new InvalidArgumentException('Could not find SMS service creds, and a dummy timeout was not supplied.');
})($env), $c['taskQueue']);
};

$container['addCookieToResponse'] = $container->protect(function(Response $res, $name, $properties) {
Expand Down
19 changes: 19 additions & 0 deletions bootstrap/smsServices.php
Expand Up @@ -5,6 +5,25 @@ interface SMS
public function send($to, $text);
}

class DeferredSMS implements SMS
{
protected $actual;
protected $queue;

public function __construct(SMS $actual, TaskQueue $queue)
{
$this->actual = $actual;
$this->queue = $queue;
}

public function send($to, $text)
{
$this->queue->push(function() use ($to, $text) {
$this->actual->send($to, $text);
});
}
}

class TwilioSMS implements SMS
{
protected $sid;
Expand Down
7 changes: 6 additions & 1 deletion public/index.php
Expand Up @@ -3,7 +3,12 @@
require __DIR__ . '/../vendor/autoload.php';

$app = new \Slim\App();
call_user_func(require __DIR__ . '/../bootstrap/services.php', $app->getContainer(), $_SERVER + $_ENV);
call_user_func(require __DIR__ . '/../bootstrap/services.php', $container = $app->getContainer(), $_SERVER + $_ENV);
call_user_func(require __DIR__ . '/../bootstrap/routes.php', $app);

$app->run();

if (count($queuedTasks = $container->get('taskQueue'))) {
fastcgi_finish_request();
$queuedTasks();
}

0 comments on commit b8249a1

Please sign in to comment.