Skip to content

Commit e7eed85

Browse files
committed
remove dependency on DispatchWallTime (fix #384)
1 parent 0a6af5b commit e7eed85

File tree

5 files changed

+41
-24
lines changed

5 files changed

+41
-24
lines changed

Sources/AWSLambdaRuntime/FoundationSupport/Context+Foundation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import struct Foundation.Date
2121

2222
extension LambdaContext {
2323
var deadlineDate: Date {
24-
let secondsSinceEpoch = Double(Int64(bitPattern: self.deadline.rawValue)) / -1_000_000_000
24+
let secondsSinceEpoch = Double(self.deadline.milliseconds()) / -1_000_000_000
2525
return Date(timeIntervalSince1970: secondsSinceEpoch)
2626
}
2727
}

Sources/AWSLambdaRuntime/Lambda+LocalServer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ internal struct LambdaHTTPServer {
650650
"arn:aws:lambda:us-east-1:\(Int16.random(in: Int16.min ... Int16.max)):function:custom-runtime"
651651
),
652652
(AmazonHeaders.traceID, "Root=\(AmazonHeaders.generateXRayTraceID());Sampled=1"),
653-
(AmazonHeaders.deadline, "\(DispatchWallTime.distantFuture.millisSinceEpoch)"),
653+
(AmazonHeaders.deadline, "\(Duration.distantFuture.milliseconds())"),
654654
])
655655

656656
return LocalServerResponse(

Sources/AWSLambdaRuntime/Lambda.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,7 @@ public enum Lambda {
7070
requestID: invocation.metadata.requestID,
7171
traceID: invocation.metadata.traceID,
7272
invokedFunctionARN: invocation.metadata.invokedFunctionARN,
73-
deadline: DispatchWallTime(
74-
millisSinceEpoch: invocation.metadata.deadlineInMillisSinceEpoch
75-
),
73+
deadline: Duration(millisSinceEpoch: invocation.metadata.deadlineInMillisSinceEpoch),
7674
logger: logger
7775
)
7876
)

Sources/AWSLambdaRuntime/LambdaContext.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public struct LambdaContext: CustomDebugStringConvertible, Sendable {
2525
let requestID: String
2626
let traceID: String
2727
let invokedFunctionARN: String
28-
let deadline: DispatchWallTime
28+
let deadline: Duration
2929
let cognitoIdentity: String?
3030
let clientContext: String?
3131
let logger: Logger
@@ -34,7 +34,7 @@ public struct LambdaContext: CustomDebugStringConvertible, Sendable {
3434
requestID: String,
3535
traceID: String,
3636
invokedFunctionARN: String,
37-
deadline: DispatchWallTime,
37+
deadline: Duration,
3838
cognitoIdentity: String?,
3939
clientContext: String?,
4040
logger: Logger
@@ -67,7 +67,7 @@ public struct LambdaContext: CustomDebugStringConvertible, Sendable {
6767
}
6868

6969
/// The timestamp that the function times out.
70-
public var deadline: DispatchWallTime {
70+
public var deadline: Duration {
7171
self.storage.deadline
7272
}
7373

@@ -92,7 +92,7 @@ public struct LambdaContext: CustomDebugStringConvertible, Sendable {
9292
requestID: String,
9393
traceID: String,
9494
invokedFunctionARN: String,
95-
deadline: DispatchWallTime,
95+
deadline: Duration,
9696
cognitoIdentity: String? = nil,
9797
clientContext: String? = nil,
9898
logger: Logger
@@ -109,30 +109,30 @@ public struct LambdaContext: CustomDebugStringConvertible, Sendable {
109109
}
110110

111111
public func getRemainingTime() -> Duration {
112-
let deadline = self.deadline.millisSinceEpoch
113-
let now = DispatchWallTime.now().millisSinceEpoch
112+
let deadline = self.deadline
113+
let now = Duration.millisSinceEpoch
114114

115-
let remaining = deadline - now
116-
return .milliseconds(remaining)
115+
return deadline - now
117116
}
118117

119118
public var debugDescription: String {
120119
"\(Self.self)(requestID: \(self.requestID), traceID: \(self.traceID), invokedFunctionARN: \(self.invokedFunctionARN), cognitoIdentity: \(self.cognitoIdentity ?? "nil"), clientContext: \(self.clientContext ?? "nil"), deadline: \(self.deadline))"
121120
}
122121

123122
/// This interface is not part of the public API and must not be used by adopters. This API is not part of semver versioning.
123+
/// The timeout is expressed relative to now
124124
package static func __forTestsOnly(
125125
requestID: String,
126126
traceID: String,
127127
invokedFunctionARN: String,
128-
timeout: DispatchTimeInterval,
128+
timeout: Duration,
129129
logger: Logger
130130
) -> LambdaContext {
131131
LambdaContext(
132132
requestID: requestID,
133133
traceID: traceID,
134134
invokedFunctionARN: invokedFunctionARN,
135-
deadline: .now() + timeout,
135+
deadline: Duration.millisSinceEpoch + timeout,
136136
logger: logger
137137
)
138138
}

Sources/AWSLambdaRuntime/Utils.swift

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,36 @@ enum AmazonHeaders {
3939
static let invokedFunctionARN = "Lambda-Runtime-Invoked-Function-Arn"
4040
}
4141

42-
extension DispatchWallTime {
42+
/// A simple set of additions to Duration helping to work with Unix epoch that does not require Foundation.
43+
/// It provides a distant future value and a way to get the current time in milliseconds since the epoch.
44+
/// The Lambda execution environment uses UTC as a timezone, this struct must not manage timezones.
45+
/// see: TZ in https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html
46+
extension Duration {
47+
/// Returns the time in milliseconds since the Unix epoch.
4348
@usableFromInline
44-
init(millisSinceEpoch: Int64) {
45-
let nanoSinceEpoch = UInt64(millisSinceEpoch) * 1_000_000
46-
let seconds = UInt64(nanoSinceEpoch / 1_000_000_000)
47-
let nanoseconds = nanoSinceEpoch - (seconds * 1_000_000_000)
48-
self.init(timespec: timespec(tv_sec: Int(seconds), tv_nsec: Int(nanoseconds)))
49+
static var millisSinceEpoch: Duration {
50+
var ts = timespec()
51+
clock_gettime(CLOCK_REALTIME, &ts)
52+
return .milliseconds(Int64(ts.tv_sec) * 1000 + Int64(ts.tv_nsec) / 1_000_000)
4953
}
5054

51-
var millisSinceEpoch: Int64 {
52-
Int64(bitPattern: self.rawValue) / -1_000_000
55+
/// Returns a Duration between Unix epoch and the distant future
56+
@usableFromInline
57+
static var distantFuture: Duration {
58+
// Use a very large value to represent the distant future
59+
millisSinceEpoch + Duration.seconds(.greatestFiniteMagnitude)
60+
}
61+
62+
/// Returns the Duration in milliseconds
63+
@usableFromInline
64+
func milliseconds() -> Int64 {
65+
Int64(self / .milliseconds(1))
66+
}
67+
68+
/// Create a Duration from milliseconds since Unix Epoch
69+
@usableFromInline
70+
init(millisSinceEpoch: Int64) {
71+
self = .milliseconds(millisSinceEpoch)
5372
}
5473
}
5574

@@ -103,7 +122,7 @@ extension AmazonHeaders {
103122
// The version number, that is, 1.
104123
let version: UInt = 1
105124
// The time of the original request, in Unix epoch time, in 8 hexadecimal digits.
106-
let now = UInt32(DispatchWallTime.now().millisSinceEpoch / 1000)
125+
let now = UInt32(Duration.millisSinceEpoch.milliseconds() / 1000)
107126
let dateValue = String(now, radix: 16, uppercase: false)
108127
let datePadding = String(repeating: "0", count: max(0, 8 - dateValue.count))
109128
// A 96-bit identifier for the trace, globally unique, in 24 hexadecimal digits.

0 commit comments

Comments
 (0)