foundry / masonry
一个用于构建单次使用或持续异步任务运行器的微型框架
Requires
- php: ^5.5 || ^7.0
- foundry/masonry-register: ^1.0.0
- psr/log: ^1.0
- react/promise: ^2.2
- symfony/console: ^2.0
- symfony/filesystem: ^2.0
- symfony/yaml: ^2.0
Requires (Dev)
- pdepend/pdepend: 2.1
- phploc/phploc: ^2.1
- phpmd/phpmd: ^2.2
- phpunit/phpunit: >=4.8.21
- sebastian/phpcpd: ^2.0
- squizlabs/php_codesniffer: ^2.3
This package is not auto-updated.
Last update: 2016-11-25 08:15:39 UTC
README
PHP Masonry是一种构建服务的块功能方式。任务从池中检索,并由工作者处理。您可以有任意数量的工作者和任意数量的任务。
安装
使用Composer安装Masonry
composer require foundry/masonry -n
内容
架构
╭──────────────────────────────────╮
│ (i) Mediator │
╭──────────────────────────────────╮ ├──────────────────────────────────┤
│ (i) Worker ├───→───┤ <Mediator> addWorker(<Worker>) │
├──────────────────────────────────┤ ┌─→──┤ <Promise> process(<Task>) │
┌─→──┤ <Promise> process(<Task>) │ │ ╰──────────────────────────────────╯
│ │ <string[]> getDescriptionTypes() │ │
│ ╰──────────────────────────────────╯ │
│ │
│ │
├──────────────────────────────────────────┴─────────────────────────────────┐ ╭───────────────────────────────╮
│ │ ┌─→─┤ (i) Task\Description │
│ ╭────────────────────────────────╮ │ │ ├───────────────────────────────┤
│ ┌─→─┤ (i) Task ├─→─┘ │ ╰───────────────────────────────╯
│ │ ├────────────────────────────────┤ │
│ │ │ <Description> getDescription() ├───→───┘ ╭────────────────────────────────╮
│ │ │ <Status> getStatus() ├─────→─────┤ (i) Task\Status │
│ │ │ <History> getHistory() ├───→───┐ ├────────────────────────────────┤
│ │ ╰────────────────────────────────╯ │ │ __construct(<string>) │
│ │ │ │ <string> getStatus() │
│ ╭──────────────────────────╮ │ │ │ <string> __toString() │
│ │ (i) Pool │ │ │ ╰────────────────────────────────╯
│ ├──────────────────────────┤ │ │
└─→──┤ <Pool> addTask(<Task>) │ │ │
│ <Task> getTask() ├─→─┘ ╭────────────────────────────────╮ │
│ <Status> getStatus() ├───→───┤ (i) Pool\Status │ │
╰──────────────────────────╯ ├────────────────────────────────┤ │
│ __construct(<string>) │ │
│ <string> getStatus() │ │
│ <string> __toString() │ │
╰────────────────────────────────╯ │
│
│
│
╭────────────────────────────╮ │
│ (i) Task\History ├──────────────────────┘
├────────────────────────────┤
┌────→─────┤ <History> addEvent(<Event>)│
│ │ <Event[]> getEvents() ├─────→─────┐
│ │ <Event> getLastEvent() ├─────→─────┤
│ ╰────────────────────────────╯ │
│ │
│ ╭───────────────────────────────────────╮ │
└──←──┤ (i) Task\History\Event ├──←──┘
├───────────────────────────────────────┤
│ <Event> startEvent() │
├───────────────────────────────────────┤
┌───┬───→──┤ <Event> endEvent(<Result>, <Reason>) │
│ │ │ <float> getStartTime() │
│ │ │ <float> getEndTime() │
│ │ │ <Result> getResult() ├────→────┐
│ │ │ <Reason> getReason() ├──→──┐ │
│ │ │ <string> __toString() │ │ │
│ │ ╰───────────────────────────────────────╯ │ │
│ │ │ │
│ │ ╭────────────────────────────────╮ │ │
│ └────←────┤ (i) Task\History\Reason ├────←────┘ │
│ ├────────────────────────────────┤ │
│ │ __construct(<string>) │ │
│ │ <string> getReason() │ │
│ │ <string> __toString() │ │
│ ╰────────────────────────────────╯ │
│ │
│ ╭────────────────────────────────╮ │
└──────←──────┤ (i) Task\History\Result ├──────←──────┘
├────────────────────────────────┤
│ __construct(<string>) │
│ <string> getResult() │
│ <string> __toString() │
╰────────────────────────────────╯
任务
任务代表需要执行的工作片段。它告诉您任务的历史、当前状态以及它想要发生什么,但不指定如何实现。
╭────────────────────────────────╮
│ (i) Task │
├────────────────────────────────┤
│ <Description> getDescription() │ ← Description tells a worker what needs to happen
│ <Status> getStatus() │ ← The current status of the Task: 'new', 'in progress', 'complete', or 'deferred'
│ <History> getHistory() │ ← The history of the Task so far
╰────────────────────────────────╯
任务 - 描述
描述是一个简单的空接口,仅用于控制。它应该扩展以提供特定任务所需的信息。
╭───────────────────────────────╮
│ (i) Task\Description │
├───────────────────────────────┤
╰───────────────────────────────╯
例如,如果您需要一个可以移动文件的工作者,您可以定义一个MoveFile接口。该接口告诉您文件当前在哪里,以及它应该在哪里。然后,您的工作者应该将接口名称(MoveFile
)添加到它知道如何处理的描述列表中,由Worker::getDescriptionTypes()
提供。
╭───────────────────────────────╮
│ (i) MoveFile : Description │
├───────────────────────────────┤
│ <string> fromLocation() │
│ <string> toLocation() │
╰───────────────────────────────╯
任务 - 状态
任务在完成之前保持在任务池中。在任何时候都可以询问任务的状态。任务可能有以下四种状态之一。
new
:任务自创建以来未被触及in progress
:任务已被从池中移除以进行处理complete
:任务已处理。这并不指定任务是否成功或失败,这由[结果][#task-history]处理deferred
:任务之前已尝试过,但由于某种原因被放回队列中
╭────────────────────────────────╮
│ (i) Task\Status │
├────────────────────────────────┤
│ __construct(<string>) │ ← Initialise the Status with: 'new', 'in progress', 'complete', or 'deferred'
│ <string> getStatus() │ ← The string representation of the status
│ <string> __toString() │ ← must return getStatus()
╰────────────────────────────────╯
任务 - 历史
历史是事件的集合
╭────────────────────────────╮
│ (i) Task\History │
├────────────────────────────┤
│ <History> addEvent(<Event>)│ ← Add a new event to the history
│ <Event[]> getEvents() │ ← Returns an array of all events
│ <Event> getLastEvent() │ ← Returns the last event or null if there is nothing in the history
╰────────────────────────────╯
任务 - 历史 - 事件
任务历史中的一个单独事件。当任务离开池以进行处理时,应创建一个新事件。事件在池被要求完成或延迟任务时完成。
╭───────────────────────────────────────╮
│ (i) Task\History\Event │
├───────────────────────────────────────┤
│ <Event> startEvent() │ ← Events should only be created through this static method
├───────────────────────────────────────┤
│ <Event> endEvent(<Result>, <Reason>) │ ← End the event with a Result, and optionally Reason
│ <float> getStartTime() │ ← Get the event start time. This should be the time the event was created
│ <float> getEndTime() │ ← Get the end time or null if it's in progress
│ <Result> getResult() │ ← Always returns a Result, though it defaults to 'incomplete'
│ <Reason> getReason() │ ← Always returns a Reason, though it's empty by default
│ <string> __toString() │ ← Should return a string representation of the event for logging purposes
╰───────────────────────────────────────╯
任务 - 历史 - 结果
╭────────────────────────────────╮
│ (i) Task\History\Result │
├────────────────────────────────┤
│ __construct(<string>) │ ← Initialise the Result with a value: 'succeeded', 'failed' or 'incomplete'
│ <string> getResult() │ ← The string representation of the result: 'succeeded', 'failed' or 'incomplete'
│ <string> __toString() │ ← must return getResult()
╰────────────────────────────────╯
任务 - 历史 - 原因
尝试处理任务时结果的原因,记录在事件中。这是可选的,可以是任何字符串。这主要用于记录失败。
╭────────────────────────────────╮
│ (i) Task\History\Reason │
├────────────────────────────────┤
│ __construct(<string>) │ ← Initialise the Reason with any string value
│ <string> getReason() │ ← The string representation of the Reason
│ <string> __toString() │ ← must return getReason()
╰────────────────────────────────╯
池
任务池设计用于存储和检索任务。它可以表示队列、栈、堆或其他结构。
╭──────────────────────────╮
│ (i) Pool │
├──────────────────────────┤
│ <Pool> addTask(<Task>) │ ← returns a reference to itself for chaining
│ <Task> getTask() │ ← get the next Task from the pool
│ <Status> getStatus() │ ← tells you if the pool has tasks 'pending' or is 'empty'
╰──────────────────────────╯
池 - 状态
任务池的状态通过状态值类表示。它可能处于两种状态。
pending
有待处理的任务empty
没有待处理的任务
注意:状态为in progress
(进行中)或complete
(完成)的任务不应被视为等待处理。
╭────────────────────────────────╮
│ (i) Pool\Status │
├────────────────────────────────┤
│ __construct(<string>) │ ← Initialise the Status with: 'pending' or 'empty'
│ <string> getStatus() │ ← The string representation of the status
│ <string> __toString() │ ← must return getStatus()
╰────────────────────────────────╯
工作者
工作者是处理任务的地方。它们可能是异步的,因此应该始终返回一个Promise。
工作者也可能能够处理多种类型的任务描述,因此将始终返回字符串数组。然而,最佳实践应该是为每种任务描述有一个工作者。
╭──────────────────────────────────╮
│ (i) Worker │
├──────────────────────────────────┤
│ <Promise> process(<Task>) │ ← Workers always return Promises, regardless of whether they are asynchronous.
│ <string[]> getDescriptionTypes() │ ← This should return an array of Descriptions Types the worker knows how to handle.
╰──────────────────────────────────╯
调解者
调解者负责接收任务并将其传递给正确的工作者。
╭──────────────────────────────────╮
│ (i) Mediator │
├──────────────────────────────────┤
│ <Mediator> addWorker(<Worker>) │ ← Inform the mediator about a Worker. Returns a reference to itself
│ <Promise> process(<Task>) │ ← Pass a task. This will return a promise from a Worker to do the task or throw an
╰──────────────────────────────────╯ exception if no appropriate Worker was found.
Promise
工作者返回React Promise。请参阅以下文档:[https://github.com/reactphp/promise](https://github.com/reactphp/promise)
工作者模块
您可以使用WorkerModule类创建Masonry的工作者模块。它介于工作者和调解者之间,在内部工作者之间进行调解,但作为工作者对外部调解者暴露。
╭─────────────────────────────────────╮
│ (i) WorkerModule : Mediator, Worker │
├─────────────────────────────────────┤
│ __construct([<Worker>]) │
│ <Mediator> addWorker(<Worker>) │
│ <Promise> process(<Task>) │
│ <string[]> getDescriptionTypes() │
╰─────────────────────────────────────╯