Skip to content

Commit

Permalink
Make HeartbeatController also conform to Sendable
Browse files Browse the repository at this point in the history
  • Loading branch information
ncooke3 committed Oct 21, 2024
1 parent 597de2b commit f651b8e
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import Foundation

/// An object that provides API to log and flush heartbeats from a synchronized storage container.
public final class HeartbeatController {
public final class HeartbeatController: Sendable {
/// Used for standardizing dates for calendar-day comparison.
private enum DateStandardizer {
private static let calendar: Calendar = {
Expand All @@ -31,11 +31,11 @@ public final class HeartbeatController {
}

/// The thread-safe storage object to log and flush heartbeats from.
private let storage: HeartbeatStorageProtocol
private let storage: any HeartbeatStorageProtocol
/// The max capacity of heartbeats to store in storage.
private let heartbeatsStorageCapacity: Int = 30
private static let heartbeatsStorageCapacity: Int = 30
/// Current date provider. It is used for testability.
private let dateProvider: () -> Date
private let dateProvider: @Sendable () -> Date
/// Used for standardizing dates for calendar-day comparison.
private static let dateStandardizer = DateStandardizer.self

Expand All @@ -51,7 +51,7 @@ public final class HeartbeatController {
/// - Parameters:
/// - id: The id to associate this controller's heartbeat storage with.
/// - dateProvider: A date provider.
convenience init(id: String, dateProvider: @escaping () -> Date) {
convenience init(id: String, dateProvider: @escaping @Sendable () -> Date) {
let storage = HeartbeatStorage.getInstance(id: id)
self.init(storage: storage, dateProvider: dateProvider)
}
Expand All @@ -61,7 +61,7 @@ public final class HeartbeatController {
/// - storage: A heartbeat storage container.
/// - dateProvider: A date provider. Defaults to providing the current date.
init(storage: HeartbeatStorageProtocol,
dateProvider: @escaping () -> Date = Date.init) {
dateProvider: @escaping @Sendable () -> Date = Date.init) {
self.storage = storage
self.dateProvider = { Self.dateStandardizer.standardize(dateProvider()) }
}
Expand All @@ -76,7 +76,7 @@ public final class HeartbeatController {

storage.readAndWriteAsync { heartbeatsBundle in
var heartbeatsBundle = heartbeatsBundle ??
HeartbeatsBundle(capacity: self.heartbeatsStorageCapacity)
HeartbeatsBundle(capacity: Self.heartbeatsStorageCapacity)

// Filter for the time periods where the last heartbeat to be logged for
// that time period was logged more than one time period (i.e. day) ago.
Expand Down Expand Up @@ -109,7 +109,7 @@ public final class HeartbeatController {
// The new value that's stored will use the old's cache to prevent the
// logging of duplicates after flushing.
return HeartbeatsBundle(
capacity: self.heartbeatsStorageCapacity,
capacity: Self.heartbeatsStorageCapacity,
cache: oldHeartbeatsBundle.lastAddedHeartbeatDates
)
}
Expand All @@ -129,14 +129,14 @@ public final class HeartbeatController {
@available(iOS 13.0, macOS 10.15, macCatalyst 13.0, tvOS 13.0, watchOS 6.0, *)
public func flushAsync() async -> HeartbeatsPayload {
return await withCheckedContinuation { continuation in
let resetTransform = { (heartbeatsBundle: HeartbeatsBundle?) -> HeartbeatsBundle? in
let resetTransform = { @Sendable (heartbeatsBundle: HeartbeatsBundle?) -> HeartbeatsBundle? in
guard let oldHeartbeatsBundle = heartbeatsBundle else {
return nil // Storage was empty.
}
// The new value that's stored will use the old's cache to prevent the
// logging of duplicates after flushing.
return HeartbeatsBundle(
capacity: self.heartbeatsStorageCapacity,
capacity: Self.heartbeatsStorageCapacity,
cache: oldHeartbeatsBundle.lastAddedHeartbeatDates
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import Foundation

/// A type that can perform atomic operations using block-based transformations.
protocol HeartbeatStorageProtocol {
protocol HeartbeatStorageProtocol: Sendable {
func readAndWriteSync(using transform: (HeartbeatsBundle?) -> HeartbeatsBundle?)
func readAndWriteAsync(using transform: @escaping @Sendable (HeartbeatsBundle?)
-> HeartbeatsBundle?)
Expand Down

0 comments on commit f651b8e

Please sign in to comment.