Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancements/disable retry on no network #62

Merged
merged 13 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Sources/Clickstream/Core/Data/Constants/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ enum Constants {
public static var success = "success"
public static var failure = "failure"
public static var networkType = "networkType"
public static let clickstreamVersion = "2.0.26"
}

// MARK: - SDK Defaults
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ enum NetworkType: Equatable {
case wwan2g
case wwan3g
case wwan4g
case wwan5g
case unknownTechnology(name: String)

var trackingId: String {
Expand All @@ -27,6 +28,7 @@ enum NetworkType: Equatable {
case .wwan2g: return "2G"
case .wwan3g: return "3G"
case .wwan4g: return "4G"
case .wwan5g: return "5G"
case .unknownTechnology(let name): return "Unknown Technology: \"\(name)\""
}
}
Expand All @@ -51,7 +53,18 @@ extension Reachability {
}

internal static func getWWANNetworkType() -> NetworkType {
guard let currentRadioAccessTechnology = CTTelephonyNetworkInfo().currentRadioAccessTechnology else { return .unknown }
var _currentRadioAccessTechnology: String? = nil
if let accessTechnology = CTTelephonyNetworkInfo().serviceCurrentRadioAccessTechnology?.values.first{
_currentRadioAccessTechnology = accessTechnology
}

guard let currentRadioAccessTechnology = _currentRadioAccessTechnology else { return .unknown }

if #available(iOS 14.1, *) {
if currentRadioAccessTechnology == CTRadioAccessTechnologyNRNSA || currentRadioAccessTechnology == CTRadioAccessTechnologyNR{
return .wwan5g
}
}
switch currentRadioAccessTechnology {
case CTRadioAccessTechnologyGPRS,
CTRadioAccessTechnologyEdge,
Expand All @@ -70,5 +83,5 @@ extension Reachability {
default:
return .unknownTechnology(name: currentRadioAccessTechnology)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@ extension DefaultEventWarehouser {
#endif
#if TRACKER_ENABLED
let healthEvent = HealthAnalysisEvent(eventName: .ClickstreamEventCached,
eventGUID: event.guid)
eventGUID: event.guid,
eventCount: 1)
if event.type != Constants.EventType.instant.rawValue {
Tracker.sharedInstance?.record(event: healthEvent)
}
Expand Down
5 changes: 3 additions & 2 deletions Sources/Clickstream/NetworkManager/Core/NetworkBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ extension DefaultNetworkBuilder {
checkedSelf.trackHealthEvents(eventBatch: eventBatch,
eventBatchData: data)
}

eventRequest.eventCount = eventBatch.events.count
checkedSelf.retryMech.trackBatch(with: eventRequest)
#if EVENT_VISUALIZER_ENABLED
/// Update status of the event batch to sent to network
Expand Down Expand Up @@ -114,7 +114,8 @@ extension DefaultNetworkBuilder {

let healthEvent = HealthAnalysisEvent(eventName: .ClickstreamBatchSent,
events: eventGUIDsString,
eventBatchGUID: eventBatch.uuid)
eventBatchGUID: eventBatch.uuid,
eventCount: eventBatch.events.count)
Tracker.sharedInstance?.record(event: healthEvent)
#endif
}
Expand Down
34 changes: 14 additions & 20 deletions Sources/Clickstream/NetworkManager/Core/RetryMechanism.swift
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,8 @@ extension DefaultRetryMechanism {
var healthEvent: HealthAnalysisEvent!
healthEvent = HealthAnalysisEvent(eventName: .ClickstreamWriteToSocketFailed,
eventBatchGUID: eventRequest.guid,
reason: FailureReason.ParsingException.rawValue)
reason: FailureReason.ParsingException.rawValue,
eventCount: eventRequest.eventCount)
Tracker.sharedInstance?.record(event: healthEvent)
#if ETE_TEST_SUITE_ENABLED
Clickstream.ackEvent = AckEventDetails(guid: eventRequest.guid, status: "Bad Request")
Expand All @@ -269,7 +270,8 @@ extension DefaultRetryMechanism {
#if TRACKER_ENABLED
let healthEvent = HealthAnalysisEvent(eventName: .ClickstreamEventBatchErrorResponse,
eventBatchGUID: eventRequest.guid, // eventRequest.guid is the batch GUID
reason: error.localizedDescription)
reason: error.localizedDescription,
eventCount: eventRequest.eventCount)
Tracker.sharedInstance?.record(event: healthEvent)
#if ETE_TEST_SUITE_ENABLED
Clickstream.ackEvent = AckEventDetails(guid: eventRequest.guid, status: "\(error)")
Expand Down Expand Up @@ -381,8 +383,9 @@ extension DefaultRetryMechanism {
persistence.deleteOne(eventRequest.guid)
#if TRACKER_ENABLED
if Tracker.debugMode {
let healthEvent = HealthAnalysisEvent(eventName: .ClickstreamEventBatchTimeout,
eventBatchGUID: fetchedEventRequest.guid)
let healthEvent = HealthAnalysisEvent(eventName: .ClickstreamEventBatchDropped,
eventBatchGUID: fetchedEventRequest.guid,
eventCount: eventRequest.eventCount)
Tracker.sharedInstance?.record(event: healthEvent)
}
#endif
Expand Down Expand Up @@ -419,6 +422,11 @@ extension DefaultRetryMechanism {


private func retryFailedBatches() {
guard isAvailble else {
stopObservingFailedBatches()
return
}

if let failedRequests = persistence.fetchAll(), !failedRequests.isEmpty {
let date = Date()
let timedOutRequests = failedRequests.filter {
Expand Down Expand Up @@ -452,21 +460,6 @@ extension DefaultRetryMechanism {
}

// MARK: - Track Clickstream health.
extension DefaultRetryMechanism {
func trackHealthEvents(eventRequest: EventRequest) {
#if TRACKER_ENABLED
if Tracker.debugMode {
guard eventRequest.eventType != Constants.EventType.instant else { return }

let healthEvent = HealthAnalysisEvent(eventName: .ClickstreamEventBatchSuccessAck,
eventBatchGUID: eventRequest.guid)
Tracker.sharedInstance?.record(event: healthEvent)

}
#endif
}
}

extension DefaultRetryMechanism {

func trackHealthAndPerformanceEvents(eventRequest: EventRequest, startTime: Date) {
Expand All @@ -475,7 +468,8 @@ extension DefaultRetryMechanism {
guard eventRequest.eventType != Constants.EventType.instant else { return }

let healthEvent = HealthAnalysisEvent(eventName: .ClickstreamEventBatchSuccessAck,
eventBatchGUID: eventRequest.guid)
eventBatchGUID: eventRequest.guid,
eventCount: eventRequest.eventCount)
Tracker.sharedInstance?.record(event: healthEvent)

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct EventRequest: Codable, Equatable {
var createdTimestamp: Date?
var eventType: Constants.EventType?
var isInternal: Bool?
var eventCount: Int

init(guid: String,
data: Data? = nil) {
Expand All @@ -29,6 +30,7 @@ struct EventRequest: Codable, Equatable {
self.createdTimestamp = Date()
self.isInternal = false
self.eventType = .realTime
self.eventCount = 0
}

static func == (lhs: Self, rhs: Self) -> Bool {
Expand Down Expand Up @@ -62,6 +64,7 @@ extension EventRequest: DatabasePersistable {
t.column("data", .blob)
t.column("retriesMade", .text).notNull()
t.column("createdTimestamp", .datetime).notNull()
t.column("eventCount", .integer).notNull()
}
}
}
Expand All @@ -86,6 +89,13 @@ extension EventRequest: DatabasePersistable {
t.add(column: "eventType", .text)
}

return [("addsIsInternalToEventRequest", addsIsInternal), ("addsEventTypeToEventRequest", addsEventType)]
let addsEventCount: (TableAlteration) -> Void = { t in
t.add(column: "eventCount", .integer).notNull().defaults(to: 0)
}

return [("addsIsInternalToEventRequest", addsIsInternal),
("addsEventTypeToEventRequest", addsEventType),
("addsEventCountToEventRequest", addsEventCount)
]
}
}
17 changes: 14 additions & 3 deletions Sources/Tracker/Health/HealthAnalysisEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@ struct HealthAnalysisEvent: Codable, Equatable, AnalysisEvent {

private(set) var timeToConnection: String?

private(set) var eventCount: Int

init?(eventName: HealthEvents,
events: String? = nil,
eventGUID: String? = nil,
eventBatchGUID: String? = nil,
reason: String? = nil,
timeToConnection: String? = nil) {
timeToConnection: String? = nil,
eventCount: Int = 0) {

// Don't initialize if debugMode is off
guard Tracker.debugMode else {
Expand All @@ -68,12 +71,13 @@ struct HealthAnalysisEvent: Codable, Equatable, AnalysisEvent {
self.guid = UUID().uuidString
self.sessionID = Tracker.sharedInstance?.commonProperties?.session.sessionId
self.timeToConnection = timeToConnection
self.eventCount = eventCount

self.trackedVia = Tracker.healthTrackingConfigs.trackedVia.rawValue
}

private enum CodingKeys : String, CodingKey {
case guid,eventName,eventType,timestamp,reason,eventGUID,eventBatchGUID,events,sessionID,trackedVia, timeToConnection
case guid,eventName,eventType,timestamp,reason,eventGUID,eventBatchGUID,events,sessionID,trackedVia, timeToConnection, eventCount
}

static func == (lhs: HealthAnalysisEvent, rhs: HealthAnalysisEvent) -> Bool {
Expand Down Expand Up @@ -110,6 +114,8 @@ extension HealthAnalysisEvent: Notifiable {
properties[TrackerConstant.clickstream_error_reason] = reason
}

properties[TrackerConstant.clickstream_event_count] = eventCount

let dict: [String : Any] = [TrackerConstant.eventName: eventName.rawValue,
TrackerConstant.eventProperties: properties]
NotificationCenter.default.post(name: TrackerConstant.DebugEventsNotification, object: dict)
Expand All @@ -130,6 +136,7 @@ extension HealthAnalysisEvent: DatabasePersistable {
t.column("eventBatchGUID", .text)
t.column("events", .text)
t.column("sessionID", .text)
t.column("eventCount", .integer)
}
}
}
Expand All @@ -153,6 +160,10 @@ extension HealthAnalysisEvent: DatabasePersistable {
t.add(column: "timeToConnection", .text)
}

return [("addsTrackedViaToHealthEvent", addsTrackedVia), ("addsTimeToConnectionToHealthEvent", addsTimeToConnection)]
let addsEventCount: (TableAlteration) -> Void = { t in
t.add(column: "eventCount", .integer).defaults(to: 0)
}

return [("addsTrackedViaToHealthEvent", addsTrackedVia), ("addsTimeToConnectionToHealthEvent", addsTimeToConnection), ("addsEventCountToHealthEvent", addsEventCount)]
}
}
13 changes: 11 additions & 2 deletions Sources/Tracker/Tracker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,20 @@ public final class Tracker {
}
}
}

var eventCount = 0
for e in eventNameBasedAggregation {
if e.eventCount > 0 {
eventCount += e.eventCount
} else {
eventCount = 0
break /// break the loop and reset event count. If any one of the event has eventCount -1, final eventCount in aggregated event will be wrong and will be of no use
}
}

let eventBatchGuids = eventNameBasedAggregation.compactMap { $0.eventBatchGUID }

var healthEvent = Gojek_Clickstream_Internal_Health.with {
$0.numberOfEvents = Int64(eventGuids.count)
$0.numberOfEvents = eventCount > 0 ? Int64(eventCount) : Int64(eventGuids.count)
$0.numberOfBatches = Int64(eventBatchGuids.count)
$0.healthMeta = metaData
$0.healthMeta.eventGuid = eventGuid
Expand Down
6 changes: 4 additions & 2 deletions Sources/Tracker/Utilities/TrackerConstants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ enum HealthEvents: String, Codable, CaseIterable {
case ClickstreamEventBatchTriggerFailed = "Clickstream Event Batch Trigger Failed"
case ClickstreamWriteToSocketFailed = "Clickstream Write to Socket Failed"
case ClickstreamEventBatchErrorResponse = "Clickstream Event Batch Error response"
case ClickstreamEventBatchTimeout = "Clickstream Event Batch Timeout"
case ClickstreamEventBatchDropped = "Clickstream Event Batch Dropped"

case ClickstreamConnectionSuccess = "Clickstream Connection Success"
case ClickstreamConnectionFailure = "Clickstream Connection Failure"
Expand Down Expand Up @@ -65,6 +65,8 @@ public struct TrackerConstant {
static var deviceMake = "Apple"
static var deviceOS = "iOS"

static let appState = "app_state"

public static let eventName = "eventName"
public static let eventProperties = "event_properties"
public static let clickstream_timestamp = "clickstream_timestamp"
Expand All @@ -86,5 +88,5 @@ public struct TrackerConstant {
case aggregate = "aggregate"
}

static let InstantEvents: [HealthEvents] = [.ClickstreamEventBatchTimeout, .ClickstreamConnectionSuccess, .ClickstreamConnectionFailure, .ClickstreamEventBatchErrorResponse, .ClickstreamWriteToSocketFailed, .ClickstreamEventBatchTriggerFailed]
static let InstantEvents: [HealthEvents] = [.ClickstreamEventBatchDropped, .ClickstreamConnectionSuccess, .ClickstreamConnectionFailure, .ClickstreamEventBatchErrorResponse, .ClickstreamWriteToSocketFailed, .ClickstreamEventBatchTriggerFailed]
}
Loading