TaskKit,也称 “Task It”

这个框架是我尝试替换标准库的 OperationQueueOperation 类的努力。
过去在使用 OperationQueue 时,我遇到了一些问题,例如当它无法处理超过 100 个 Operation 时会无限期冻结(至少在 Linux 上是这样),以及许多其他令我感到沮丧或非常恼人的复杂之处。
所以我构建了这个!我尝试使其具有相同的线程安全性、类似的 API,但比标准库的同类更面向协议。

安装 (SPM)

将其添加到您的 Package.swift

.package(url: "https://github.com/Ponyboy47/TaskKit.git", from: "0.6.0")

支持 Swift 4.x (包括 4.2)

任务协议

TaskKit 的基础是(你猜对了)任务。

您可以遵循许多任务协议

任务 (Task)

这是所有后续 *Task 协议也遵循的基础协议。
为了遵循任何 Task 协议,您必须实现以下协议要求

var state: TaskState { get set }

这包含有关任务当前执行进度的信息,也可能包含日志消息数组(您需要在符合 Task 协议的对象中添加日志消息)。
建议您首先将其赋值为 .ready,否则,请确保在将任务添加到任务队列 (TaskQueue) 之前 status.state 值是 .ready,否则任务将无法执行。

var priority: TaskPriority { get set }

任务的优先级决定了它相对于队列中其他任务的执行时间。
高优先级任务在低优先级任务之前执行。

var qos: DispatchQoS { get }

这将是用于执行您的任务的 服务质量 (Quality of Service)。

func finish()

一个函数,无论您的任务是否成功完成,都会在任务完成时执行。
检查您的任务状态,以便您可以根据任务是失败还是成功来设置不同的逻辑。

func execute() -> Bool

这是将要调用以运行您的任务的函数。
此函数应返回您的任务是否成功完成执行。

ConfigurableTask (可配置任务)

一个 Task,它依赖于某些外部源来正确配置自身(例如:在执行前验证配置文件的脚本)。

func configure() -> Bool

在您的任务可以执行之前必须成功运行的函数。
此函数应返回它是否正确配置了您的任务。

PausableTask (可暂停任务)

一个 Task,可以在执行过程中停止并在稍后恢复。

func pause() -> Bool

用于停止执行的函数。
返回您的任务执行是否已成功暂停。

func resume() -> Bool

用于恢复先前停止的执行的函数。
返回您的任务执行是否已成功恢复。

CancellableTask (可取消任务)

一个 Task,可以在执行过程中取消,但不能(或不会)在稍后恢复。

func cancel()

用于取消执行的函数。

DependentTask (依赖任务)

一个 Task,在成功执行一个或多个其他 Task 之前无法执行。

var dependencies: [Task] { get set }

必须在此任务开始执行之前成功执行的任务数组。

func finish(dependency: Task)

每当依赖项完成执行时运行的函数。
刚完成的依赖项作为 dependency 参数传递。

基本用法

在您至少有一个类型符合任何 Task 协议之后,您可以创建一个 TaskQueue 并向其中添加任务

// Create a queue (maxSimultaneous defaults to 1)
let queue = TaskQueue(name: "com.example.taskqueue", maxSimultaneous: 2)

// Add a task to the queue
queue.add(task: myTask)

// Start the queue's execution
queue.start()

如果您有一个带有依赖项的任务,那么您不需要将依赖项添加到任务中。它们会在它们所依赖的任务运行之前自动运行。

// Add a dependency to your task
myTask.add(dependency: dependencyTask)

// Add the base task to the queue
queue.add(task: myTask)

// Start the queue
queue.start()

链接队列

有时,您可能希望将任务分隔到不同的队列中,即使单独队列中的任务可能相互依赖。这是您可以改用 LinkedTaskQueue 的地方。

// Let's start with two queues:
// 1. For moving media files
// 2. For converting the media
let moveQueue = LinkedTaskQueue(name: "com.example.linked.move", maxSimultaneous: 5)
let conversionQueue = LinkedTaskQueue(name: "com.example.linked.conversion", linkedTo: moveQueue)

// Add our move tasks
moveQueue.add(tasks: moveTasks)

// One of the move tasks shouldn't happen until after it has been converted
moveTasks[0].add(dependency: conversionTask)

// Add that conversion task to its queue
conversionQueue.add(task: conversionTask)

// Start both the queues
moveQueue.start()
conversionQueue.start()

注意:任何依赖任务都必须存在于链接队列之一中,否则将发生致命错误

待办

许可证

MIT