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

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->createTask($account->id, $account->username, null);
$changeUsernameForm->createEventTask($account->id, $account->username, null);
return $account;
}

View File

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

View File

@ -46,6 +46,19 @@ abstract class Controller extends \yii\console\Controller {
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() {
$exchangeName = $this->getExchangeName();
$connection = $this->getAmqp()->getConnection();
@ -66,9 +79,15 @@ abstract class Controller extends \yii\console\Controller {
}
public function callback(AMQPMessage $msg) {
$routingKey = $msg->delivery_info['routing_key'];
$method = 'route' . Inflector::camelize($routingKey);
$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)) {
$this->log(

View File

@ -16,4 +16,11 @@ class Helper {
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\exceptions\NoContentException;
use common\components\RabbitMQ\Component as RabbitMQComponent;
use common\models\amqp\UsernameChanged;
use common\models\MojangUsername;
use console\controllers\base\AmqpController;
use Yii;
class AccountQueueController extends AmqpController {
public function getExchangeName() {
return 'account';
return 'events';
}
public function getQueueName() {
return 'account-operations';
return 'accounts-events';
}
public function getExchangeDeclareArgs() {
protected function getExchangeDeclareArgs() {
return array_replace(parent::getExchangeDeclareArgs(), [
1 => RabbitMQComponent::TYPE_TOPIC, // type -> topic
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) {
$mojangApi = new MojangApi();
try {

View File

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

View File

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

View File

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