dannys42 / SwiftWorkQueue

Abstracting code deferral (RunLoops, DispatchQueues, OperationQueues, EventLoops)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

build status macOS iOS Linux Apache 2

SwiftWorkQueue

WorkQueue is a set of protocols that help to abstract code deferral. There are implementations to support RunLoop, DispatchQueue, OperationQueue, NIO EventLoop.

Swift has many code deferal mechanisms (as listed above). Unfortunately when library authors need to perform defered operations (e.g. typically for async methods), they have to make a choice as to whether to use DispatchQueue, OperationQueue, RunLoop, etc.

However an application may be composed of many such libraries, where each author has chosen a different mechanism. This may lead to inefficient use of CPU resources. SwiftWorkQueue aims to resolve this problem and allow the application developer to make the choice for their application.

Design goals:

  • Allow library authors to have a generic representation of code deferral, so that application developers can make the decision as to which method they prefer
  • A modular set of protocols supporting a variety of queue types, such as calling after a timeout.

Usage

Library Authors

Typically, when a library author needs to perform deferred operations, they decide the code deferal mechanism (e.g. DispatchQueue). This will typically look like this:

import Foundation

class SomeObject {
	private let dispatchQueue: DispatchQueue
	
	init(dispatchQueue: DispatchQueue? = nil) {

		// use a custom queue if one was not provided	
		self.dispatchQueue = dispatchQueue ?? DispatchQueue()
	}


	func someAsyncCall(_ completion: @escaping ()->Void) {
		self.dispatchQueue.async {
			// perform some sort of task in the background
			completion()
		}
	}
}

To use WorkQueue, the change for the library author is minimal:

import WorkQueue
import WorkQueueDispatch

class SomeObject {
	private let workQueue: WorkQueue
	
	init(workQueue: WorkQueue? = nil) {

		// use a custom DispatchQueue if no WorkQueue was provided	
		self.workQueue = workQueue ?? WorkQueueDispatch(queue: DispatchQueue(label: "SomeObject default"))
	}


	func someAsyncCall(_ completion: @escaping ()->Void) {
		self.workQueue.async {
			// perform some sort of task in the background
			completion()
		}
	}
}

Application Developers

Given the class above, the application developer can choose the deferal mechanism they want:

import WorkQueue
// application author will typically pick one of the following
import WorkQueueDispatch  	// To support DispatchQueue 
import WorkQueueOperation 	// To support OperationQueue
import WorkQueueRunLoop  	// To support RunLoop
import WorkQueueNIO		  	// To support NIO 

class MyApplication {
	let workQueue: WorkQueue
	
	init() {
		self.workQueue = WorkQueueRunLoop(runLoop: .main)
	}
	
	func run() {
		SomeObject().someAsyncCall() {
			// completion handler
		}
	}
}

Even though SomeObject()'s default deferal mechanism was to use a DispatchQueue, in this case, the application author has chosen to use RunLoop. .someAsyncCall() and the subsequent completion handler will be called on the RunLoop specified.

Installation

Add the SwiftWorkQueue package to the dependencies within your application's Package.swift file. Substitute "x.y.z" with the latest SwiftWorkQueue release.

.package(url: "https://github.com/dannys42/SwiftWorkQueue.git", from: "x.y.z")

Add ClosureChain to your target's dependencies:

.target(name: "example", dependencies: ["SwiftWorkQueue"]),

Cocoapods

Add SwiftWorkQueue to your Podfile:

pod `SwiftWorkQueue `

API Documentation

For more information visit our API reference.

License

This library is licensed under Apache 2.0. The full license text is available in LICENSE.

About

Abstracting code deferral (RunLoops, DispatchQueues, OperationQueues, EventLoops)

License:Apache License 2.0


Languages

Language:Swift 100.0%