Skip to content

Commit 563b3f9

Browse files
authored
Added file size storage limits (#30)
* Added file size storage limits
1 parent c565d2e commit 563b3f9

File tree

5 files changed

+47
-56
lines changed

5 files changed

+47
-56
lines changed

Examples/apps/DestinationsExample/DestinationsExample/AppDelegate.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
8686

8787
// This functionality is needed to forward deep link attribution data with AppsFlyer
8888
// Report Push Notification attribution data for re-engagements
89-
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [String : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
89+
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
9090
// this enables remote notifications for various destinations (appsflyer)
9191
analytics?.receivedRemoteNotification(userInfo: userInfo)
9292
}

Sources/Segment/Plugins/Platforms/iOS/iOSDelegation.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ import UIKit
1616
public protocol RemoteNotifications: Plugin {
1717
func registeredForRemoteNotifications(deviceToken: Data)
1818
func failedToRegisterForRemoteNotification(error: Error?)
19-
func receivedRemoteNotification(userInfo: [String: Any])
19+
func receivedRemoteNotification(userInfo: [AnyHashable: Any])
2020
func handleAction(identifier: String, userInfo: [String: Any])
2121
}
2222

2323
extension RemoteNotifications {
2424
public func registeredForRemoteNotifications(deviceToken: Data) {}
2525
public func failedToRegisterForRemoteNotification(error: Error?) {}
26-
public func receivedRemoteNotification(userInfo: [String: Any]) {}
26+
public func receivedRemoteNotification(userInfo: [AnyHashable: Any]) {}
2727
public func handleAction(identifier: String, userInfo: [String: Any]) {}
2828
}
2929

@@ -46,7 +46,7 @@ extension Analytics {
4646
}
4747
}
4848

49-
public func receivedRemoteNotification(userInfo: [String: Any]) {
49+
public func receivedRemoteNotification(userInfo: [AnyHashable: Any]) {
5050
apply { plugin in
5151
if let p = plugin as? RemoteNotifications {
5252
p.receivedRemoteNotification(userInfo: userInfo)

Sources/Segment/Plugins/Platforms/watchOS/watchOSDelegation.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,13 @@ import WatchKit
1515
public protocol RemoteNotifications: Plugin {
1616
func registeredForRemoteNotifications(deviceToken: Data)
1717
func failedToRegisterForRemoteNotification(error: Error?)
18-
func receivedRemoteNotification(userInfo: [String: Any])
18+
func receivedRemoteNotification(userInfo: [AnyHashable: Any])
1919
}
2020

2121
extension RemoteNotifications {
2222
public func registeredForRemoteNotifications(deviceToken: Data) {}
2323
public func failedToRegisterForRemoteNotification(error: Error?) {}
24-
public func receivedRemoteNotification(userInfo: [String: Any]) {}
24+
public func receivedRemoteNotification(userInfo: [AnyHashable: Any]) {}
2525
}
2626

2727
extension Analytics {
@@ -43,7 +43,7 @@ extension Analytics {
4343
}
4444
}
4545

46-
public func receivedRemoteNotification(userInfo: [String: Any]) {
46+
public func receivedRemoteNotification(userInfo: [AnyHashable: Any]) {
4747
apply { plugin in
4848
if let p = plugin as? RemoteNotifications {
4949
p.receivedRemoteNotification(userInfo: userInfo)

Sources/Segment/Plugins/SegmentDestination.swift

Lines changed: 8 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ public class SegmentDestination: DestinationPlugin {
3737
private var httpClient: HTTPClient?
3838
private var uploads = [UploadTaskInfo]()
3939
private var storage: Storage?
40-
private var maxPayloadSize = 500000 // Max 500kb
4140

4241
private var apiKey: String? = nil
4342
private var apiHost: String? = nil
@@ -139,21 +138,19 @@ public class SegmentDestination: DestinationPlugin {
139138
for url in data {
140139
analytics.log(message: "Processing Batch:\n\(url.lastPathComponent)")
141140

142-
if isPayloadSizeAcceptable(url: url) {
143-
let uploadTask = httpClient.startBatchUpload(writeKey: analytics.configuration.values.writeKey, batch: url) { (result) in
144-
switch result {
141+
let uploadTask = httpClient.startBatchUpload(writeKey: analytics.configuration.values.writeKey, batch: url) { (result) in
142+
switch result {
145143
case .success(_):
146144
storage.remove(file: url)
147145
default:
148146
analytics.logFlush()
149-
}
150-
151-
analytics.log(message: "Processed: \(url.lastPathComponent)")
152-
}
153-
// we have a legit upload in progress now, so add it to our list.
154-
if let upload = uploadTask {
155-
add(uploadTask: UploadTaskInfo(url: url, task: upload))
156147
}
148+
149+
analytics.log(message: "Processed: \(url.lastPathComponent)")
150+
}
151+
// we have a legit upload in progress now, so add it to our list.
152+
if let upload = uploadTask {
153+
add(uploadTask: UploadTaskInfo(url: url, task: upload))
157154
}
158155
}
159156
} else {
@@ -190,30 +187,4 @@ extension SegmentDestination {
190187
internal func add(uploadTask: UploadTaskInfo) {
191188
uploads.append(uploadTask)
192189
}
193-
194-
internal func isPayloadSizeAcceptable(url: URL) -> Bool {
195-
var result = true
196-
var fileSizeTotal: Int64 = 0
197-
198-
// Make sure we're under the max payload size.
199-
do {
200-
let attributes = try FileManager.default.attributesOfItem(atPath: url.path)
201-
guard let fileSize = attributes[FileAttributeKey.size] as? Int64 else {
202-
analytics?.log(message: "File size could not be read")
203-
// none of the logic beyond here will work if we can't get the
204-
// filesize so assume everything is good and hope for the best.
205-
return true
206-
}
207-
fileSizeTotal += fileSize
208-
} catch {
209-
analytics?.log(message: "Could not read file attributes")
210-
}
211-
212-
if fileSizeTotal >= maxPayloadSize {
213-
analytics?.log(message: "Batch file is too large to be sent")
214-
result = false
215-
}
216-
return result
217-
}
218-
219190
}

Sources/Segment/Utilities/Storage.swift

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ internal class Storage: Subscriber {
1313
let writeKey: String
1414
let syncQueue = DispatchQueue(label: "storage.segment.com")
1515
let userDefaults: UserDefaults?
16+
static let MAXFILESIZE = 475000 // Server accepts max 500k per batch
1617

1718
init(store: Store, writeKey: String) {
1819
self.store = store
@@ -44,14 +45,8 @@ extension Storage {
4445
switch key {
4546
case .events:
4647
if let event = value as? RawEvent {
47-
// this is synchronized against finish(file:) down below.
48-
var currentFile = 0
49-
syncQueue.sync {
50-
let index: Int = userDefaults?.integer(forKey: key.rawValue) ?? 0
51-
userDefaults?.set(index, forKey: key.rawValue)
52-
currentFile = index
53-
}
54-
self.storeEvent(toFile: self.eventsFile(index: currentFile), event: event)
48+
let eventStoreFile = currentFile(key)
49+
self.storeEvent(toFile: eventStoreFile, event: event)
5550
}
5651
break
5752
default:
@@ -137,6 +132,16 @@ extension Storage {
137132
}
138133
return result
139134
}
135+
136+
func currentFile(_ key: Storage.Constants) -> URL {
137+
var currentFile = 0
138+
syncQueue.sync {
139+
let index: Int = userDefaults?.integer(forKey: key.rawValue) ?? 0
140+
userDefaults?.set(index, forKey: key.rawValue)
141+
currentFile = index
142+
}
143+
return self.eventsFile(index: currentFile)
144+
}
140145
}
141146

142147
// MARK: - State Subscriptions
@@ -212,19 +217,34 @@ extension Storage {
212217
// MARK: - Event Storage
213218

214219
extension Storage {
220+
215221
func storeEvent(toFile file: URL, event: RawEvent) {
222+
223+
var storeFile = file
224+
216225
let fm = FileManager.default
217226
var newFile = false
218-
if fm.fileExists(atPath: file.path) == false {
219-
start(file: file)
227+
if fm.fileExists(atPath: storeFile.path) == false {
228+
start(file: storeFile)
229+
newFile = true
230+
}
231+
232+
// Verify file size isn't too large
233+
if let attributes = try? fm.attributesOfItem(atPath: storeFile.path),
234+
let fileSize = attributes[FileAttributeKey.size] as? UInt64,
235+
fileSize >= Storage.MAXFILESIZE {
236+
finish(file: storeFile)
237+
// Set the new file path
238+
storeFile = currentFile(.events)
239+
start(file: storeFile)
220240
newFile = true
221241
}
222242

223243
syncQueue.sync {
224244
do {
225245
let jsonString = event.toString()
226246
if let jsonData = jsonString.data(using: .utf8) {
227-
let handle = try FileHandle(forWritingTo: file)
247+
let handle = try FileHandle(forWritingTo: storeFile)
228248
handle.seekToEndOfFile()
229249
// prepare for the next entry
230250
if newFile == false {
@@ -237,7 +257,7 @@ extension Storage {
237257
assert(false, "Storage: Unable to convert event to json!")
238258
}
239259
} catch {
240-
assert(false, "Storage: failed to write event to \(file), error: \(error)")
260+
assert(false, "Storage: failed to write event to \(storeFile), error: \(error)")
241261
}
242262
}
243263
}

0 commit comments

Comments
 (0)