Skip to content

Commit

Permalink
Add EventLoop.now API for getting the current time
Browse files Browse the repository at this point in the history
  • Loading branch information
simonjbeaumont committed Dec 3, 2024
1 parent 876fbf6 commit 2c37229
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 3 deletions.
3 changes: 3 additions & 0 deletions Sources/NIOCore/EventLoop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,9 @@ public protocol EventLoop: EventLoopGroup {
@preconcurrency
func submit<T>(_ task: @escaping @Sendable () throws -> T) -> EventLoopFuture<T>

/// The current time of the event loop.
var now: NIODeadline { get }

/// Schedule a `task` that is executed by this `EventLoop` at the given time.
///
/// - Parameters:
Expand Down
4 changes: 3 additions & 1 deletion Sources/NIOEmbedded/AsyncTestingEventLoop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ public final class NIOAsyncTestingEventLoop: EventLoop, @unchecked Sendable {
/// The current "time" for this event loop. This is an amount in nanoseconds.
/// As we need to access this from any thread, we store this as an atomic.
private let _now = ManagedAtomic<UInt64>(0)
internal var now: NIODeadline {

/// The current "time" for this event loop. This is an amount in nanoseconds.
public var now: NIODeadline {
NIODeadline.uptimeNanoseconds(self._now.load(ordering: .relaxed))
}

Expand Down
4 changes: 3 additions & 1 deletion Sources/NIOEmbedded/Embedded.swift
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,10 @@ extension EmbeddedScheduledTask: Comparable {
/// responsible for ensuring they never call into the `EmbeddedEventLoop` in an
/// unsynchronized fashion.
public final class EmbeddedEventLoop: EventLoop, CustomStringConvertible {
private var _now: NIODeadline = .uptimeNanoseconds(0)
/// The current "time" for this event loop. This is an amount in nanoseconds.
internal var _now: NIODeadline = .uptimeNanoseconds(0)
public var now: NIODeadline { _now }


private enum State { case open, closing, closed }
private var state: State = .open
Expand Down
6 changes: 6 additions & 0 deletions Sources/NIOPosix/SelectableEventLoop.swift
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,12 @@ internal final class SelectableEventLoop: EventLoop {
thread.isCurrent
}

/// - see: `EventLoop.now`
@usableFromInline
internal var now: NIODeadline {
.now()
}

/// - see: `EventLoop.scheduleTask(deadline:_:)`
@inlinable
internal func scheduleTask<T>(deadline: NIODeadline, _ task: @escaping () throws -> T) -> Scheduled<T> {
Expand Down
10 changes: 10 additions & 0 deletions Tests/NIOEmbeddedTests/AsyncTestingEventLoopTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -619,4 +619,14 @@ final class NIOAsyncTestingEventLoopTests: XCTestCase {
await eventLoop.advanceTime(by: .seconds(1))
XCTAssertEqual(counter.load(ordering: .relaxed), 3)
}

func testCurrentTime() async {
let eventLoop = NIOAsyncTestingEventLoop()

await eventLoop.advanceTime(to: .uptimeNanoseconds(42))
XCTAssertEqual(eventLoop.now, .uptimeNanoseconds(42))

await eventLoop.advanceTime(by: .nanoseconds(42))
XCTAssertEqual(eventLoop.now, .uptimeNanoseconds(84))
}
}
12 changes: 11 additions & 1 deletion Tests/NIOEmbeddedTests/EmbeddedEventLoopTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ public final class EmbeddedEventLoopTest: XCTestCase {
try eventLoop.syncShutdownGracefully()
childTasks.append(
scheduleRecursiveTask(
at: eventLoop._now + childTaskStartDelay,
at: eventLoop.now + childTaskStartDelay,
andChildTaskAfter: childTaskStartDelay
)
)
Expand Down Expand Up @@ -497,4 +497,14 @@ public final class EmbeddedEventLoopTest: XCTestCase {
eventLoop.advanceTime(by: .seconds(1))
XCTAssertEqual(counter, 3)
}

func testCurrentTime() {
let eventLoop = EmbeddedEventLoop()

eventLoop.advanceTime(to: .uptimeNanoseconds(42))
XCTAssertEqual(eventLoop.now, .uptimeNanoseconds(42))

eventLoop.advanceTime(by: .nanoseconds(42))
XCTAssertEqual(eventLoop.now, .uptimeNanoseconds(84))
}
}
8 changes: 8 additions & 0 deletions Tests/NIOPosixTests/EventLoopTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1962,6 +1962,10 @@ private class EventLoopWithPreSucceededFuture: EventLoop {
preconditionFailure("not implemented")
}

var now: NIODeadline {
preconditionFailure("not implemented")
}

@discardableResult
func scheduleTask<T>(deadline: NIODeadline, _ task: @escaping () throws -> T) -> Scheduled<T> {
preconditionFailure("not implemented")
Expand Down Expand Up @@ -2013,6 +2017,10 @@ private class EventLoopWithoutPreSucceededFuture: EventLoop {
preconditionFailure("not implemented")
}

var now: NIODeadline {
preconditionFailure("not implemented")
}

@discardableResult
func scheduleTask<T>(deadline: NIODeadline, _ task: @escaping () throws -> T) -> Scheduled<T> {
preconditionFailure("not implemented")
Expand Down

0 comments on commit 2c37229

Please sign in to comment.