-
-
Notifications
You must be signed in to change notification settings - Fork 289
Implementation of aws SQS #134
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
a54d754
c6d0999
f7af7d6
f577bc1
98129b4
55caefe
cc97769
d0cdc27
d581070
ff2ddc5
4d92521
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| <?php | ||
| /** | ||
| * @link http://www.yiiframework.com/ | ||
| * @copyright Copyright (c) 2008 Yii Software LLC | ||
| * @license http://www.yiiframework.com/license/ | ||
| */ | ||
|
|
||
| namespace yii\queue\sqs; | ||
|
|
||
| use yii\queue\cli\Command as CliCommand; | ||
|
|
||
| /** | ||
| * Manages application aws sqs-queue. | ||
| * | ||
| * @author Manoj Malviya <manojm@girnarsoft.com> | ||
| */ | ||
| class Command extends CliCommand | ||
| { | ||
| /** | ||
| * @var Queue | ||
| */ | ||
| public $queue; | ||
|
|
||
| /** | ||
| * Runs all jobs from sqs. | ||
| * It can be used as cron job. | ||
| */ | ||
| public function actionRun() | ||
| { | ||
| $this->queue->run(); | ||
| } | ||
|
|
||
| /** | ||
| * Listens sqs and runs new jobs. | ||
| * It can be used as demon process. | ||
| */ | ||
| public function actionListen() | ||
| { | ||
| $this->queue->listen(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,206 @@ | ||||
| <?php | ||||
|
|
||||
| namespace yii\queue\sqs; | ||||
|
|
||||
| use yii\base\NotSupportedException; | ||||
| use yii\queue\cli\Queue as CliQueue; | ||||
| use yii\queue\cli\Signal; | ||||
| use \Aws\Sqs\SqsClient; | ||||
| use Aws\Credentials\CredentialProvider; | ||||
|
|
||||
| /** | ||||
| * SQS Queue | ||||
| * | ||||
| * @author Manoj Malviya <manojm@girnarsoft.com> | ||||
| */ | ||||
| class Queue extends CliQueue | ||||
| { | ||||
| /** | ||||
| * @var SqsClient | ||||
| */ | ||||
| private $_client; | ||||
|
|
||||
| /** | ||||
| * The SQS url. | ||||
| * @var string | ||||
| */ | ||||
| public $url; | ||||
|
|
||||
| /** | ||||
| * aws access key | ||||
| * @var string | ||||
| */ | ||||
| public $key = ''; | ||||
|
|
||||
| /** | ||||
| * aws secret | ||||
| * @var string | ||||
| */ | ||||
| public $secret = ''; | ||||
|
|
||||
| /** | ||||
| * region where queue is hosted. | ||||
| * @var string | ||||
| */ | ||||
| public $region = ''; | ||||
|
|
||||
| /** | ||||
| * API version | ||||
| * @var string | ||||
| */ | ||||
| public $version = 'latest'; | ||||
|
|
||||
| /** | ||||
| * @var string command class name | ||||
| */ | ||||
| public $commandClass = Command::class; | ||||
|
|
||||
| /** | ||||
| * @inheritdoc | ||||
| */ | ||||
| public function init() | ||||
| { | ||||
| parent::init(); | ||||
| } | ||||
|
|
||||
| /** | ||||
| * Runs all jobs from queue. | ||||
| */ | ||||
| public function run() | ||||
| { | ||||
| while (!Signal::isExit() && ($payload = $this->getPayload())) { | ||||
| list($ttr, $message) = explode(';', $payload['Body'], 2); | ||||
|
|
||||
| $this->reserve($payload, $ttr); //reserve it so it is not visible to another worker till ttr | ||||
|
|
||||
| if ($this->handleMessage(null, $message, $ttr, 1)) { | ||||
| //if handled then remove from queue | ||||
| $this->release($payload); | ||||
| } | ||||
| } | ||||
| } | ||||
|
|
||||
| /** | ||||
| * Listens to get new jobs. | ||||
| */ | ||||
| public function listen() | ||||
| { | ||||
| $this->run(); | ||||
| } | ||||
|
|
||||
| /** | ||||
| * @inheritdoc | ||||
| */ | ||||
| protected function pushMessage($message, $ttr, $delay, $priority) | ||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This method is used anywhere ?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I know it's used here Line 146 in 967b0e1
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry, i didn't notice. |
||||
| { | ||||
| if ($priority) { | ||||
| throw new NotSupportedException('Priority is not supported in this driver'); | ||||
| } | ||||
|
|
||||
| $model = $this->getClient()->sendMessage([ | ||||
| 'DelaySeconds' => $delay, | ||||
| 'QueueUrl' => $this->url, | ||||
| 'MessageBody' => "$ttr;$message", | ||||
| ]); | ||||
|
|
||||
| if ($model !== null) { | ||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if ($model === null) {
return false;
}
return $model['MessageId']; |
||||
| return $model['MessageId']; | ||||
| } else { | ||||
| return false; | ||||
| } | ||||
| } | ||||
|
|
||||
| /** | ||||
| * @inheritdoc | ||||
| */ | ||||
| public function status($id) | ||||
| { | ||||
| throw new NotSupportedException('Status is not supported in the driver.'); | ||||
| } | ||||
|
|
||||
| /** | ||||
| * @return \Aws\Sqs\SqsClient | ||||
| */ | ||||
| protected function getClient() | ||||
| { | ||||
| if ($this->key && $this->secret) { | ||||
| $provider = [ | ||||
| 'key' => $this->key, | ||||
| 'secret' => $this->secret | ||||
| ]; | ||||
| } else { | ||||
| // use default provider if no key and secret passed | ||||
| //see - http://docs.aws.amazon.com/aws-sdk-php/v3/guide/guide/credentials.html#credential-profiles | ||||
| $provider = CredentialProvider::defaultProvider(); | ||||
| } | ||||
|
|
||||
| $config = [ | ||||
| 'credential' => $provider, | ||||
| 'region' => $this->region, | ||||
| 'version' => $this->version, | ||||
| ]; | ||||
|
|
||||
| if (!$this->_client) { | ||||
| $this->_client = SqsClient::factory($config); | ||||
|
|
||||
| } | ||||
| return $this->_client; | ||||
| } | ||||
|
|
||||
| /** | ||||
| * | ||||
| */ | ||||
| private function getPayload() | ||||
| { | ||||
| $payload = $this->getClient()->receiveMessage([ | ||||
| 'QueueUrl' => $this->url, | ||||
| 'AttributeNames' => ['ApproximateReceiveCount'], | ||||
| 'MaxNumberOfMessages' => 1, | ||||
| ]); | ||||
|
|
||||
| $payload = $payload['Messages']; | ||||
| if ($payload) { | ||||
| return array_pop($payload); | ||||
| } | ||||
|
|
||||
| return null; | ||||
| } | ||||
|
|
||||
| /** | ||||
| * Set the visibilty to reserve message | ||||
| * So that no other worker can see this message | ||||
| * | ||||
| * @param array $payload | ||||
| * @param int $ttr | ||||
| */ | ||||
| private function reserve($payload, $ttr) | ||||
| { | ||||
| $receiptHandle = $payload['ReceiptHandle']; | ||||
| $this->getClient()->changeMessageVisibility(array( | ||||
| 'QueueUrl' => $this->url, | ||||
| 'ReceiptHandle' => $receiptHandle, | ||||
| 'VisibilityTimeout' => $ttr | ||||
| )); | ||||
| } | ||||
|
|
||||
| /** | ||||
| * Mark the message as handled | ||||
| * | ||||
| * @param array $payload | ||||
| * @return boolean | ||||
| */ | ||||
| private function release($payload) | ||||
| { | ||||
| if (!empty($payload['ReceiptHandle'])) { | ||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if (empty($payload['ReceiptHandle'])) {
return false;
}
// rest of the code here |
||||
| $receiptHandle = $payload['ReceiptHandle']; | ||||
| $response = $this->getClient()->deleteMessage([ | ||||
| 'QueueUrl' => $this->url, | ||||
| 'ReceiptHandle' => $receiptHandle, | ||||
| ]); | ||||
|
|
||||
| return $response !== null; | ||||
| } | ||||
|
|
||||
| return false; | ||||
| } | ||||
| } | ||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this method should do the same as in other queue drivers. $queue->listen() should run an infinite loop with timeout (sleep) to use as a daemon, regardless of payload existence.