Skip to content

Commit

Permalink
Merge pull request #208 from GSM-MSG/207-throttler-implement
Browse files Browse the repository at this point in the history
🔀 :: Throttler 구현
  • Loading branch information
baekteun authored Jun 15, 2023
2 parents 10e75eb + 4dd5fbe commit 2ad0a19
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 50 deletions.
16 changes: 5 additions & 11 deletions Projects/Core/EventLimiter/Sources/Debouncer.swift
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
import Foundation

public actor Debouncer {
public final class Debouncer {
private let dueTime: UInt64
private var task: Task<Void, Never>?

public init(for dueTime: Double) {
public init(for dueTime: TimeInterval) {
self.dueTime = UInt64(dueTime * 1_000_000_000)
}

public init(for dueTime: Int) {
self.dueTime = UInt64(dueTime * 1_000_000_000)
}

public nonisolated func callAsFunction(action: @escaping () async -> Void) {
Task {
await execute(action: action)
}
public func callAsFunction(action: @escaping () async -> Void) {
execute(action: action)
}

public func execute(action: @escaping () async -> Void) {
private func execute(action: @escaping () async -> Void) {
task?.cancel()
self.task = Task {
do {
Expand Down
37 changes: 23 additions & 14 deletions Projects/Core/EventLimiter/Sources/Throttler.swift
Original file line number Diff line number Diff line change
@@ -1,37 +1,46 @@
import Foundation

@available(*, unavailable, message: "아직 구현되지 않은 객체입니다.")
public actor Throttler {
private let dueTime: TimeInterval
public final class Throttler {
private let latest: Bool
private let dueTime: UInt64
private var task: Task<Void, Never>?
private var action: (() async -> Void)?
private var isInitial = true

public init(for dueTime: TimeInterval) {
self.dueTime = dueTime
public init(for dueTime: TimeInterval, latest: Bool = true) {
self.dueTime = UInt64(dueTime * 1_000_000_000)
self.latest = latest
}

public nonisolated func callAsFunction(
latest: Bool = true,
public func callAsFunction(
action: @escaping () async -> Void
) {
Task {
await execute(latest: latest, action: action)
}
execute(action: action)
}

public func execute(
latest: Bool = true,
private func execute(
action: @escaping () async -> Void
) {
if latest {
self.action = action
}
guard task?.isCancelled ?? true else { return }

Task {
await action()
self.action = nil
}

self.task = Task {
try? await Task.sleep(nanoseconds: UInt64(dueTime) * 1_000_000_000)
self.task = Task { [weak self] in
guard let self else { return }
try? await Task.sleep(nanoseconds: dueTime)
self.task?.cancel()
self.task = nil

if latest, let action = self.action {
await action()
self.action = nil
}
}
}
}
64 changes: 39 additions & 25 deletions Projects/Core/EventLimiter/Tests/DebouncerTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,44 @@ final class DebouncerTests: XCTestCase {
override func tearDownWithError() throws {}

func testExample() async {
// let throttler = Throttler(for: 1)
//
// throttler {
// print("ASDf")
// }
// throttler {
// print("ASDf2")
// }
//
// try? await Task.sleep(nanoseconds: 500_000_000)
// throttler {
// print("ASDf3")
// }
//
// try? await Task.sleep(nanoseconds: 600_000_000)
// throttler {
// print("ASDf4")
// }
//
// try? await Task.sleep(nanoseconds: 200_000_000)
// throttler {
// print("ASDf5")
// }
//
// try? await Task.sleep(nanoseconds: 5_000_000_000)
let debouncer = Debouncer(for: 1)

debouncer {
print("ASDf")
}
debouncer {
print("ASDf2")
}

try? await Task.sleep(nanoseconds: 1_000_000_000)
debouncer {
print("ASDf3")
}

try? await Task.sleep(nanoseconds: 600_000_000)
debouncer {
print("ASDf4")
}

try? await Task.sleep(nanoseconds: 200_000_000)
debouncer {
print("ASDf5")
}

try? await Task.sleep(nanoseconds: 400_000_000)
debouncer {
print("ASDf6")
}
debouncer {
print("ASDf7")
}

try? await Task.sleep(nanoseconds: 2_000_000_000)

debouncer {
print("ASDf8")
}

try? await Task.sleep(nanoseconds: 2_000_000_000)
}
}
44 changes: 44 additions & 0 deletions Projects/Core/EventLimiter/Tests/ThrottlerTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import XCTest
import EventLimiter

final class ThrottlerTests: XCTestCase {
override func setUpWithError() throws {}

override func tearDownWithError() throws {}

func testExample() async {
let throttler = Throttler(for: 1)

throttler {
print("ASDf")
}
throttler {
print("ASDf2")
}

try? await Task.sleep(nanoseconds: 500_000_000)
throttler {
print("ASDf3")
}

try? await Task.sleep(nanoseconds: 600_000_000)
throttler {
print("ASDf4")
}

try? await Task.sleep(nanoseconds: 200_000_000)
throttler {
print("ASDf5")
}

try? await Task.sleep(nanoseconds: 400_000_000)
throttler {
print("ASDf6")
}
throttler {
print("ASDf7")
}

try? await Task.sleep(nanoseconds: 5_000_000_000)
}
}

0 comments on commit 2ad0a19

Please sign in to comment.