|
// |
|
// CoalesceOperation.swift |
|
// RequestCoalesce |
|
// |
|
// Created by Nicholas Cross on 4/12/2016. |
|
// Copyright © 2016 Nicholas Cross. All rights reserved. |
|
// |
|
|
|
import Foundation |
|
|
|
public class CoalesceGroup { |
|
private var coalesceGroup: DispatchGroup |
|
private var coalesceQueue: DispatchQueue |
|
|
|
init() { |
|
self.coalesceGroup = DispatchGroup() |
|
self.coalesceQueue = DispatchQueue(label: "OperationQueue") |
|
} |
|
|
|
public func performAsync(coalesce coalesceable: Coalesceable, withForceRefresh forceRefresh: Bool = false, completed: @escaping ()->()) { |
|
DispatchQueue.global(qos: .background).async { |
|
self.perform(coalesce: coalesceable, withForceRefresh: forceRefresh, completed: completed) |
|
} |
|
} |
|
|
|
public func perform(coalesce coalesceable: Coalesceable, withForceRefresh forceRefresh: Bool = false, completed: @escaping ()->()) { |
|
guard !forceRefresh else { |
|
self._perform(coalesce: coalesceable, withForceRefresh: true, completed: completed) |
|
return |
|
} |
|
|
|
self.coalesceQueue.async { |
|
self._perform(coalesce: coalesceable, completed: completed) |
|
} |
|
} |
|
|
|
private func _perform(coalesce coalesceable: Coalesceable, withForceRefresh forceRefresh: Bool = false, completed: @escaping ()->()) { |
|
if (!forceRefresh) { |
|
self.coalesceGroup.wait() |
|
} |
|
|
|
self.coalesceGroup.enter() |
|
|
|
self.coalesceGroup.notify(queue: DispatchQueue.global(qos: .background), execute: completed) |
|
|
|
if !coalesceable.isCached || forceRefresh { |
|
coalesceable.performOperation() { |
|
DispatchQueue.global(qos: .background).async { |
|
self.coalesceGroup.leave() |
|
} |
|
} |
|
} |
|
else { |
|
self.coalesceGroup.leave() |
|
} |
|
} |
|
|
|
} |
|
|
|
public protocol Coalesceable { |
|
var isCached: Bool {get} |
|
func performOperation(complete: @escaping ()->()) |
|
} |