Skip to content
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

Ag #4

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open

Ag #4

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
024fefc
Add schedule queue worker
bogdevich Oct 23, 2018
357e0ed
controller
andrey-mostovoy Oct 23, 2018
225699d
Merge branch 'ag' of github.com:Topface/schEDUler into AG
andrey-mostovoy Oct 23, 2018
120656b
Add HandlerWorker and HandlerInterface's
bogdevich Oct 23, 2018
774d5d3
Merge branch 'AG' of https://github.com/Topface/schEDUler into AG
bogdevich Oct 23, 2018
e39458b
Little fixes
bogdevich Oct 23, 2018
8ffe0ea
tf 2
andrey-mostovoy Oct 23, 2018
1679176
Merge branch 'ag' of github.com:Topface/schEDUler into AG
andrey-mostovoy Oct 23, 2018
f996a8f
redis
andrey-mostovoy Oct 23, 2018
05df7a6
Add SchedulerQueueStorage
bogdevich Oct 23, 2018
1fe2888
Merge branch 'AG' of https://github.com/Topface/schEDUler into AG
bogdevich Oct 23, 2018
345ad14
Add loggers
bogdevich Oct 23, 2018
8071a6c
Change redis factory interface
bogdevich Oct 23, 2018
72d6c9a
controller 3
andrey-mostovoy Oct 23, 2018
e356158
Merge branch 'ag' of github.com:Topface/schEDUler into AG
andrey-mostovoy Oct 23, 2018
f7f992c
Merge branch 'AG' of https://github.com/Topface/schEDUler into AG
bogdevich Oct 23, 2018
fb918ee
Fix redis factory interface realisation
bogdevich Oct 23, 2018
38a6432
Merge branch 'ag' of github.com:Topface/schEDUler into AG
andrey-mostovoy Oct 23, 2018
cfdc203
monolog
andrey-mostovoy Oct 23, 2018
c42df2b
Add handler factory
bogdevich Oct 23, 2018
6805457
Return task result in handler worker
bogdevich Oct 23, 2018
39e5b58
fix controller
andrey-mostovoy Oct 23, 2018
ce6dbef
Make handler worker more beautiful
bogdevich Oct 23, 2018
b23e531
Merge branch 'ag' of github.com:Topface/schEDUler into AG
andrey-mostovoy Oct 23, 2018
ad28a91
Fix namespaces
bogdevich Oct 23, 2018
23a27f5
fixes
andrey-mostovoy Oct 23, 2018
ffa6d63
Merge branch 'ag' of github.com:Topface/schEDUler into AG
andrey-mostovoy Oct 23, 2018
b5d7f37
remove lock
andrey-mostovoy Oct 23, 2018
b02f99e
remove useless interface
andrey-mostovoy Oct 23, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file modified .gitignore
100644 → 100755
Empty file.
24 changes: 13 additions & 11 deletions README.md
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,31 @@
Задача:

* Шедулер (/src/Scheduler) должен предоставлять:
* интерфейс для добавления заданий в расписание;
* интерфейс для получения заданий из расписания для выполнения;
+ интерфейс для добавления заданий в расписание;
+ интерфейс для получения заданий из расписания для выполнения;
* интерфейсы для добавления и получения заданий из очереди;
* интерфейс для фабрики обработчиков заданий;
* интерфейс для обработчика задания;
* базовую реализацию воркера для выборки заданий из расписания и добавления их в очередь;
* базовую реализацию воркера для получения задания из очереди, поиска обработчика для неё и запуска этого обработчика.
* Шедулер должен запускаться по крону раз в минуту, выбирать из расписания задания, которые нужно выполнить и добавлять их очередь на выполнения.

* Шедулер должен запускаться по крону раз в минуту, выбирать из расписания задания, которые нужно выполнить и добавлять их очередь на выполнение.
* Базовые реализации интерфейсов должны быть покрыты тестами.

* Основной код (/src/Topface) должен предоставлять:
* возможность запуска крона через run.php;
* возможность запуска обработчиков очереди через run.php;
* возможность добавлять два-три типа задания в расписание;
* реализации необходимых для работы библиотеки интерфейсов;
* обработчики заданий расписания.
+ возможность запуска крона через run.php;
+ возможность запуска обработчиков очереди через run.php;
+ возможность добавлять два-три типа задания в расписание;
+ реализации необходимых для работы библиотеки интерфейсов;
+ обработчики заданий расписания.
* Способ просмотра результатов работы заданий можно выбрать самим (логи, ES и т.п.).
* Для хранения расписания, заданий и очереди использовать Redis.
+ Для хранения расписания, заданий и очереди использовать Redis.
* Опционально:
* Добавить логирование действия через PSR-3 интерфейс.
+ Добавить логирование действия через PSR-3 интерфейс.
* Добавить сбор статистических метрик работы шедулера.

Для упрощения работы добавлены:
* [интерфейс](/src/Scheduler/Task/SchedulerTaskInterface.php) и [реализация](/src/Scheduler/Task/SchedulerTask.php) для сущности "Задание";
* [интерфейс](/src/Scheduler/SchedulerInterface.php) и [простой вариант реализации](/src/Scheduler/Scheduler.php) логики хранения расписания.

Для запуска кода и тестов советуется использовать докер-образ hub.core.tf/topface-ci:1.4.
Для запуска кода и тестов советуется использовать докер-образ hub.core.tf/topface-ci:1.4.
3 changes: 2 additions & 1 deletion composer.json
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"php": "^7.0",
"ext-msgpack": "~2.0.0",
"predis/predis": "v1.0.1",
"php-di/php-di": "~6.0.0"
"php-di/php-di": "~6.0.0",
"monolog/monolog": "~1.23"
},
"require-dev": {
"phpunit/phpunit": "~6.5"
Expand Down
127 changes: 126 additions & 1 deletion composer.lock
100644 → 100755

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Empty file modified phpunit.xml.dist
100644 → 100755
Empty file.
15 changes: 15 additions & 0 deletions src/Scheduler/Handler/HandlerFactoryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Scheduler\Handler;

/**
* Фабрика обработчиков очереди
*/
interface HandlerFactoryInterface {
/**
* @param int $typeId Тип таска для обработки
*
* @return HandlerInterface
*/
public function getHandler(int $typeId): HandlerInterface;
}
19 changes: 19 additions & 0 deletions src/Scheduler/Handler/HandlerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Scheduler\Handler;

use Scheduler\Task\SchedulerTask;

/**
* Интерфейс обработчика таски
*/
interface HandlerInterface {
/**
* Обрабатываем таску и возвращаем результат выполнения
*
* @param SchedulerTask $SchedulerTask
*
* @return bool
*/
public function runTask(SchedulerTask $SchedulerTask): bool;
}
108 changes: 108 additions & 0 deletions src/Scheduler/HandlerWorker/HandlerWorker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?php

namespace Scheduler\HandlerWorker;

use Exception;
use Psr\Log\LoggerInterface;
use Scheduler\Handler\HandlerFactoryInterface;
use Scheduler\SchedulerQueueStorage\SchedulerQueueStorageInterface;
use Scheduler\Task\SchedulerTask;

/**
* Обрабатываем очередь задач, которые нам нужно выполнить
*/
class HandlerWorker implements HandlerWorkerInterface {
/**
* Сторейдж доступа к очереди тасков на выполнение
*
* @var SchedulerQueueStorageInterface
*/
private $SchedulerQueueStorage;

/**
* Фабрика обработчиков типов тасков
*
* @var HandlerFactoryInterface
*/
private $HandlerFactory;

/**
* Логгер для записи событий
*
* @var LoggerInterface
*/
private $Logger;

/**
* @param SchedulerQueueStorageInterface $SchedulerQueueStorage
* @param HandlerFactoryInterface $HandlerFactory
* @param LoggerInterface $Logger
*/
public function __construct(
SchedulerQueueStorageInterface $SchedulerQueueStorage,
HandlerFactoryInterface $HandlerFactory,
LoggerInterface $Logger
) {
$this->SchedulerQueueStorage = $SchedulerQueueStorage;
$this->HandlerFactory = $HandlerFactory;
$this->Logger = $Logger;
}

/**
* Получаем новое задание из очереди и обрабатываем его
*/
public function run() {
while(true) {
// достаем элемент из очереди
$Task = $this->SchedulerQueueStorage->pop();

if (!$Task) {
continue;
}

$result = $this->processTask($Task);

if (!$result) {
$this->Logger->error(
sprintf(
'Task #%s failed and restarted',
$Task->getTaskId()
)
);
$this->SchedulerQueueStorage->add($Task);
}

// чистим память в обработчике, чтобы не текла
unset($Task);

// чуть-чуть спим для приличия
usleep(500);
}
}

/**
* Получаем хэндлер для задачи и выполняем её
*
* @param SchedulerTask $SchedulerTask Задача, которую необходимо выполнить
*
* @return bool
*/
public function processTask(SchedulerTask $SchedulerTask): bool {
$TaskHandler = $this->HandlerFactory->getHandler($SchedulerTask->getTypeId());
try {
return $TaskHandler->runTask($SchedulerTask);
} catch (Exception $Ex) {
$this->Logger->error(
sprintf(
'Task #%s handler raise an exception %s, message: %s\n%s',
$SchedulerTask->getTaskId(),
get_class($Ex),
$Ex->getMessage(),
$Ex->getTraceAsString()
)
);
}

return false;
}
}
13 changes: 13 additions & 0 deletions src/Scheduler/HandlerWorker/HandlerWorkerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Scheduler\HandlerWorker;

/**
* Интерфейс обработчика очереди
*/
interface HandlerWorkerInterface {
/**
* Получаем новое задание из очереди и обрабатываем его
*/
public function run();
}
8 changes: 7 additions & 1 deletion src/Scheduler/Scheduler.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
use Scheduler\Task\SchedulerTask;
use Scheduler\Task\SchedulerTaskInterface;

/**
* Класс расписания выполняемых задач
*/
class Scheduler implements SchedulerInterface {

/**
* @var Client
*/
Expand All @@ -18,6 +20,8 @@ public function __construct(SchedulerRedisClientFactoryInterface $RedisClientFac
}

/**
* Добавляем задачу в пул или устанавливаем новые данные для неё
*
* @inheritdoc
*/
public function addOrSet(SchedulerTaskInterface $Task): string {
Expand All @@ -30,6 +34,8 @@ public function addOrSet(SchedulerTaskInterface $Task): string {
}

/**
* Достаем таск из очереди и удаляем его оттуда
*
* @inheritdoc
*/
public function getAndRemove(int $timestamp, int $count = self::LIMIT): array {
Expand Down
Empty file modified src/Scheduler/SchedulerInterface.php
100644 → 100755
Empty file.
Loading