Skip to content

[MOB-19274][MOB-15354] Use Disk for Storage Services#966

Merged
cdhoffmann merged 27 commits intoadobe:migrateOffUserDefaultsfrom
cdhoffmann:swapDataStore
Sep 7, 2023
Merged

[MOB-19274][MOB-15354] Use Disk for Storage Services#966
cdhoffmann merged 27 commits intoadobe:migrateOffUserDefaultsfrom
cdhoffmann:swapDataStore

Conversation

@cdhoffmann
Copy link
Copy Markdown
Contributor

Phase 1 of migration from UserDefaults as our storage mechanism. Next, we will be working on migrating existing data from UserDefaults to this new Disk storage.

@cdhoffmann cdhoffmann requested a review from praveek August 31, 2023 19:29
@codecov
Copy link
Copy Markdown

codecov bot commented Aug 31, 2023

Codecov Report

Merging #966 (8ea84f6) into migrateOffUserDefaults (eb4406a) will decrease coverage by 0.21%.
Report is 13 commits behind head on migrateOffUserDefaults.
The diff coverage is 88.89%.

❗ Current head 8ea84f6 differs from pull request most recent head fef2c3a. Consider uploading reports for the commit fef2c3a to get more accurate results

@@                    Coverage Diff                     @@
##           migrateOffUserDefaults     #966      +/-   ##
==========================================================
- Coverage                   90.22%   90.01%   -0.21%     
==========================================================
  Files                         130      131       +1     
  Lines                        8119     8221     +102     
==========================================================
+ Hits                         7325     7400      +75     
- Misses                        794      821      +27     

Comment thread TestApps/FileSystemNamedCollection.swift Outdated
Comment thread TestApps/FileSystemNamedCollection.swift Outdated
Comment thread AEPLifecycle/Tests/FunctionalTests/LifecycleFunctionalTests.swift Outdated
Comment thread AEPServices/Sources/ServiceProvider.swift Outdated
Comment thread AEPServices/Sources/storage/FileSystemNamedCollection.swift Outdated
Copy link
Copy Markdown
Contributor

@pfransenadb pfransenadb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Getting there -- quite a few questions/comments on FileSystemNamedCollection and NamedCollectionDataStore


func setAppGroup(_ appGroup: String?) {
self.appGroup = appGroup
if let appGroup = appGroup {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this function also handle setting appGroup to nil (and clearing the associated appGroupUrl?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also -- why not use get/set semantics on appGroup variable?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regardless of how it's done, setting/getting of appGroup needs to be done on queue as well.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that the get/set semantics would be cleaner, but the get/set function are part of the NamedCollectionProcessing protocol so we would be breaking compatibility by changing it. Or did you mean keeping the setAppGroup and getAppGroup functions and using the computed variable internally to handle the logic?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't consider that there was a pre-existing protocol -- makes sense, leave as is.

guard let fileUrl = fileUrl(for: collectionName) else {
return
}
queue.sync {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be async, this function doesn't need to return anything.

}

func remove(collectionName: String, key: String) {
queue.sync {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can also be async

}

func set(collectionName: String, key: String, value: Any?) {
guard let fileUrl = fileUrl(for: collectionName) else {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fileUrl needs to be called from within queue.sync to maintain ordering.

private var appGroupUrl: URL?
private let fileManager = FileManager.default
private let LOG_TAG = "FileSystemNamedCollection"
var appGroup: String?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should be private?

import Foundation

class FileSystemNamedCollection: NamedCollectionProcessing {
private let queue = DispatchQueue(label: "FileSystemNamedCollection.barrierQueue")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: isn't really a barrier, just a FIFO queue.

set(key: key, value: encodedValue)
guard let encodedValue = try? encoder.encode(value) else {return}
let encodedString = String(data: encodedValue, encoding: .utf8)
set(key: key, value: encodedString)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in previous code a failure to encode resulted in a nil value set (removal) -- is the change (failing to set and bailing due to the new guard statement) intentional, or was the previous behavior preferred/depended on?

Copy link
Copy Markdown
Contributor Author

@cdhoffmann cdhoffmann Sep 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good point. Not too sure if we were depending on this to be nil in failure scenarios. I think it's a matter of preference. I would prefer to simply return, as setting nil on a value when encoding fails feels odd to me. What do you think @praveek? Should we remove the guard and set nil when encoding fails?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I too prefer simply returning instead of setting nil value. However, I would like to maintain the same behavior as before since I'm uncertain whether other extensions depend on the previous behavior and want to keep all the changes for this migration only within Core.

do {
try fileManager.createDirectory(at: adobeBaseUrl, withIntermediateDirectories: true)
} catch {
Log.error(label: adobeDirectory, "Failed to create storage directory with error: \(error)")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you check if directory exists and exit before attempting to create a directory?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently Apple doesn't recommend that approach. https://developer.apple.com/documentation/foundation/filemanager/1410277-fileexists

If you see the note towards the bottom which says: "Attempting to predicate behavior based on the current state of the file system or a particular file on the file system is not recommended. Doing so can cause odd behavior or race conditions. It’s far better to attempt an operation (such as loading a file or creating a directory), check for errors, and handle those errors gracefully than it is to try to figure out ahead of time whether the operation will succeed."

I have tested this function, and if the directory exists, it doesn't do anything. So in our case it works just fine.

Comment thread AEPServices/Sources/storage/FileSystemNamedCollection.swift
@cdhoffmann cdhoffmann merged commit 909434e into adobe:migrateOffUserDefaults Sep 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants