Skip to content

Instantly share code, notes, and snippets.

@kylehughes
Created May 27, 2020 18:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kylehughes/83b185f8cc28f2ccd4ba5548440201d7 to your computer and use it in GitHub Desktop.
Save kylehughes/83b185f8cc28f2ccd4ba5548440201d7 to your computer and use it in GitHub Desktop.
Batch Collector Implementation
//
// Collector.swift
// InformationSuperhighway
//
// Created by Kyle Hughes on 2/26/20.
// Copyright © 2020 Kyle Hughes. All rights reserved.
//
final class Collector<Item> {
typealias FlushHandler = ([Item]) -> Void
private let collection: Atomic<[Item]>
private let flushHandler: FlushHandler
private let flushInterval: TimeInterval
private let flushHandlerQueue: DispatchQueue
private let flushQueue: DispatchQueue
private var flushTimer: Timer?
// MARK: Internal Initialization
init(
flushInterval: TimeInterval,
flushHandlerQueue: DispatchQueue = .global(qos: .default),
flushHandler: @escaping FlushHandler
) {
self.flushInterval = flushInterval
self.flushHandlerQueue = flushHandlerQueue
self.flushHandler = flushHandler
collection = Atomic([])
flushQueue = DispatchQueue(label: "Collector.FlushQueue", qos: .userInitiated)
}
// MARK: Internal Instance Interface
func add(item: Item) {
collection.value.append(item)
}
func flush() {
flushQueue.async {
self.collection.modify { collection in
guard !collection.isEmpty else {
return
}
let capturedCollection = collection
collection.removeAll()
self.flushHandlerQueue.async {
self.flushHandler(capturedCollection)
}
}
}
}
func start() {
guard flushTimer == nil else {
return
}
flush()
flushTimer = .scheduledTimer(
timeInterval: flushInterval,
target: self,
selector: #selector(handleFlushTimerTrigger),
userInfo: nil,
repeats: true)
}
func stop() {
guard let flushTimer = flushTimer else {
return
}
flushTimer.invalidate()
self.flushTimer = nil
}
// MARK: Private Instance Interface
@objc private func handleFlushTimerTrigger() {
flush()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment