Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
37 changes: 33 additions & 4 deletions SYNQueue/SYNQueue/SYNQueue.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class SYNQueue : NSOperationQueue {
let logProvider: SYNQueueLogProvider?
var tasksMap = [String: SYNQueueTask]()
var taskHandlers = [String: SYNTaskCallback]()
var taskCoalescingHandlers = [String: SYNTaskCoalescingCallback]()
let completionBlock: SYNTaskCompleteCallback?

public var tasks: [SYNQueueTask] {
Expand Down Expand Up @@ -120,6 +121,16 @@ public class SYNQueue : NSOperationQueue {
taskHandlers[taskType] = taskHandler
}

/**
Add a coalescing handler for a task type. This will give an array of tasks to the callback (all of the same type) which must all be completed by the handler.

:param: taskType The task type for the handler
:param: taskCoalescingHandler The coalescing handler for this particular task type, must be able to take multiple tasks, coalesce them, and complete them all.
*/
public func addTaskCoalescingHandler(taskType: String, taskCoalescingHandler:SYNTaskCoalescingCallback) {
taskCoalescingHandlers[taskType] = taskCoalescingHandler
}

/**
Deserializes tasks that were serialized (persisted)
*/
Expand All @@ -144,7 +155,24 @@ public class SYNQueue : NSOperationQueue {
:param: op A SYNQueueTask to execute on the queue
*/
override public func addOperation(op: NSOperation) {
if let task = op as? SYNQueueTask {
if var task = op as? SYNQueueTask {

// If this task type has coalescing block
// If there are other non-started task in the queue that are of the same type
// Call the task coalescing handler with an array of the other non-started
// tasks of the same task type in the queue

if let coalescingHandler = taskCoalescingHandlers[task.taskType] {
var tasksToCoalesce = self.tasks.filter({ return ($0.taskType == task.taskType && !$0.executing && $0.taskID != task.taskID && $0.dependencies.count == 0) })
if tasksToCoalesce.count > 0 {
tasksToCoalesce.append(task)
task = coalescingHandler(tasksToCoalesce) // Overwrite task to the new coalesced task and continue

// Cancel tasks that have now been coalesced
for task in tasksToCoalesce { task.cancel() }
}
}

if tasksMap[task.taskID] != nil {
log(.Warning, "Attempted to add duplicate task \(task.taskID)")
return
Expand All @@ -155,10 +183,10 @@ public class SYNQueue : NSOperationQueue {
if let sp = serializationProvider, let queueName = task.queue.name {
sp.serializeTask(task, queueName: queueName)
}

op.completionBlock = { self.taskComplete(task) }
super.addOperation(task)
}

op.completionBlock = { self.taskComplete(op) }
super.addOperation(op)
}

func addDeserializedTask(task: SYNQueueTask) {
Expand All @@ -172,6 +200,7 @@ public class SYNQueue : NSOperationQueue {
}

func runTask(task: SYNQueueTask) {

if let handler = taskHandlers[task.taskType] {
handler(task)
} else {
Expand Down
3 changes: 2 additions & 1 deletion SYNQueue/SYNQueue/SYNQueueTask.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import Foundation

public typealias SYNTaskCallback = (SYNQueueTask) -> Void
public typealias SYNTaskCoalescingCallback = ([SYNQueueTask]) -> SYNQueueTask
public typealias SYNTaskCompleteCallback = (NSError?, SYNQueueTask) -> Void
public typealias JSONDictionary = [String: AnyObject?]

Expand Down Expand Up @@ -196,7 +197,7 @@ public class SYNQueueTask : NSOperation {

// Convert the dictionary to an NSDictionary by replacing nil values
// with NSNull
var nsdict = NSMutableDictionary(capacity: dict.count)
let nsdict = NSMutableDictionary(capacity: dict.count)
for (key, value) in dict {
nsdict[key] = value ?? NSNull()
}
Expand Down
5 changes: 5 additions & 0 deletions SYNQueueDemo/SYNQueueDemo.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
9FD63FC51B338BA5001BD09A /* TaskCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD63FC41B338BA5001BD09A /* TaskCell.swift */; };
9FD63FC71B33EA2F001BD09A /* NSUserDefaultsSerializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD63FC61B33EA2F001BD09A /* NSUserDefaultsSerializer.swift */; };
9FD63FCD1B3417DF001BD09A /* Utils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FD63FCC1B3417DF001BD09A /* Utils.swift */; };
DC6668E61B8CC7090045852A /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC6668E51B8CC7090045852A /* SettingsViewController.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -61,6 +62,7 @@
9FD63FC41B338BA5001BD09A /* TaskCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskCell.swift; sourceTree = "<group>"; };
9FD63FC61B33EA2F001BD09A /* NSUserDefaultsSerializer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSUserDefaultsSerializer.swift; sourceTree = "<group>"; };
9FD63FCC1B3417DF001BD09A /* Utils.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Utils.swift; sourceTree = "<group>"; };
DC6668E51B8CC7090045852A /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -109,6 +111,7 @@
9FD63F961B333BDC001BD09A /* AppDelegate.swift */,
9F70B5021B368AB500BDB945 /* ConsoleLogger.swift */,
9FD63F981B333BDC001BD09A /* ViewController.swift */,
DC6668E51B8CC7090045852A /* SettingsViewController.swift */,
9FD63F9A1B333BDC001BD09A /* Main.storyboard */,
9FD63F9F1B333BDC001BD09A /* LaunchScreen.xib */,
9FD63FC41B338BA5001BD09A /* TaskCell.swift */,
Expand Down Expand Up @@ -188,6 +191,7 @@
9FD63F891B333BDC001BD09A /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0630;
ORGANIZATIONNAME = Syntertainment;
TargetAttributes = {
Expand Down Expand Up @@ -247,6 +251,7 @@
files = (
9FD63FCD1B3417DF001BD09A /* Utils.swift in Sources */,
9FD63F991B333BDC001BD09A /* ViewController.swift in Sources */,
DC6668E61B8CC7090045852A /* SettingsViewController.swift in Sources */,
9FD63FC51B338BA5001BD09A /* TaskCell.swift in Sources */,
9F70B5031B368AB500BDB945 /* ConsoleLogger.swift in Sources */,
9FD63F971B333BDC001BD09A /* AppDelegate.swift in Sources */,
Expand Down
Loading