-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First stab at implementing asynchronously pushed-back task results
The general idea is to not keep workers waiting for tasks that may take a while to complete. Things like backups and upgrades may take the client a minute to process - the worker does not need to sit idle during that time; it might as well process other tasks simultaniously. Flow: 1. Worker pushes the task to the client, with a uri and one-time signing key 2. Client acknowledges receipt and support for the async return push with a 202 3. Worker marks task as awaiting async response and continues to whatever other tasks are queued 4. Client processes slow task, and when done pushes the response to the sitedash endpoint from (1). Endpoint stores received data, marks related job exec as having received data to process. 5. Same worker (when free) is assigned again to job exec and finishes processing the data
- Loading branch information
Showing
5 changed files
with
174 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
core/components/sitedashclient/src/Communication/Pusher.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
<?php | ||
|
||
namespace modmore\SiteDashClient\Communication; | ||
|
||
final class Pusher { | ||
private $responseUri; | ||
private $signingKey; | ||
|
||
public function __construct($server, $responseUri, $signingKey) | ||
{ | ||
$this->responseUri = $server . $responseUri; | ||
$this->signingKey = base64_decode($signingKey); | ||
} | ||
|
||
public function acknowledge() | ||
{ | ||
ob_start(); | ||
|
||
echo json_encode([ | ||
'return_push' => true, | ||
]); | ||
|
||
// Get the size of the output. | ||
$size = ob_get_length(); | ||
|
||
// 202 accepted | ||
http_response_code(202); | ||
|
||
// Disable compression (in case content length is compressed). | ||
header('Content-Encoding: none'); | ||
|
||
// Set the content length of the response. | ||
header("Content-Length: {$size}"); | ||
|
||
// Close the connection. | ||
header('Connection: close'); | ||
|
||
// Flush all output. | ||
ob_end_flush(); | ||
ob_flush(); | ||
flush(); | ||
|
||
ignore_user_abort(true); | ||
@session_write_close(); | ||
|
||
if (is_callable('fastcgi_finish_request')) { | ||
fastcgi_finish_request(); | ||
return; | ||
} | ||
sleep(1); | ||
} | ||
|
||
public function push(array $data) | ||
{ | ||
$logFile = MODX_CORE_PATH . 'cache/logs/sitedash_push_' . date('Y-m-d-H-i-s') . '.log'; | ||
|
||
$ch = curl_init(); | ||
|
||
$postData = $this->prepareData($data); | ||
curl_setopt($ch, CURLOPT_URL, $this->responseUri); | ||
curl_setopt($ch, CURLOPT_POST, true); | ||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData)); | ||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); | ||
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']); | ||
|
||
$response = curl_exec($ch); | ||
$error = curl_error($ch); | ||
$errno = curl_errno($ch); | ||
curl_close($ch); | ||
|
||
$dataFormat = json_encode($data, JSON_PRETTY_PRINT); | ||
$postDataFormat = json_encode($postData, JSON_PRETTY_PRINT); | ||
$log = <<<HTML | ||
Push requested to {$this->responseUri} with one-time use signing key: | ||
{$this->signingKey} | ||
Data: {$dataFormat} | ||
Data to post to SiteDash, incl signature: {$postDataFormat} | ||
Response from SiteDash: {$errno} {$error} | ||
{$response} | ||
HTML; | ||
|
||
file_put_contents($logFile, $log); | ||
} | ||
|
||
private function prepareData(array $data) | ||
{ | ||
return [ | ||
'data' => $data, | ||
'signature' => $this->sign($data), | ||
]; | ||
} | ||
|
||
private function sign(array $data) | ||
{ | ||
$sigData = json_encode($data); | ||
|
||
$binary_signature = ''; | ||
openssl_sign($sigData, $binary_signature, $this->signingKey, OPENSSL_ALGO_SHA1); | ||
|
||
// Encode it as base64 | ||
$binary_signature = base64_encode($binary_signature); | ||
return $binary_signature; | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
core/components/sitedashclient/src/Communication/Result.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?php | ||
|
||
namespace modmore\SiteDashClient\Communication; | ||
|
||
final class Result { | ||
/** | ||
* @var Pusher|null | ||
*/ | ||
private $pusher; | ||
|
||
public function __construct(Pusher $pusher = null) | ||
{ | ||
$this->pusher = $pusher; | ||
} | ||
|
||
public function __invoke($responseCode, $data) | ||
{ | ||
if ($this->pusher) { | ||
$this->pusher->push($data); | ||
} | ||
else { | ||
http_response_code($responseCode); | ||
echo json_encode($data, JSON_PRETTY_PRINT); | ||
@session_write_close(); | ||
exit(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters