Skip to content

Commit

Permalink
Add nanoseconds to instant protocol (#114)
Browse files Browse the repository at this point in the history
  • Loading branch information
ktoso authored Apr 3, 2023
1 parent 63a9c24 commit bb7fa3b
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 52 deletions.
45 changes: 17 additions & 28 deletions Sources/Tracing/TracingTime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,17 @@ import Darwin
@_exported import Instrumentation
@_exported import InstrumentationBaggage

public protocol SwiftDistributedTracingDurationProtocol: Comparable, AdditiveArithmetic, Sendable {
static func / (_ lhs: Self, _ rhs: Int) -> Self
static func /= (_ lhs: inout Self, _ rhs: Int)
static func * (_ lhs: Self, _ rhs: Int) -> Self
static func *= (_ lhs: inout Self, _ rhs: Int)

static func / (_ lhs: Self, _ rhs: Self) -> Double
}

extension SwiftDistributedTracingDurationProtocol {
public static func /= (_ lhs: inout Self, _ rhs: Int) {
lhs = lhs / rhs
}
public protocol TracerInstant: Comparable, Hashable, Sendable {
/// Representation of this instant as the number of nanoseconds since UNIX Epoch (January 1st 1970)
var nanosecondsSinceEpoch: UInt64 { get }
}

public protocol SwiftDistributedTracingInstantProtocol: Comparable, Hashable, Sendable {}

public protocol TracerInstantProtocol: SwiftDistributedTracingInstantProtocol {
extension TracerInstant {
/// Representation of this instant as the number of milliseconds since UNIX Epoch (January 1st 1970)
var millisecondsSinceEpoch: UInt64 { get }
@inlinable
public var millisecondsSinceEpoch: UInt64 {
self.nanosecondsSinceEpoch / 1_000_000
}
}

/// A specialized clock protocol for purposes of tracing.
Expand All @@ -55,7 +46,7 @@ public protocol TracerInstantProtocol: SwiftDistributedTracingInstantProtocol {
/// especially when the system is already using some notion of simulated or mocked time, such that traces are
/// expressed using the same notion of time.
public protocol TracerClock {
associatedtype Instant: TracerInstantProtocol
associatedtype Instant: TracerInstant

var now: Self.Instant { get }
}
Expand All @@ -68,24 +59,23 @@ public struct DefaultTracerClock: TracerClock {
// empty
}

public struct Timestamp: TracerInstantProtocol {
/// Milliseconds since January 1st, 1970, also known as "unix epoch".
public var millisecondsSinceEpoch: UInt64
public struct Timestamp: TracerInstant {
public let nanosecondsSinceEpoch: UInt64

internal init(millisecondsSinceEpoch: UInt64) {
self.millisecondsSinceEpoch = millisecondsSinceEpoch
public init(nanosecondsSinceEpoch: UInt64) {
self.nanosecondsSinceEpoch = nanosecondsSinceEpoch
}

public static func < (lhs: Instant, rhs: Instant) -> Bool {
lhs.millisecondsSinceEpoch < rhs.millisecondsSinceEpoch
lhs.nanosecondsSinceEpoch < rhs.nanosecondsSinceEpoch
}

public static func == (lhs: Instant, rhs: Instant) -> Bool {
lhs.millisecondsSinceEpoch == rhs.millisecondsSinceEpoch
lhs.nanosecondsSinceEpoch == rhs.nanosecondsSinceEpoch
}

public func hash(into hasher: inout Hasher) {
self.millisecondsSinceEpoch.hash(into: &hasher)
self.nanosecondsSinceEpoch.hash(into: &hasher)
}
}

Expand All @@ -100,8 +90,7 @@ public struct DefaultTracerClock: TracerClock {
/// and the odds that this code will still be running 530 years from now is very, very low,
/// so as a practical matter this will never overflow.
let nowNanos = UInt64(ts.tv_sec) &* 1_000_000_000 &+ UInt64(ts.tv_nsec)
let nowMillis = UInt64(nowNanos / 1_000_000) // nanos to millis

return Instant(millisecondsSinceEpoch: nowMillis)
return Instant(nanosecondsSinceEpoch: nowNanos)
}
}
22 changes: 11 additions & 11 deletions Tests/TracingTests/DynamicTracepointTracerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,8 @@ extension DynamicTracepointTestTracer {

private var status: SpanStatus?

private let startTime: UInt64
private(set) var endTime: UInt64?
private let startTimestampNanosSinceEpoch: UInt64
private(set) var endTimestampNanosSinceEpoch: UInt64?

public var operationName: String
private(set) var baggage: Baggage
Expand All @@ -281,16 +281,16 @@ extension DynamicTracepointTestTracer {
return span
}

init<Instant: TracerInstantProtocol>(operationName: String,
startTime: Instant,
baggage: Baggage,
kind: SpanKind,
file fileID: String,
line: UInt,
onEnd: @escaping (TracepointSpan) -> Void)
init<Instant: TracerInstant>(operationName: String,
startTime: Instant,
baggage: Baggage,
kind: SpanKind,
file fileID: String,
line: UInt,
onEnd: @escaping (TracepointSpan) -> Void)
{
self.operationName = operationName
self.startTime = startTime.millisecondsSinceEpoch
self.startTimestampNanosSinceEpoch = startTime.nanosecondsSinceEpoch
self.baggage = baggage
self.onEnd = onEnd
self.kind = kind
Expand Down Expand Up @@ -323,7 +323,7 @@ extension DynamicTracepointTestTracer {
}

func end<Clock: TracerClock>(clock: Clock) {
self.endTime = clock.now.millisecondsSinceEpoch
self.endTimestampNanosSinceEpoch = clock.now.nanosecondsSinceEpoch
self.onEnd(self)
}
}
Expand Down
10 changes: 5 additions & 5 deletions Tests/TracingTests/TestTracer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ final class TestSpan: Span {

private var status: SpanStatus?

public let startTime: UInt64
public private(set) var endTime: UInt64?
public let startTimestampNanosSinceEpoch: UInt64
public private(set) var endTimestampNanosSinceEpoch: UInt64?

private(set) var recordedErrors: [(Error, SpanAttributes)] = []

Expand All @@ -150,15 +150,15 @@ final class TestSpan: Span {

let onEnd: (TestSpan) -> Void

init<Instant: TracerInstantProtocol>(
init<Instant: TracerInstant>(
operationName: String,
startTime: Instant,
baggage: Baggage,
kind: SpanKind,
onEnd: @escaping (TestSpan) -> Void
) {
self.operationName = operationName
self.startTime = startTime.millisecondsSinceEpoch
self.startTimestampNanosSinceEpoch = startTime.nanosecondsSinceEpoch
self.baggage = baggage
self.onEnd = onEnd
self.kind = kind
Expand All @@ -182,7 +182,7 @@ final class TestSpan: Span {
}

func end<Clock: TracerClock>(clock: Clock) {
self.endTime = clock.now.millisecondsSinceEpoch
self.endTimestampNanosSinceEpoch = clock.now.nanosecondsSinceEpoch
self.onEnd(self)
}
}
Expand Down
2 changes: 1 addition & 1 deletion Tests/TracingTests/TracedLockTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ private final class TracedLockPrintlnTracer: LegacyTracer {

private(set) var isRecording = false

init<Instant: TracerInstantProtocol>(
init<Instant: TracerInstant>(
operationName: String,
startTime: Instant,
kind: SpanKind,
Expand Down
2 changes: 1 addition & 1 deletion Tests/TracingTests/TracerTests+swift57.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ final class SampleSwift57Span: Span {

let onEnd: (SampleSwift57Span) -> Void

init<Instant: TracerInstantProtocol>(
init<Instant: TracerInstant>(
operationName: String,
startTime: Instant,
baggage: Baggage,
Expand Down
12 changes: 6 additions & 6 deletions Tests/TracingTests/TracerTimeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ final class TracerTimeTests: XCTestCase {
mockClock.setTime(13)
#if swift(>=5.7.0)
let span: TestSpan = tracer.startSpan("start", clock: mockClock)
XCTAssertEqual(span.startTime, 13)
XCTAssertEqual(span.startTimestampNanosSinceEpoch, 13)
#else
let span: TestSpan = tracer.startAnySpan("start", clock: mockClock) as! TestSpan
XCTAssertEqual(span.startTime, 13)
XCTAssertEqual(span.startTimestampNanosSinceEpoch, 13)
#endif
}
}
Expand All @@ -61,14 +61,14 @@ final class MockClock: TracerClock {
self._now = time
}

struct Instant: TracerInstantProtocol {
var millisecondsSinceEpoch: UInt64
struct Instant: TracerInstant {
var nanosecondsSinceEpoch: UInt64
static func < (lhs: MockClock.Instant, rhs: MockClock.Instant) -> Bool {
lhs.millisecondsSinceEpoch < rhs.millisecondsSinceEpoch
lhs.nanosecondsSinceEpoch < rhs.nanosecondsSinceEpoch
}
}

var now: Instant {
Instant(millisecondsSinceEpoch: self._now)
Instant(nanosecondsSinceEpoch: self._now)
}
}

0 comments on commit bb7fa3b

Please sign in to comment.