-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathFileSystemQueue.swift
81 lines (65 loc) · 2.3 KB
/
FileSystemQueue.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import Foundation
// A data structure that both the queue writer and queue readers use together. It's a cache of the queue that is stored on the file system.
protocol FileSystemQueue {
var queue: [PendingTask] { get }
func load() // can be called at anytime to read the queue from file system and store in-memory for speed
func add(_ pendingTask: PendingTask)
func delete(_ pendingTask: PendingTask)
func delete(_ taskId: Double)
}
// sourcery: InjectRegister = "FileSystemQueue"
class FileSystemQueueImpl: FileSystemQueue {
private let fileStore: FileSystemStore
private let queueFilePath: [String] = ["tasks_queue.json"]
private let jsonAdapter: JsonAdapter
init(fileStore: FileSystemStore, jsonAdapter: JsonAdapter) {
self.fileStore = fileStore
self.jsonAdapter = jsonAdapter
}
func load() {
dataStore.updateDataBlock { data in
guard !data.hasLoadedCache else {
return
}
let queueData = self.fileStore.readFile(self.queueFilePath)
guard let queueData else {
// no queue file exists.
data.hasLoadedCache = true
return
}
data.cache = jsonAdapter.fromData(queueData)!
data.hasLoadedCache = true
}
}
var queue: [PendingTask] {
load()
return dataStore.getDataSnapshot().cache
}
func add(_ pendingTask: PendingTask) {
load()
dataStore.updateDataBlock { data in
data.cache.append(pendingTask)
fileStore.saveFile(jsonAdapter.toData(data.cache)!, filePath: queueFilePath)
}
}
func delete(_ taskId: Double) {
load()
dataStore.updateDataBlock { data in
data.cache.removeAll { $0.taskId == taskId }
fileStore.saveFile(jsonAdapter.toData(data.cache)!, filePath: queueFilePath)
}
}
func delete(_ pendingTask: PendingTask) {
guard let taskId = pendingTask.taskId else {
return
}
delete(taskId)
}
public struct Data: AutoResettable {
var hasLoadedCache = false
var cache: [PendingTask] = []
}
final class DataStore: InMemoryDataStore<Data>, Singleton {
static let shared: DataStore = .init(data: .init())
}
}