Skip to content

Commit acaba2e

Browse files
authored
Add tidy frequency to MemoryPersistDriver (#707)
* Add tidy frequency to MemoryPersistDriver - Fix bug where expired test was the wrong way around - Add test for tidy * Fix breaking change
1 parent 4f20ed2 commit acaba2e

File tree

2 files changed

+46
-4
lines changed

2 files changed

+46
-4
lines changed

Sources/Hummingbird/Storage/MemoryPersistDriver.swift

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,35 @@ import NIOCore
1818

1919
/// In memory driver for persist system for storing persistent cross request key/value pairs
2020
public actor MemoryPersistDriver<C: Clock>: PersistDriver where C.Duration == Duration {
21+
public struct Configuration: Sendable {
22+
/// amount of time between each call to tidy
23+
public var tidyFrequency: Duration
24+
25+
/// Initialize MemoryPersistDriver configuration
26+
/// - Parameter tidyFrequency:
27+
public init(tidyFrequency: Duration = .seconds(600)) {
28+
self.tidyFrequency = tidyFrequency
29+
}
30+
}
31+
32+
/// Initialize MemoryPersistDriver
33+
/// - Parameters:
34+
/// - clock: Clock to use when calculating expiration dates
35+
@_disfavoredOverload
2136
public init(_ clock: C = .continuous) {
2237
self.values = [:]
2338
self.clock = clock
39+
self.configuration = .init()
40+
}
41+
42+
/// Initialize MemoryPersistDriver
43+
/// - Parameters:
44+
/// - clock: Clock to use when calculating expiration dates
45+
/// - configuration: Configuration of driver
46+
public init(_ clock: C = .continuous, configuration: Configuration = .init()) {
47+
self.values = [:]
48+
self.clock = clock
49+
self.configuration = configuration
2450
}
2551

2652
public func create(key: String, value: some Codable & Sendable, expires: Duration?) async throws {
@@ -51,7 +77,7 @@ public actor MemoryPersistDriver<C: Clock>: PersistDriver where C.Duration == Du
5177
let now = self.clock.now
5278
self.values = self.values.compactMapValues {
5379
if let expires = $0.expires {
54-
if expires > now {
80+
if expires < now {
5581
return nil
5682
}
5783
}
@@ -72,7 +98,7 @@ public actor MemoryPersistDriver<C: Clock>: PersistDriver where C.Duration == Du
7298
}
7399

74100
public func run() async throws {
75-
let timerSequence = AsyncTimerSequence(interval: .seconds(600), clock: .suspending)
101+
let timerSequence = AsyncTimerSequence(interval: self.configuration.tidyFrequency, clock: self.clock)
76102
.cancelOnGracefulShutdown()
77103
for try await _ in timerSequence {
78104
self.tidy()
@@ -81,4 +107,5 @@ public actor MemoryPersistDriver<C: Clock>: PersistDriver where C.Duration == Du
81107

82108
var values: [String: Item]
83109
let clock: C
110+
let configuration: Configuration
84111
}

Tests/HummingbirdTests/PersistTests.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ import XCTest
1919
final class PersistTests: XCTestCase {
2020
static let redisHostname = Environment().get("REDIS_HOSTNAME") ?? "localhost"
2121

22-
func createRouter() throws -> (Router<BasicRequestContext>, PersistDriver) {
22+
func createRouter(
23+
configuration: MemoryPersistDriver<ContinuousClock>.Configuration = .init()
24+
) throws -> (Router<BasicRequestContext>, PersistDriver) {
2325
let router = Router()
24-
let persist = MemoryPersistDriver()
26+
let persist = MemoryPersistDriver(configuration: configuration)
2527

2628
router.put("/persist/:tag") { request, context -> HTTPResponse.Status in
2729
let buffer = try await request.body.collect(upTo: .max)
@@ -225,4 +227,17 @@ final class PersistTests: XCTestCase {
225227
}
226228
}
227229
}
230+
231+
func testTidy() async throws {
232+
let (router, persist) = try createRouter(configuration: .init(tidyFrequency: .milliseconds(1)))
233+
let app = Application(responder: router.buildResponder(), services: [persist])
234+
try await app.test(.router) { client in
235+
let tag = UUID().uuidString
236+
try await client.execute(uri: "/persist/\(tag)/10", method: .put, body: ByteBufferAllocator().buffer(string: "NotExpired")) { _ in }
237+
try await Task.sleep(for: .milliseconds(20))
238+
try await client.execute(uri: "/persist/\(tag)", method: .get) { response in
239+
XCTAssertEqual(String(buffer: response.body), "NotExpired")
240+
}
241+
}
242+
}
228243
}

0 commit comments

Comments
 (0)