Implement idle timeout, additional HTTP attributes - #47
Conversation
| /// Add listeners for application lifecycle events -- typically called during didFinishLaunching. | ||
| func subscribeToLifecycleEvents() | ||
|
|
||
| /// Called when no spans have been retied in `idleTimeoutInterval` |
There was a problem hiding this comment.
| /// Called when no spans have been retied in `idleTimeoutInterval` | |
| /// Called when no spans have been retired in `idleTimeoutInterval` |
| addAttribute("network.connection.type", metric.isCellular ? "cell" : "wifi") | ||
| addAttribute("network.protocol.version", Self.networkProtocolVersion(metric.networkProtocolName)) | ||
|
|
||
| // No official semantic convention exists yet for the the properties below |
There was a problem hiding this comment.
| // No official semantic convention exists yet for the the properties below | |
| // No official semantic convention exists yet for the properties below |
| public var flushInterval: TimeInterval { Tracer.defaultFlushInterval } | ||
|
|
||
| public var idleTimeoutInterval: TimeInterval { Tracer.defaultIdleInterval } |
There was a problem hiding this comment.
What's the difference between the NautilusTelemetryReporter and the Tracer? I'm asking to learn.
There was a problem hiding this comment.
The NautilusTelemetryReporter protocol is implemented in an app component and is responsible for sending telemetry batches to an OpenTelemetry collector instance. Tracer is responsible for span creation & batching -- it passes off batches to the reporter.
| flushInterval = Self.defaultFlushInterval | ||
| idleTimeoutInterval = Self.defaultIdleInterval | ||
| flushTimer = FlushTimer(flushInterval: flushInterval, repeating: true) { [weak self] in self?.flushRetiredSpans() } | ||
| idleTimer = FlushTimer(flushInterval: idleTimeoutInterval, repeating: false) { |
There was a problem hiding this comment.
Can you help me understand why this one doesn't repeat?
There was a problem hiding this comment.
The idle timer firing is pushed forward every time a span is retired and then fires once if no more spans are retired in that interval. This implements a behavior of "if no spans have been ended for 10 seconds, then inform the reporter". The intended use case is for the reporter to check whether the app is in the background & then flush the trace, which gives us better capture of background task & notification-driven fetches.
Internal PR coming which may make this more clear.
| flushTimer.schedule( | ||
| deadline: DispatchTime.now() + flushInterval, | ||
| repeating: flushInterval, | ||
| repeating: repeating ? flushInterval : .infinity, |
There was a problem hiding this comment.
I was expecting .never when repeating == false. Can you help. me understand .infinity?
There was a problem hiding this comment.
It's from Apple's docs for the variant that takes a Double for the repeating interval:
/// - parameter repeating: the repeat interval for the timer in seconds, or `.infinity` if the timer
/// should fire only once.
If you pass a DispatchTimeInterval, you can use .never, which is probably nicer to read.
| XCTAssertNil(attributes["http.response.header.content-encoding"]) | ||
| } | ||
|
|
||
| func testNilDateElapsedNanosecondAttribute() throws { |
| var idleTimeoutInterval: TimeInterval { 0.1 } | ||
|
|
||
| func idleTimeout() { | ||
| idleExpectation.fulfill() |
| var handlerCallCount = 0 | ||
|
|
||
| let timer = FlushTimer(flushInterval: 0.1) { | ||
| let timer = FlushTimer(flushInterval: 0.1, repeating: true) { |
There was a problem hiding this comment.
Could we add a test for repeating: false?
| timer.flushInterval = 0.05 | ||
| XCTAssertEqual(timer.flushInterval, 0.05) | ||
| XCTAssertEqual(timer.flushInterval, timer.minimumFlushInterval) |
There was a problem hiding this comment.
| timer.flushInterval = 0.05 | |
| XCTAssertEqual(timer.flushInterval, 0.05) | |
| XCTAssertEqual(timer.flushInterval, timer.minimumFlushInterval) | |
| let tooSmallFlushInterval = 0.05 | |
| XCTAssertNotEqual(tooSmallFlushInterval, timer.minimumFlushInterval) | |
| timer.flushInterval = tooSmallFlushInterval | |
| XCTAssertEqual(timer.flushInterval, timer.minimumFlushInterval) |
This would be a bit more powerful and robust to changes.
4da57c5 to
3605fb0
Compare
| flushTimer.schedule( | ||
| deadline: DispatchTime.now() + flushInterval, | ||
| repeating: repeating ? flushInterval : .infinity, | ||
| repeating: repeating ? DispatchTimeInterval(flushInterval) : .never, |
| // Push the timeout ahead | ||
| idleTimer?.setupTimer() |
@jparise
@bachand