Skip to content

Commit e71d58a

Browse files
refactor: cleanup prints and lint
Signed-off-by: Fabrizio Demaria <fabrizio.f.demaria@gmail.com>
1 parent 6597465 commit e71d58a

File tree

3 files changed

+30
-90
lines changed

3 files changed

+30
-90
lines changed

Sources/OpenFeature/AsyncCoalescingSerialQueue.swift

Lines changed: 2 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -7,76 +7,27 @@ internal actor AsyncCoalescingSerialQueue {
77
private var currentTask: Task<Void, Never>?
88
private var pendingOperation: (() async -> Void)?
99
private var pendingContinuations: [CheckedContinuation<Void, Never>] = []
10-
private var operationCounter: Int = 0
11-
12-
/// Verbose mode controls whether debug logging is enabled
13-
private let verbose: Bool
14-
15-
/// Initialize the queue with optional verbose logging
16-
/// - Parameter verbose: If true, detailed debug logs will be printed with [ASQ] prefix
17-
init(verbose: Bool = false) {
18-
self.verbose = verbose
19-
}
2010

2111
/// Runs the given operation serially. If an operation is already running,
2212
/// this operation replaces any previously pending operation (which gets skipped).
2313
/// All callers whose operations were replaced will wait for the latest operation to complete.
2414
func run(_ operation: @Sendable @escaping () async -> Void) async {
2515
await withCheckedContinuation { continuation in
26-
operationCounter += 1
27-
let operationId = operationCounter
28-
29-
if verbose {
30-
print("[ASQ] 🔵 run() called - Operation #\(operationId)")
31-
print("[ASQ] ├─ currentTask == nil: \(currentTask == nil)")
32-
print("[ASQ] ├─ pendingOperation == nil (before): \(pendingOperation == nil)")
33-
print("[ASQ] ├─ pendingContinuations.count (before): \(pendingContinuations.count)")
34-
}
35-
3616
// Replace any pending operation with this new one
37-
let hadPendingOperation = pendingOperation != nil
3817
pendingOperation = operation
3918
pendingContinuations.append(continuation)
4019

41-
if verbose {
42-
if hadPendingOperation {
43-
print("[ASQ] ├─ ⚠️ REPLACED previous pending operation with Operation #\(operationId)")
44-
} else {
45-
print("[ASQ] ├─ ✓ Set Operation #\(operationId) as pending operation")
46-
}
47-
print("[ASQ] ├─ pendingContinuations.count (after): \(pendingContinuations.count)")
48-
}
49-
5020
// If nothing is currently running, start processing
5121
if currentTask == nil {
52-
if verbose {
53-
print("[ASQ] └─ ▶️ No task running, calling processNext() for Operation #\(operationId)")
54-
}
5522
processNext()
56-
} else {
57-
if verbose {
58-
print("[ASQ] └─ ⏸️ Task already running, Operation #\(operationId) will wait")
59-
}
6023
}
6124
}
6225
}
6326

6427
private func processNext() {
65-
if verbose {
66-
print("[ASQ] 🟢 processNext() called")
67-
print("[ASQ] ├─ pendingOperation == nil: \(pendingOperation == nil)")
68-
print("[ASQ] ├─ pendingContinuations.count: \(pendingContinuations.count)")
69-
}
70-
7128
guard let operation = pendingOperation else {
7229
// No pending work
73-
if verbose {
74-
print("[ASQ] ├─ ⛔ No pending operation, cleaning up")
75-
}
7630
currentTask = nil
77-
if verbose {
78-
print("[ASQ] └─ ✓ currentTask set to nil, queue is now idle")
79-
}
8031
return
8132
}
8233

@@ -85,40 +36,16 @@ internal actor AsyncCoalescingSerialQueue {
8536
let continuations = pendingContinuations
8637
pendingContinuations = []
8738

88-
if verbose {
89-
print("[ASQ] ├─ ✓ Captured \(continuations.count) continuation(s) to resume")
90-
print("[ASQ] ├─ ✓ Cleared pendingOperation and pendingContinuations")
91-
print("[ASQ] └─ 🚀 Starting new Task to execute operation")
92-
}
93-
9439
// Start the task
95-
currentTask = Task { [weak self, verbose] in
96-
if verbose {
97-
print("[ASQ] 🔄 Task execution started")
98-
}
40+
currentTask = Task { [weak self] in
9941
await operation()
100-
if verbose {
101-
print("[ASQ] ✅ Task execution completed")
102-
}
10342

10443
// Resume all waiting callers
105-
if verbose {
106-
print("[ASQ] 📤 Resuming \(continuations.count) continuation(s)")
107-
}
108-
for (index, continuation) in continuations.enumerated() {
109-
if verbose {
110-
print("[ASQ] ├─ Resuming continuation #\(index + 1)")
111-
}
44+
for continuation in continuations {
11245
continuation.resume()
11346
}
114-
if verbose {
115-
print("[ASQ] ✓ All continuations resumed")
116-
}
11747

11848
// Process next operation if any arrived while we were running
119-
if verbose {
120-
print("[ASQ] 🔁 Checking for next operation...")
121-
}
12249
await self?.processNext()
12350
}
12451
}

Sources/OpenFeature/OpenFeatureAPI.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ public class OpenFeatureAPI {
1717
static public let shared = OpenFeatureAPI()
1818

1919
public init() {
20-
// Check for OPENFEATURE_ASQ_VERBOSE environment variable to enable verbose logging
21-
let verboseMode = ProcessInfo.processInfo.environment["OPENFEATURE_ASQ_VERBOSE"] != nil
22-
contextQueue = AsyncCoalescingSerialQueue(verbose: verboseMode)
20+
contextQueue = AsyncCoalescingSerialQueue()
2321
}
2422

2523
/**

Tests/OpenFeatureTests/AsyncSerialQueueTests.swift

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import XCTest
22
import Combine
33
@testable import OpenFeature
44

5+
// swiftlint:disable type_body_length file_length trailing_closure
56
class AsyncCoalescingSerialQueueTests: XCTestCase {
67
override func setUp() {
78
super.setUp()
@@ -89,7 +90,10 @@ class AsyncCoalescingSerialQueueTests: XCTestCase {
8990

9091
let finalState = OpenFeatureAPI.shared.getState()
9192
XCTAssertNotNil(finalState.provider, "Provider should not be nil after concurrent operations")
92-
XCTAssertNotNil(finalState.evaluationContext, "Evaluation context should not be nil after concurrent operations")
93+
XCTAssertNotNil(
94+
finalState.evaluationContext,
95+
"Evaluation context should not be nil after concurrent operations"
96+
)
9397
XCTAssertTrue([.ready].contains(finalState.providerStatus), "Provider status should be in a valid final state")
9498

9599
if let context = finalState.evaluationContext {
@@ -161,13 +165,17 @@ class AsyncCoalescingSerialQueueTests: XCTestCase {
161165

162166
let contextMap = context?.asObjectMap() ?? [:]
163167
if contextMap.keys.contains("iteration") {
164-
XCTAssertTrue(contextMap.keys.contains("timestamp"), "Context with iteration should also have timestamp")
168+
XCTAssertTrue(
169+
contextMap.keys.contains("timestamp"),
170+
"Context with iteration should also have timestamp"
171+
)
165172
}
166173
} else {
167174
XCTFail("Provider or Evaluation Context unexpectedly nil")
168175
}
169176
}
170177

178+
// swiftlint:disable:next function_body_length
171179
func testAsyncCoalescingSerialQueueCoalescence() async throws {
172180
// Track which operations actually executed
173181
actor ExecutionTracker {
@@ -186,7 +194,7 @@ class AsyncCoalescingSerialQueueTests: XCTestCase {
186194

187195
// Create a provider with a slow onContextSet to ensure operations overlap
188196
let provider = MockProvider(
189-
onContextSet: { oldContext, newContext in
197+
onContextSet: { _, newContext in
190198
// Add delay to simulate slow provider operation
191199
// This ensures that when tasks 2 and 3 are queued, task 1 is still running
192200
let targetingKey = newContext.getTargetingKey()
@@ -241,7 +249,10 @@ class AsyncCoalescingSerialQueueTests: XCTestCase {
241249
XCTAssertLessThanOrEqual(
242250
executedOperations.count,
243251
2,
244-
"Should execute at most 2 operations due to coalescence (first + latest), but executed: \(executedOperations)"
252+
"""
253+
Should execute at most 2 operations due to coalescence (first + latest), \
254+
but executed: \(executedOperations)
255+
"""
245256
)
246257

247258
// Verify user2 was NOT executed (it should be coalesced/skipped)
@@ -273,7 +284,7 @@ class AsyncCoalescingSerialQueueTests: XCTestCase {
273284

274285
let tracker = ExecutionTracker()
275286
let provider = MockProvider(
276-
onContextSet: { oldContext, newContext in
287+
onContextSet: { _, newContext in
277288
await tracker.recordExecution(newContext.getTargetingKey())
278289
}
279290
)
@@ -304,7 +315,7 @@ class AsyncCoalescingSerialQueueTests: XCTestCase {
304315

305316
let tracker = ExecutionTracker()
306317
let provider = MockProvider(
307-
onContextSet: { oldContext, newContext in
318+
onContextSet: { _, newContext in
308319
await tracker.recordExecution(newContext.getTargetingKey())
309320
try await Task.sleep(nanoseconds: 10_000_000) // 10ms
310321
}
@@ -344,7 +355,7 @@ class AsyncCoalescingSerialQueueTests: XCTestCase {
344355

345356
let tracker = ExecutionTracker()
346357
let provider = MockProvider(
347-
onContextSet: { oldContext, newContext in
358+
onContextSet: { _, newContext in
348359
await tracker.recordExecution(newContext.getTargetingKey())
349360
try await Task.sleep(nanoseconds: 100_000_000) // 100ms - long enough for many to queue
350361
}
@@ -395,7 +406,7 @@ class AsyncCoalescingSerialQueueTests: XCTestCase {
395406

396407
let tracker = ExecutionTracker()
397408
let provider = MockProvider(
398-
onContextSet: { oldContext, newContext in
409+
onContextSet: { _, newContext in
399410
await tracker.recordExecution(newContext.getTargetingKey())
400411
}
401412
)
@@ -464,7 +475,7 @@ class AsyncCoalescingSerialQueueTests: XCTestCase {
464475

465476
let tracker = ExecutionTracker()
466477
let provider = MockProvider(
467-
onContextSet: { oldContext, newContext in
478+
onContextSet: { _, newContext in
468479
let targetingKey = newContext.getTargetingKey()
469480
await tracker.recordExecution(targetingKey)
470481

@@ -543,7 +554,7 @@ class AsyncCoalescingSerialQueueTests: XCTestCase {
543554

544555
let completionTracker = CompletionTracker()
545556
let provider = MockProvider(
546-
onContextSet: { oldContext, newContext in
557+
onContextSet: { _, _ in
547558
try await Task.sleep(nanoseconds: 50_000_000) // 50ms
548559
}
549560
)
@@ -594,7 +605,7 @@ class AsyncCoalescingSerialQueueTests: XCTestCase {
594605

595606
let tracker = ExecutionTracker()
596607
let provider = MockProvider(
597-
onContextSet: { oldContext, newContext in
608+
onContextSet: { _, newContext in
598609
await tracker.recordExecution(newContext.getTargetingKey())
599610
try await Task.sleep(nanoseconds: 20_000_000) // 20ms
600611
}
@@ -609,7 +620,10 @@ class AsyncCoalescingSerialQueueTests: XCTestCase {
609620
group.addTask {
610621
let ctx = ImmutableContext(
611622
targetingKey: "wave\(wave)-user\(i)",
612-
structure: ImmutableStructure(attributes: ["wave": .integer(Int64(wave)), "id": .integer(Int64(i))])
623+
structure: ImmutableStructure(attributes: [
624+
"wave": .integer(Int64(wave)),
625+
"id": .integer(Int64(i)),
626+
])
613627
)
614628
await OpenFeatureAPI.shared.setEvaluationContextAndWait(evaluationContext: ctx)
615629
}
@@ -639,3 +653,4 @@ class AsyncCoalescingSerialQueueTests: XCTestCase {
639653
)
640654
}
641655
}
656+
// swiftlint:enable type_body_length file_length trailing_closure

0 commit comments

Comments
 (0)