client parameter stats changes

This commit is contained in:
Kyle Matthew Hedden 2022-08-30 17:51:36 -04:00
parent 571d55aebd
commit 55d6df4e25
2 changed files with 32 additions and 35 deletions

View File

@ -7,16 +7,15 @@
//
@objcMembers open class ClientParameterHandler: NSObject {
var parameterHandlerList: [ClientParameterProtocol] = []
let parametersWorkQueue = DispatchQueue(label: "com.mva.clientparameter")
let group = DispatchGroup()
static let DefaultTimeout = 30.0
open func createParametersHandler(_ clientParameterModel: ClientParameterModelProtocol) -> ClientParameterProtocol? {
do {
let parameterType = try ModelRegistry.getHandler(clientParameterModel) as! ClientParameterProtocol.Type
return parameterType.init(clientParameterModel)
} catch {
MVMCoreLoggingHandler.shared()?.logCoreEvent(.clientParameterNotFound(name: clientParameterModel.type))
if let errorObject = MVMCoreErrorObject.createErrorObject(for: error, location: #function) {
MVMCoreLoggingHandler.addError(toLog: errorObject)
}
@ -52,29 +51,29 @@
}
open func getParameters(with model: ClientParameterModel, requestParameters: [String: Any], completionHandler:@escaping ([String: Any]?) -> ()) throws {
let timeout = model.timeout ?? 30.0
let parametersWorkQueue = DispatchQueue(label: "com.mva.clientparameter")
let group = DispatchGroup()
let timeout = model.timeout ?? Self.DefaultTimeout
let parameterHandlerList = model.list.compactMap { createParametersHandler($0) }
let requestUUID = [0..<parameterHandlerList.count].map { _ in UUID().uuidString }
var returnedList = [[String: AnyHashable]?](repeating: nil, count: parameterHandlerList.count)
// Dispatch setup on queue to ensure setup is complete before completion callbacks.
// Don't use [weak self]. Object is deallocated in the dispatch queue.
parametersWorkQueue.async(group: group, qos: .userInitiated) {
// Create the handler list so that same object can be used when merging. Merging needs default value in case of timeout
for parameterModel in model.list {
if let parameterHandler = self.createParametersHandler(parameterModel) {
self.parameterHandlerList.append(parameterHandler)
}
}
var returnedList = [[String: AnyHashable]?](repeating: nil, count: self.parameterHandlerList.count)
var mergedParametersList: [String: AnyHashable] {
var parametersList: [String: AnyHashable] = [:]
for (index, item) in returnedList.enumerated() {
let parameter = item ?? self.parameterHandlerList[index].valueOnTimeout()
parametersList = parametersList.merging(parameter) { (_, new) in new }
return returnedList.enumerated().map { (index, element) -> [String: AnyHashable] in
guard let parameter = element else {
MVMCoreLoggingHandler.shared()?.logCoreEvent(.clientParameterTimeout(name: model.list[index].type, uuid: requestUUID[index]))
return parameterHandlerList[index].valueOnTimeout()
}
return parameter
}.reduce(into: [String: AnyHashable]()) { partialResult, next in
partialResult.merge(next) { first, last in first }
}
return parametersList
}
// Setup completion handlers. Barriered to ensure one happens after the other.
@ -92,28 +91,30 @@
}
// Setup timeout.
self.parametersWorkQueue.asyncAfter(deadline: .now() + .seconds(Int(timeout)), execute: timeoutWorkItem)
parametersWorkQueue.asyncAfter(deadline: .now() + .seconds(Int(timeout)), execute: timeoutWorkItem)
// Setup the parameter execution.
for (index, parameterHandler) in self.parameterHandlerList.enumerated() {
for (index, parameterHandler) in parameterHandlerList.enumerated() {
let parameterType = parameterHandler.clientParameterModel.type
self.group.enter()
MVMCoreLoggingHandler.shared()?.logCoreEvent(.clientParameterFetching(name: parameterType, uuid: requestUUID[index]))
group.enter()
parameterHandler.fetchClientParameters(requestParameters: requestParameters,
timingOutIn: timeout) { (receivedParameter) in
// Queue the results for merge.
self.parametersWorkQueue.async {
parametersWorkQueue.async {
if (returnedList[index] != nil) {
MVMCoreLoggingHandler.addError(toLog: MVMCoreErrorObject(title: nil, message: "Client parameter \(parameterType) has already executed. The completion handler should only be called once!", code: ErrorCode.default.rawValue, domain: ErrorDomainNative, location: String(describing: ClientParameterHandler.self))!)
} else {
MVMCoreLoggingHandler.shared()?.logCoreEvent(.clientParameterFetchComplete(name: parameterType, uuid: requestUUID[index]))
returnedList[index] = receivedParameter
self.group.leave() // Leaving is only done after setup (barriered).
group.leave() // Leaving is only done after setup (barriered).
}
}
}
}
// Callback when all parameters have been merged.
self.group.notify(queue: self.parametersWorkQueue, work: completionWorkItem);
group.notify(queue: parametersWorkQueue, work: completionWorkItem);
}
}
}

View File

@ -56,28 +56,24 @@ public enum MVMCoreEvent {
/// Could not find the client parameter specified.
case clientParameterNotFound(
name: String,
pageType: String
name: String
)
/// The client perameter handler was invoked and is in progress.
case clientParameterFetching(
name: String,
pageType: String,
uuid: String
)
/// The client perameter handler timed out and is returning a default value.
case clientParameterTimeout(
name: String,
pageType: String,
uuid: String
)
/// The client paramter fetch completed.
case clientParameterComplete(
case clientParameterFetchComplete(
name: String,
pageType: String,
uuid: String
)
@ -100,7 +96,7 @@ public enum MVMCoreEvent {
case .clientParameterNotFound: return .clientParameter
case .clientParameterFetching: return .clientParameter
case .clientParameterTimeout: return .clientParameter
case .clientParameterComplete: return .clientParameter
case .clientParameterFetchComplete: return .clientParameter
}
}