Skip to content

Commit

Permalink
Merge pull request #4 from Lickability/fix/persister-expiration-policy
Browse files Browse the repository at this point in the history
Expiration Policy update
  • Loading branch information
ashlirankin authored Jan 31, 2023
2 parents 556198f + b9f663b commit faca66f
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 0 deletions.
7 changes: 7 additions & 0 deletions Sources/Persister/Cache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ public protocol Cache {
/// - key: The key that can be used to recall the written item later.
func write<Item: Codable>(item: Item, forKey key: String) throws

/// Writes an item to cache, providing an expiration policy.
/// - Parameters:
/// - item: The item to write to the cache.
/// - key: The key that can be used to recall the written item later.
/// - expirationPolicy: Determines when newly written items are considered expired.
func write<Item: Codable>(item: Item, forKey key: String, expirationPolicy: CacheExpirationPolicy) throws

/// Removes an item associated with the given `key`.
/// - Parameter key: The key associated with the item when it was written.
func remove(forKey key: String) throws
Expand Down
4 changes: 4 additions & 0 deletions Sources/Persister/DiskCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ extension DiskCache: Cache {
// MARK: - Cache

public func write<Item: Codable>(item: Item, forKey key: String) throws {
try write(item: item, forKey: key, expirationPolicy: expirationPolicy)
}

public func write<Item: Codable>(item: Item, forKey key: String, expirationPolicy: CacheExpirationPolicy) throws {
try diskManager.createDirectoryIfNecessary(directoryURL: rootDirectoryURL)

let filePath = persistencePath(forKey: key)
Expand Down
4 changes: 4 additions & 0 deletions Sources/Persister/MemoryCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ extension MemoryCache: Cache {
}

public func write<Item: Codable>(item: Item, forKey key: String) throws {
try write(item: item, forKey: key, expirationPolicy: expirationPolicy)
}

public func write<Item>(item: Item, forKey key: String, expirationPolicy: CacheExpirationPolicy) throws where Item : Decodable, Item : Encodable {
let expirationDate = expirationPolicy.expirationDate(from: Date())
let container = ItemContainer(item: item, expirationDate: expirationDate)

Expand Down
5 changes: 5 additions & 0 deletions Sources/Persister/Persister.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ extension Persister: Cache {
try diskCache.write(item: item, forKey: key)
}

public func write<Item: Codable>(item: Item, forKey key: String, expirationPolicy: CacheExpirationPolicy) throws {
try memoryCache.write(item: item, forKey: key, expirationPolicy: expirationPolicy)
try diskCache.write(item: item, forKey: key, expirationPolicy: expirationPolicy)
}

public func remove(forKey key: String) throws {
try memoryCache.remove(forKey: key)
try diskCache.remove(forKey: key)
Expand Down
19 changes: 19 additions & 0 deletions Tests/DiskCacheTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,23 @@ final class DiskCacheTests: XCTestCase {
}
}
}

func testUsesCorrectExpirationPolicy() throws {
let expectation = XCTestExpectation(description: "Only one item should have been removed.")

let cache = DiskCache(rootDirectoryURL: diskURL, expirationPolicy: .afterInterval(1))
try cache.write(item: TestCodable(), forKey: itemKey, expirationPolicy: .afterInterval(500))

DispatchQueue.main.asyncAfter(deadline: .now() + 2) {

try? cache.removeExpired()

let item1: ItemContainer<TestCodable>? = try? cache.read(forKey: self.itemKey)

XCTAssertNotNil(item1)

expectation.fulfill()
}
wait(for: [expectation], timeout: 5)
}
}
19 changes: 19 additions & 0 deletions Tests/MemoryCacheTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,23 @@ final class MemoryCacheTests: XCTestCase {
XCTAssertNotNil(item3)
XCTAssertNotNil(item4)
}

func testUsesCorrectExpirationPolicy() throws {
let expectation = XCTestExpectation(description: "Only one item should have been removed.")

let cache = MemoryCache(capacity: .unlimited, expirationPolicy: .afterInterval(1))
try cache.write(item: TestCodable(), forKey: itemKey, expirationPolicy: .afterInterval(500))

DispatchQueue.main.asyncAfter(deadline: .now() + 2) {

try? cache.removeExpired()

let item1: ItemContainer<TestCodable>? = try? cache.read(forKey: self.itemKey)

XCTAssertNotNil(item1)

expectation.fulfill()
}
wait(for: [expectation], timeout: 5)
}
}

0 comments on commit faca66f

Please sign in to comment.