Изменена логика для работы с очередью задач, чтобы её можно было использовать в дальнейшем в кластере серверов

This commit is contained in:
ErickSkrauch 2016-07-17 18:25:24 +03:00
parent 9ea689a700
commit 6d3db89140
8 changed files with 56 additions and 20 deletions

View File

@ -104,7 +104,7 @@ class RegistrationForm extends ApiForm {
} }
$changeUsernameForm = new ChangeUsernameForm(); $changeUsernameForm = new ChangeUsernameForm();
$changeUsernameForm->createTask($account->id, $account->username, null); $changeUsernameForm->createEventTask($account->id, $account->username, null);
return $account; return $account;
} }

View File

@ -57,7 +57,7 @@ class ChangeUsernameForm extends PasswordProtectedForm {
throw $e; throw $e;
} }
$this->createTask($account->id, $account->username, $oldNickname); $this->createEventTask($account->id, $account->username, $oldNickname);
return true; return true;
} }
@ -69,18 +69,18 @@ class ChangeUsernameForm extends PasswordProtectedForm {
* @param string $newNickname * @param string $newNickname
* @param string $oldNickname * @param string $oldNickname
*/ */
public function createTask($accountId, $newNickname, $oldNickname) { public function createEventTask($accountId, $newNickname, $oldNickname) {
$message = Amqp::getInstance()->prepareMessage(new UsernameChanged([ $model = new UsernameChanged([
'accountId' => $accountId, 'accountId' => $accountId,
'oldUsername' => $oldNickname, 'oldUsername' => $oldNickname,
'newUsername' => $newNickname, 'newUsername' => $newNickname,
]), [ ]);
$message = Amqp::getInstance()->prepareMessage($model, [
'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT, 'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT,
]); ]);
Amqp::sendToExchange('account', 'username-changed', $message, [ Amqp::sendToEventsExchange('accounts.username-changed', $message);
3 => true, // durable -> true
]);
} }
} }

View File

@ -46,6 +46,19 @@ abstract class Controller extends \yii\console\Controller {
return Yii::$app->get('amqp'); return Yii::$app->get('amqp');
} }
/**
* Позволяет задать карту route из amqp к обработчику внутри класса:
* return [
* 'accounts.change-username' => 'routeChangeUsername',
* 'accounts.delete-account' => 'routeAccountDeleted',
* ];
*
* @return array
*/
public function getRoutesMap() {
return [];
}
protected function configureListen() { protected function configureListen() {
$exchangeName = $this->getExchangeName(); $exchangeName = $this->getExchangeName();
$connection = $this->getAmqp()->getConnection(); $connection = $this->getAmqp()->getConnection();
@ -66,9 +79,15 @@ abstract class Controller extends \yii\console\Controller {
} }
public function callback(AMQPMessage $msg) { public function callback(AMQPMessage $msg) {
$routingKey = $msg->delivery_info['routing_key'];
$method = 'route' . Inflector::camelize($routingKey);
$body = Json::decode($msg->body, true); $body = Json::decode($msg->body, true);
/** @var string $routingKey */
$routingKey = $msg->delivery_info['routing_key'];
$map = $this->getRoutesMap();
if (isset($map[$routingKey])) {
$method = $map[$routingKey];
} else {
$method = 'route' . Inflector::camelize($routingKey);
}
if (!method_exists($this, $method)) { if (!method_exists($this, $method)) {
$this->log( $this->log(

View File

@ -16,4 +16,11 @@ class Helper {
static::getInstance()->sendToExchange($exchange, $routingKey, $message, $exchangeArgs); static::getInstance()->sendToExchange($exchange, $routingKey, $message, $exchangeArgs);
} }
public static function sendToEventsExchange($routingKey, $message) {
static::sendToExchange('events', $routingKey, $message, [
1 => Component::TYPE_TOPIC, // type -> topic
3 => true, // durable -> true
]);
}
} }

View File

@ -3,27 +3,38 @@ namespace console\controllers;
use common\components\Mojang\Api as MojangApi; use common\components\Mojang\Api as MojangApi;
use common\components\Mojang\exceptions\NoContentException; use common\components\Mojang\exceptions\NoContentException;
use common\components\RabbitMQ\Component as RabbitMQComponent;
use common\models\amqp\UsernameChanged; use common\models\amqp\UsernameChanged;
use common\models\MojangUsername; use common\models\MojangUsername;
use console\controllers\base\AmqpController; use console\controllers\base\AmqpController;
use Yii;
class AccountQueueController extends AmqpController { class AccountQueueController extends AmqpController {
public function getExchangeName() { public function getExchangeName() {
return 'account'; return 'events';
} }
public function getQueueName() { public function getQueueName() {
return 'account-operations'; return 'accounts-events';
} }
public function getExchangeDeclareArgs() { protected function getExchangeDeclareArgs() {
return array_replace(parent::getExchangeDeclareArgs(), [ return array_replace(parent::getExchangeDeclareArgs(), [
1 => RabbitMQComponent::TYPE_TOPIC, // type -> topic
3 => true, // durable -> true 3 => true, // durable -> true
]); ]);
} }
protected function getQueueBindArgs($exchangeName, $queueName) {
return [$queueName, $exchangeName, 'accounts.#'];
}
public function getRoutesMap() {
return [
'accounts.username-changed' => 'routeUsernameChanged',
];
}
public function routeUsernameChanged(UsernameChanged $body) { public function routeUsernameChanged(UsernameChanged $body) {
$mojangApi = new MojangApi(); $mojangApi = new MojangApi();
try { try {

View File

@ -56,8 +56,8 @@ services:
build: ./docker/rabbitmq build: ./docker/rabbitmq
environment: environment:
RABBITMQ_DEFAULT_USER: "ely-accounts-app" RABBITMQ_DEFAULT_USER: "ely-accounts-app"
RABBITMQ_DEFAULT_PASS: "app-password" RABBITMQ_DEFAULT_PASS: "ely-accounts-app-password"
RABBITMQ_DEFAULT_VHOST: "/account.ely.by" RABBITMQ_DEFAULT_VHOST: "/ely.by"
ports: ports:
- "15672:15672" # Manager interface - "15672:15672" # Manager interface

View File

@ -19,8 +19,8 @@ return [
'host' => 'rabbitmq', 'host' => 'rabbitmq',
'port' => 5672, 'port' => 5672,
'user' => 'ely-accounts-app', 'user' => 'ely-accounts-app',
'password' => 'app-password', 'password' => 'ely-accounts-app-password',
'vhost' => '/account.ely.by', 'vhost' => '/ely.by',
], ],
], ],
]; ];

View File

@ -7,7 +7,6 @@ use common\models\Account;
use common\models\UsernameHistory; use common\models\UsernameHistory;
use tests\codeception\api\unit\DbTestCase; use tests\codeception\api\unit\DbTestCase;
use tests\codeception\common\fixtures\AccountFixture; use tests\codeception\common\fixtures\AccountFixture;
use Yii;
/** /**
* @property AccountFixture $accounts * @property AccountFixture $accounts
@ -92,7 +91,7 @@ class ChangeUsernameFormTest extends DbTestCase {
public function testCreateTask() { public function testCreateTask() {
$model = $this->createModel(); $model = $this->createModel();
$model->createTask('1', 'test1', 'test'); $model->createEventTask('1', 'test1', 'test');
// TODO: у меня пока нет идей о том, чтобы это как-то успешно протестировать, увы // TODO: у меня пока нет идей о том, чтобы это как-то успешно протестировать, увы
// но по крайней мере можно убедиться, что оно не падает где-то на этом шаге // но по крайней мере можно убедиться, что оно не падает где-то на этом шаге
} }