Skip to content

Commit

Permalink
(5.0) Fix of crash when logging is enabled. (#115)
Browse files Browse the repository at this point in the history
Also removed unused test code. Improve documentation on LDClient.flush()
  • Loading branch information
gwhelanLD authored Jul 17, 2020
1 parent f4b4af2 commit fdada02
Show file tree
Hide file tree
Showing 15 changed files with 28 additions and 151 deletions.
8 changes: 6 additions & 2 deletions LaunchDarkly/LaunchDarkly/LDClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -797,8 +797,12 @@ public class LDClient {
}

/**
Report events to LaunchDarkly servers. While online, the LDClient automatically reports events on the `LDConfig.eventFlushInterval`, and whenever the client app moves to the background. There should normally not be a need to call reportEvents.
*/
Tells the SDK to immediately send any currently queued events to LaunchDarkly.

There should not normally be a need to call this function. While online, the LDClient automatically reports events
on an interval defined by `LDConfig.eventFlushInterval`. Note that this function does not block until events are
sent, it only triggers a background task to send events immediately.
*/
public func flush() {
LDClient.instances?.forEach { $1.internalFlush() }
}
Expand Down
6 changes: 5 additions & 1 deletion LaunchDarkly/LaunchDarkly/ObjectiveC/ObjcLDClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,11 @@ public final class ObjcLDClient: NSObject {
}

/**
Report events to LaunchDarkly servers. While online, the LDClient automatically reports events on the `LDConfig.eventFlushInterval`, and whenever the client app moves to the background. There should normally not be a need to call reportEvents.
Tells the SDK to immediately send any currently queued events to LaunchDarkly.

There should not normally be a need to call this function. While online, the LDClient automatically reports events
on an interval defined by `LDConfig.eventFlushInterval`. Note that this function does not block until events are
sent, it only triggers a background task to send events immediately.
*/
@objc public func flush() {
ldClient.flush()
Expand Down
9 changes: 0 additions & 9 deletions LaunchDarkly/LaunchDarkly/Service Objects/ErrorNotifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,6 @@ final class ErrorNotifier: ErrorNotifying {

#if DEBUG
extension ErrorNotifier {
convenience init(observers: [ErrorObserver]? = nil) {
self.init()
guard let observers = observers, observers.isEmpty == false
else {
return
}
errorObservers.append(contentsOf: observers)
}

func erase(owner: LDObserverOwner) {
for index in 0..<errorObservers.count {
guard errorObservers[index].owner === owner
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class EventReporter: EventReporting {
set {
isOnlineQueue.sync {
_isOnline = newValue
Log.debug(typeName(and: #function, appending: ": ") + "\(isOnline)")
Log.debug(typeName(and: #function, appending: ": ") + "\(_isOnline)")
_isOnline ? startReporting(isOnline: _isOnline) : stopReporting()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,14 @@ class FlagSynchronizer: LDFlagSynchronizing, EventHandler {
set {
isOnlineQueue.sync {
_isOnline = newValue
Log.debug(typeName(and: #function, appending: ": ") + "\(isOnline)")
Log.debug(typeName(and: #function, appending: ": ") + "\(_isOnline)")
configureCommunications(isOnline: _isOnline)
}
}
}

private var _isOnline = false
private var isOnlineQueue = DispatchQueue(label: "com.launchdarkly.DiagnosticReporter.isOnlineQueue")
private var isOnlineQueue = DispatchQueue(label: "com.launchdarkly.FlagSynchronizer.isOnlineQueue")
let pollingInterval: TimeInterval
let useReport: Bool

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ final class DictionarySpec: QuickSpec {
public override func spec() {
symmetricDifferenceSpec()
withNullValuesRemovedSpec()
dictionarySpec()
}

private func symmetricDifferenceSpec() {
Expand Down Expand Up @@ -211,10 +212,6 @@ fileprivate extension Dictionary where Key == String, Value == Any {
static var null: String {
return "null-key"
}

static var all: [String] {
return [bool, int, double, string, array, dictionary, null]
}
}

struct Values {
Expand All @@ -239,10 +236,6 @@ fileprivate extension Dictionary where Key == String, Value == Any {
static var null: NSNull {
return NSNull()
}

static var all: [Any] {
return [bool, int, double, string, array, dictionary, null]
}
}

static func stub() -> [String: Any] {
Expand Down
34 changes: 0 additions & 34 deletions LaunchDarkly/LaunchDarklyTests/LDClientSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,6 @@ final class LDClientSpec: QuickSpec {
var onSyncComplete: FlagSyncCompleteClosure? {
return serviceFactoryMock.onFlagSyncComplete
}
// flag maintaining mock accessors
var replaceStoreComplete: CompletionClosure? {
return flagStoreMock.replaceStoreReceivedArguments?.completion
}
var updateStoreComplete: CompletionClosure? {
return flagStoreMock.updateStoreReceivedArguments?.completion
}
var deleteFlagComplete: CompletionClosure? {
return flagStoreMock.deleteFlagReceivedArguments?.completion
}
var recordedEvent: LaunchDarkly.Event? {
eventReporterMock.recordReceivedEvent
}
Expand Down Expand Up @@ -2597,27 +2587,3 @@ extension CacheConvertingMock {
convertCacheDataReceivedArguments = nil
}
}

extension LDConfig {
func copyReplacingMobileKey(_ mobileKey: MobileKey) -> LDConfig {
var newConfig = LDConfig(mobileKey: mobileKey)
newConfig.baseUrl = baseUrl
newConfig.eventsUrl = eventsUrl
newConfig.streamUrl = streamUrl
newConfig.eventCapacity = eventCapacity
newConfig.connectionTimeout = connectionTimeout
newConfig.eventFlushInterval = eventFlushInterval
newConfig.flagPollingInterval = flagPollingInterval
newConfig.backgroundFlagPollingInterval = backgroundFlagPollingInterval
newConfig.streamingMode = streamingMode
newConfig.enableBackgroundUpdates = enableBackgroundUpdates
newConfig.startOnline = startOnline
newConfig.allUserAttributesPrivate = allUserAttributesPrivate
newConfig.privateUserAttributes = privateUserAttributes
newConfig.useReport = useReport
newConfig.inlineUserInEvents = inlineUserInEvents
newConfig.isDebugMode = isDebugMode

return newConfig
}
}
6 changes: 0 additions & 6 deletions LaunchDarkly/LaunchDarklyTests/Models/ErrorObserverSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ final class ErrorOwnerMock {
}
}

extension ErrorObserver {
static func createObservers(count: Int, using owner: ErrorOwnerMock = ErrorOwnerMock()) -> [ErrorObserver] {
(0..<count).map { _ in ErrorObserver(owner: owner, errorHandler: owner.handle) }
}
}

final class ErrorObserverSpec: QuickSpec {

override func spec() {
Expand Down
55 changes: 0 additions & 55 deletions LaunchDarkly/LaunchDarklyTests/Models/EventSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1306,13 +1306,6 @@ extension Array where Element == [String: Any] {
}
}

extension Event.Kind {
static var random: Event.Kind {
let index = Int(arc4random_uniform(UInt32(Event.Kind.allKinds.count) - 1))
return Event.Kind.allKinds[index]
}
}

extension Event {
static func stub(_ eventKind: Kind, with user: LDUser) -> Event {
switch eventKind {
Expand All @@ -1328,10 +1321,6 @@ extension Event {
}
}

static func stubFeatureEvent(_ featureFlag: FeatureFlag, with user: LDUser) -> Event {
return Event.featureEvent(key: UUID().uuidString, value: true, defaultValue: false, featureFlag: featureFlag, user: user, includeReason: false)
}

static func stubEvents(eventCount: Int = Event.Kind.allKinds.count, for user: LDUser) -> [Event] {
var eventStubs = [Event]()
while eventStubs.count < eventCount {
Expand All @@ -1350,48 +1339,4 @@ extension Event {
event.dictionaryValue(config: config)
}
}

func matches(eventDictionary: [String: Any]?) -> Bool {
guard let eventDictionary = eventDictionary
else {
return false
}
if kind == .summary {
return kind == eventDictionary.eventKind && endDate?.isWithin(0.001, of: eventDictionary.eventEndDate) ?? false
}
guard let eventDictionaryKey = eventDictionary.eventKey,
let eventDictionaryCreationDateMillis = eventDictionary.eventCreationDateMillis
else {
return false
}
return key == eventDictionaryKey && creationDate?.millisSince1970 == eventDictionaryCreationDateMillis
}
}

extension Array where Element == Event {
func matches(eventDictionaries: [[String: Any]]) -> Bool {
guard self.count == eventDictionaries.count else {
return false
}
for index in self.indices {
if !self[index].matches(eventDictionary: eventDictionaries[index]) {
return false
}
}
return true
}
}

extension Array where Element == [String: Any] {
func matches(events: [Event]) -> Bool {
guard self.count == events.count else {
return false
}
for index in self.indices {
if !events[index].matches(eventDictionary: self[index]) {
return false
}
}
return true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1073,10 +1073,6 @@ extension DarklyService.StreamRequestPath {
}

extension LDUser {
func base64encoded(using config: LDConfig) -> String? {
return dictionaryValue(includeFlagConfig: false, includePrivateAttributes: true, config: config).base64UrlEncodedString
}

init?(base64urlEncodedString: String) {
let base64encodedString = base64urlEncodedString.replacingOccurrences(of: "-", with: "+").replacingOccurrences(of: "_", with: "/")
self.init(data: Data(base64Encoded: base64encodedString))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,9 @@ final class UserEnvironmentFlagCacheSpec: QuickSpec {
var selectedUser: LDUser {
return users.selectedUser
}
var unchangedUsers: [LDUser] {
var remainingUsers = users
remainingUsers.remove(at: users.firstIndex(of: selectedUser)!)
return remainingUsers
}
var selectedMobileKey: String {
return userEnvironmentsCollection[selectedUser.key]!.environmentFlags.keys.selectedMobileKey
}
var unchangedEnvironments: [MobileKey: CacheableEnvironmentFlags] {
var remainingEnvironments = userEnvironmentsCollection[selectedUser.key]!.environmentFlags
remainingEnvironments.removeValue(forKey: selectedMobileKey)
return remainingEnvironments
}
var oldestUser: LDUser {
//sort <userKey, lastUpdated> pairs youngest to oldest
let sortedLastUpdatedPairs = userEnvironmentsCollection.compactMapValues { (cacheableUserEnvironments) in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,25 +36,25 @@ final class ErrorNotifierSpec: QuickSpec {
}

init(observerCount: Int) {
self.init()
errorObservers = ErrorObserver.createObservers(count: observerCount)
errorNotifier = ErrorNotifier(observers: errorObservers)
originalObserverCount = errorObservers.count
observersPerOwner = observerCount
self.init(ownerCount: observerCount, observersPerOwner: 1)
}

init(ownerCount: Int, observersPerOwner: Int) {
self.init()
errorMock = ErrorMock(with: Constants.errorIdentifier)
nextErrorObserver = ErrorObserver(owner: nextErrorObserverOwner, errorHandler: nextErrorObserverOwner.handle)
errorNotifier = ErrorNotifier()

// create ownerCount owners, then observersPerOwner observers for each owner
let owners = (0..<ownerCount).map { _ in ErrorOwnerMock() }
owners.forEach { owner in
errorObservers += ErrorObserver.createObservers(count: observersPerOwner, using: owner)
for _ in 0..<ownerCount {
let owner = ErrorOwnerMock()
for _ in 0..<observersPerOwner {
let observer = ErrorObserver(owner: owner, errorHandler: owner.handle)
errorNotifier.addErrorObserver(observer)
errorObservers.append(observer)
}
}

errorNotifier = ErrorNotifier(observers: errorObservers)
originalObserverCount = errorObservers.count
self.observersPerOwner = observersPerOwner
originalObserverCount = errorObservers.count
}

var ownerToRemove: ErrorOwnerMock? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ final class EventReporterSpec: QuickSpec {
var serviceMock: DarklyServiceMock!
var events: [Event]!
var eventKeys: [String]! { events.compactMap { $0.key } }
var eventKinds: [Event.Kind]! { events.compactMap { $0.kind } }
var lastEventResponseDate: Date?
var flagKey: LDFlagKey!
var featureFlag: FeatureFlag!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ final class FlagChangeNotifierSpec: QuickSpec {
var flagsUnchangedOwnerKey: String?
var featureFlags: [LDFlagKey: FeatureFlag] = DarklyServiceMock.Constants.stubFeatureFlags()
var user: LDUser = LDUser.stub(key: Constants.userKey, includeNullValue: true)
var flagStoreMock: FlagMaintainingMock! {
(user.flagStore as! FlagMaintainingMock)
}

let alternateFlagKeys = ["flag-key-1", "flag-key-2", "flag-key-3"]

//Use this initializer when stubbing observers for observer add & remove tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ final class FlagSynchronizerSpec: QuickSpec {
struct TestContext {
var config: LDConfig!
var user: LDUser!
var flagStoreMock: FlagMaintainingMock! {
user.flagStore as? FlagMaintainingMock
}
var serviceMock: DarklyServiceMock!
var eventSourceMock: DarklyStreamingProviderMock? {
serviceMock.createdEventSource
Expand Down

0 comments on commit fdada02

Please sign in to comment.