Skip to content

Commit

Permalink
Uncaching in executors will use the Identity Model Repo
Browse files Browse the repository at this point in the history
* When Requests are uncached in the executors, hook them up to the same identity model instance via the Identity Model Repo
  • Loading branch information
nan-li committed Apr 25, 2024
1 parent e358a4f commit 3e2359e
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ class OSIdentityOperationExecutor: OSOperationExecutor {
if var deltaQueue = OneSignalUserDefaults.initShared().getSavedCodeableData(forKey: OS_IDENTITY_EXECUTOR_DELTA_QUEUE_KEY, defaultValue: []) as? [OSDelta] {
// Hook each uncached Delta to the model in the store
for (index, delta) in deltaQueue.enumerated().reversed() {
if let modelInStore = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: delta.model.modelId) {
// The model exists in the store, set it to be the Delta's model
if let modelInStore = OneSignalUserManagerImpl.sharedInstance.getIdentityModel(delta.model.modelId) {
// The model exists in the repo, set it to be the Delta's model
delta.model = modelInStore
} else {
// The model does not exist, drop this Delta
Expand All @@ -59,14 +59,14 @@ class OSIdentityOperationExecutor: OSOperationExecutor {
if var addRequestQueue = OneSignalUserDefaults.initShared().getSavedCodeableData(forKey: OS_IDENTITY_EXECUTOR_ADD_REQUEST_QUEUE_KEY, defaultValue: []) as? [OSRequestAddAliases] {
// Hook each uncached Request to the model in the store
for (index, request) in addRequestQueue.enumerated().reversed() {
if let identityModel = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: request.identityModel.modelId) {
// 1. The model exists in the store, so set it to be the Request's models
if let identityModel = OneSignalUserManagerImpl.sharedInstance.getIdentityModel(request.identityModel.modelId) {
// 1. The model exists in the repo, so set it to be the Request's models
request.identityModel = identityModel
} else if let identityModel = OSUserExecutor.identityModels[request.identityModel.modelId] {
// 2. The model exists in the user executor
request.identityModel = identityModel
} else if !request.prepareForExecution() {
// 3. The models do not exist AND this request cannot be sent, drop this Request
} else if request.prepareForExecution() {
// 2. The request can be sent, add the model to the repo
OneSignalUserManagerImpl.sharedInstance.addIdentityModelToRepo(request.identityModel)
} else {
// 3. The model do not exist AND this request cannot be sent, drop this Request
addRequestQueue.remove(at: index)
}
}
Expand All @@ -79,13 +79,13 @@ class OSIdentityOperationExecutor: OSOperationExecutor {
if var removeRequestQueue = OneSignalUserDefaults.initShared().getSavedCodeableData(forKey: OS_IDENTITY_EXECUTOR_REMOVE_REQUEST_QUEUE_KEY, defaultValue: []) as? [OSRequestRemoveAlias] {
// Hook each uncached Request to the model in the store
for (index, request) in removeRequestQueue.enumerated().reversed() {
if let identityModel = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: request.identityModel.modelId) {
// 1. The model exists in the store, so set it to be the Request's model
if let identityModel = OneSignalUserManagerImpl.sharedInstance.getIdentityModel(request.identityModel.modelId) {
// 1. The model exists in the repo, so set it to be the Request's model
request.identityModel = identityModel
} else if let identityModel = OSUserExecutor.identityModels[request.identityModel.modelId] {
// 2. The model exists in the user executor
request.identityModel = identityModel
} else if !request.prepareForExecution() {
} else if request.prepareForExecution() {
// 2. The request can be sent, add the model to the repo
OneSignalUserManagerImpl.sharedInstance.addIdentityModelToRepo(request.identityModel)
} else {
// 3. The model does not exist AND this request cannot be sent, drop this Request
removeRequestQueue.remove(at: index)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,9 @@ class OSPropertyOperationExecutor: OSOperationExecutor {
// Read unfinished deltas from cache, if any...
// Note that we should only have deltas for the current user as old ones are flushed..
if var deltaQueue = OneSignalUserDefaults.initShared().getSavedCodeableData(forKey: OS_PROPERTIES_EXECUTOR_DELTA_QUEUE_KEY, defaultValue: []) as? [OSDelta] {
// Hook each uncached Delta to the model in the store
for (index, delta) in deltaQueue.enumerated().reversed() {
if let modelInStore = OneSignalUserManagerImpl.sharedInstance.propertiesModelStore.getModel(modelId: delta.model.modelId) {
// 1. The model exists in the properties model store, set it to be the Delta's model
delta.model = modelInStore
} else {
// 2. The model does not exist, drop this Delta
if (OneSignalUserManagerImpl.sharedInstance.getIdentityModel(delta.identityModelId) == nil) {
// The identity model does not exist, drop this Delta
OneSignalLog.onesignalLog(.LL_WARN, message: "OSPropertyOperationExecutor.init dropped: \(delta)")
deltaQueue.remove(at: index)
}
Expand All @@ -61,13 +57,13 @@ class OSPropertyOperationExecutor: OSOperationExecutor {
if var updateRequestQueue = OneSignalUserDefaults.initShared().getSavedCodeableData(forKey: OS_PROPERTIES_EXECUTOR_UPDATE_REQUEST_QUEUE_KEY, defaultValue: []) as? [OSRequestUpdateProperties] {
// Hook each uncached Request to the model in the store
for (index, request) in updateRequestQueue.enumerated().reversed() {
if let identityModel = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: request.identityModel.modelId) {
// 1. The identity model exist in the store, set it to be the Request's models
request.identityModel = identityModel
} else if let identityModel = OSUserExecutor.identityModels[request.identityModel.modelId] {
// 2. The model exists in the user executor
if let identityModel = OneSignalUserManagerImpl.sharedInstance.getIdentityModel(request.identityModel.modelId) {
// 1. The identity model exist in the repo, set it to be the Request's model
request.identityModel = identityModel
} else if !request.prepareForExecution() {
} else if request.prepareForExecution() {
// 2. The request can be sent, add the model to the repo
OneSignalUserManagerImpl.sharedInstance.addIdentityModelToRepo(request.identityModel)
} else {
// 3. The identitymodel do not exist AND this request cannot be sent, drop this Request
OneSignalLog.onesignalLog(.LL_WARN, message: "OSPropertyOperationExecutor.init dropped: \(request)")
updateRequestQueue.remove(at: index)
Expand Down Expand Up @@ -99,11 +95,17 @@ class OSPropertyOperationExecutor: OSOperationExecutor {
OneSignalLog.onesignalLog(.LL_VERBOSE, message: "OSPropertyOperationExecutor processDeltaQueue with queue: \(self.deltaQueue)")
}
for delta in self.deltaQueue {
guard let identityModel = OneSignalUserManagerImpl.sharedInstance.getIdentityModel(delta.identityModelId)
else {
// drop this delta
continue
}

let request = OSRequestUpdateProperties(
properties: [delta.property: delta.value],
deltas: nil,
refreshDeviceMetadata: false, // Sort this out.
identityModel: OneSignalUserManagerImpl.sharedInstance.user.identityModel // TODO: Make sure this is ok
identityModel: identityModel
)
self.updateRequestQueue.append(request)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,15 @@ class OSSubscriptionOperationExecutor: OSOperationExecutor {
subscriptionModels[request.subscriptionModel.modelId] = request.subscriptionModel
}
// 2. Hook up the identity model
if let identityModel = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: request.identityModel.modelId) {
// a. The model exist in the store
if let identityModel = OneSignalUserManagerImpl.sharedInstance.getIdentityModel(request.identityModel.modelId) {
// a. The model exist in the repo
request.identityModel = identityModel
} else if let identityModel = OSUserExecutor.identityModels[request.identityModel.modelId] {
// b. The model exist in the user executor
request.identityModel = identityModel
} else if !request.prepareForExecution() {
// The model do not exist AND this request cannot be sent, drop this Request
} else if request.prepareForExecution() {
// b. The request can be sent, add the model to the repo
OneSignalUserManagerImpl.sharedInstance.addIdentityModelToRepo(request.identityModel)
} else {
// c. The model do not exist AND this request cannot be sent, drop this Request
OneSignalLog.onesignalLog(.LL_WARN, message: "OSSubscriptionOperationExecutor.init dropped: \(request)")
continue
}
requestQueue.append(request)
Expand Down Expand Up @@ -161,29 +162,31 @@ class OSSubscriptionOperationExecutor: OSOperationExecutor {
OneSignalLog.onesignalLog(.LL_VERBOSE, message: "OSSubscriptionOperationExecutor processDeltaQueue with queue: \(deltaQueue)")
}
for delta in deltaQueue {
guard let model = delta.model as? OSSubscriptionModel else {
// Log error
guard let subModel = delta.model as? OSSubscriptionModel,
let identityModel = OneSignalUserManagerImpl.sharedInstance.getIdentityModel(delta.identityModelId)
else {
OneSignalLog.onesignalLog(.LL_ERROR, message: "OSSubscriptionOperationExecutor processDeltaQueue dropping OSDelta: \(delta)")
continue
}

switch delta.name {
case OS_ADD_SUBSCRIPTION_DELTA:
let request = OSRequestCreateSubscription(
subscriptionModel: model,
identityModel: OneSignalUserManagerImpl.sharedInstance.user.identityModel // TODO: Make sure this is ok
subscriptionModel: subModel,
identityModel: identityModel
)
addRequestQueue.append(request)

case OS_REMOVE_SUBSCRIPTION_DELTA:
let request = OSRequestDeleteSubscription(
subscriptionModel: model
subscriptionModel: subModel
)
removeRequestQueue.append(request)

case OS_UPDATE_SUBSCRIPTION_DELTA:
let request = OSRequestUpdateSubscription(
subscriptionObject: [delta.property: delta.value],
subscriptionModel: model
subscriptionModel: subModel
)
updateRequestQueue.append(request)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import OneSignalOSCore
class OSUserExecutor {
static var userRequestQueue: [OSUserRequest] = []
static var transferSubscriptionRequestQueue: [OSRequestTransferSubscription] = []
static var identityModels: [String: OSIdentityModel] = [:]

// Read in requests from the cache, do not read in FetchUser requests as this is not needed.
static func start() {
Expand All @@ -47,58 +46,48 @@ class OSUserExecutor {
// Hook each uncached Request to the right model reference
for request in cachedRequestQueue {
if request.isKind(of: OSRequestFetchIdentityBySubscription.self), let req = request as? OSRequestFetchIdentityBySubscription {
if let identityModel = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: req.identityModel.modelId) {
// 1. The model exist in the store, set it to be the Request's model
req.identityModel = identityModel
} else if let identityModel = identityModels[req.identityModel.modelId] {
// 2. The model exists in the dict of identityModels already processed to use
if let identityModel = getIdentityModel(req.identityModel.modelId) {
// 1. The model exist in the repo, set it to be the Request's model
// It is the current user or the model has already been processed
req.identityModel = identityModel
} else {
// 3. The models do not exist, use the model on the request, and add to dict.
identityModels[req.identityModel.modelId] = req.identityModel
// 2. The model do not exist, use the model on the request, and add to repo.
addIdentityModel(req.identityModel)
}
userRequestQueue.append(req)

} else if request.isKind(of: OSRequestCreateUser.self), let req = request as? OSRequestCreateUser {
if let identityModel = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: req.identityModel.modelId) {
// 1. The model exist in the store, set it to be the Request's model
req.identityModel = identityModel
} else if let identityModel = identityModels[req.identityModel.modelId] {
// 2. The model exists in the dict of identityModels already processed to use
if let identityModel = getIdentityModel(req.identityModel.modelId) {
// 1. The model exist in the repo, set it to be the Request's model
req.identityModel = identityModel
} else {
// 3. The models do not exist, use the model on the request, and add to dict.
identityModels[req.identityModel.modelId] = req.identityModel
// 2. The models do not exist, use the model on the request, and add to repo.
addIdentityModel(req.identityModel)
}
userRequestQueue.append(req)

} else if request.isKind(of: OSRequestIdentifyUser.self), let req = request as? OSRequestIdentifyUser {

if let identityModelToIdentify = identityModels[req.identityModelToIdentify.modelId],
let identityModelToUpdate = OneSignalUserManagerImpl.sharedInstance.identityModelStore.getModel(modelId: req.identityModelToUpdate.modelId) {
// 1. A model exist in the dict and a model exist in the store, set it to be the Request's models
req.identityModelToIdentify = identityModelToIdentify
req.identityModelToUpdate = identityModelToUpdate
} else if let identityModelToIdentify = identityModels[req.identityModelToIdentify.modelId],
let identityModelToUpdate = identityModels[req.identityModelToUpdate.modelId] {
// 2. The two models exist in the dict, set it to be the Request's models
if let identityModelToIdentify = getIdentityModel(req.identityModelToIdentify.modelId),
let identityModelToUpdate = getIdentityModel(req.identityModelToUpdate.modelId) {
// 1. Both models exist in the repo, set it to be the Request's models
req.identityModelToIdentify = identityModelToIdentify
req.identityModelToUpdate = identityModelToUpdate
} else if let identityModelToIdentify = identityModels[req.identityModelToIdentify.modelId],
identityModels[req.identityModelToUpdate.modelId] == nil {
// 3. A model is in the dict, the other model does not exist
} else if let identityModelToIdentify = getIdentityModel(req.identityModelToIdentify.modelId),
getIdentityModel(req.identityModelToUpdate.modelId) == nil {
// 2. A model is in the repo, the other model does not exist
req.identityModelToIdentify = identityModelToIdentify
identityModels[req.identityModelToUpdate.modelId] = req.identityModelToUpdate
addIdentityModel(req.identityModelToUpdate)
} else {
// 4. Both models don't exist yet
// 3. Both models don't exist yet
// Drop the request if the identityModelToIdentify does not already exist AND the request is missing OSID
// Otherwise, this request will forever fail `prepareForExecution` and block pending requests such as recovery calls to `logout` or `login`
guard request.prepareForExecution() else {
OneSignalLog.onesignalLog(.LL_ERROR, message: "OSUserExecutor.start() dropped: \(request)")
continue
}
identityModels[req.identityModelToIdentify.modelId] = req.identityModelToIdentify
identityModels[req.identityModelToUpdate.modelId] = req.identityModelToUpdate
addIdentityModel(req.identityModelToIdentify)
addIdentityModel(req.identityModelToUpdate)
}
userRequestQueue.append(req)
}
Expand Down Expand Up @@ -128,6 +117,14 @@ class OSUserExecutor {
executePendingRequests()
}

static private func getIdentityModel(_ modelId: String) -> OSIdentityModel? {
return OneSignalUserManagerImpl.sharedInstance.getIdentityModel(modelId)
}

static private func addIdentityModel(_ model: OSIdentityModel) {
OneSignalUserManagerImpl.sharedInstance.addIdentityModelToRepo(model)
}

static func appendToQueue(_ request: OSUserRequest) {
if request.isKind(of: OSRequestTransferSubscription.self), let req = request as? OSRequestTransferSubscription {
self.transferSubscriptionRequestQueue.append(req)
Expand Down

0 comments on commit 3e2359e

Please sign in to comment.