Skip to content

Commit

Permalink
Patch (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
muukii authored Jun 23, 2023
1 parent 470ae39 commit f1fecaf
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 268 deletions.
20 changes: 16 additions & 4 deletions Demo/Demo/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,22 @@
// Created by muukii on 2020/02/03.
//

import SwiftUI
import BulkLogger
import SwiftUI

let logger = Logger(context: "", sinks: [])
let logger = Logger(
context: "",
sinks: [
BulkSink(
buffer: MemoryBuffer(size: 3).asAny(),
debounceDueTime: .seconds(3),
targets: [
OSLogTarget(subsystem: "a", category: "a").asAny()
]
)
.asAny()
]
)

struct ContentView: View {
var body: some View {
Expand All @@ -24,13 +36,13 @@ struct ContentView: View {
}) {
Text("Debug")
}

Button(action: {
logger.warn("Warn")
}) {
Text("Error")
}

Button(action: {
logger.error("Error")
}) {
Expand Down
8 changes: 4 additions & 4 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import PackageDescription
let package = Package(
name: "Bulk",
platforms: [
.macOS(.v10_12),
.iOS(.v10),
.tvOS(.v10),
.watchOS(.v3)
.macOS(.v11),
.iOS(.v13),
.tvOS(.v13),
.watchOS(.v5)
],
products: [
.library(name: "Bulk", targets: ["Bulk"]),
Expand Down
95 changes: 49 additions & 46 deletions Sources/Bulk/Core/BulkBufferTimer.swift
Original file line number Diff line number Diff line change
@@ -1,57 +1,60 @@
//
// Copyright (c) 2020 Hiroshi Kimura(Muukii) <[email protected]>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import Foundation
import Dispatch

public final class BulkBufferTimer {

let interval: DispatchTimeInterval
let queue: DispatchQueue
private let onTimeout: () -> Void

private var item: DispatchWorkItem?

public init(interval: DispatchTimeInterval, queue: DispatchQueue, onTimeout: @escaping () -> Void) {

public struct BulkBufferTimer {

private let interval: DispatchTimeInterval

private let onTimeout: @Sendable () async -> Void
private var item: Task<(), Never>?

public init(
interval: DispatchTimeInterval,
@_inheritActorContext onTimeout: @escaping @Sendable () async -> Void
) {

self.interval = interval
self.queue = queue
self.onTimeout = onTimeout

refresh()
}
public func tap() {

public mutating func tap() {
refresh()
}
private func refresh() {

private mutating func refresh() {

self.item?.cancel()

let _item = DispatchWorkItem(qos: .background, flags: []) {
self.onTimeout()

let task = Task { [onTimeout, interval] in

try? await Task.sleep(nanoseconds: interval.makeNanoseconds())

guard Task.isCancelled == false else { return }

await onTimeout()
}

self.item = task
}

}

extension DispatchTimeInterval {

fileprivate func makeNanoseconds() -> UInt64 {

switch self {
case .nanoseconds(let v): return UInt64(v)
case .microseconds(let v): return UInt64(v) * 1_000
case .milliseconds(let v): return UInt64(v) * 1_000_000
case .seconds(let v): return UInt64(v) * 1_000_000_000
case .never: return UInt64.max
@unknown default:
assertionFailure()
return 0
}

queue.asyncAfter(deadline: .now() + interval, execute: _item)
self.item = _item

}

}
59 changes: 25 additions & 34 deletions Sources/Bulk/Core/BulkSink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ public final class BulkSink<Element>: BulkSinkType {
private let targets: [AnyTarget<Element>]

private var timer: BulkBufferTimer!

private let _send: (Element) -> Void
private let _onFlush: () -> Void

private let buffer: AnyBuffer<Element>

Expand All @@ -28,35 +25,18 @@ public final class BulkSink<Element>: BulkSinkType {

self.buffer = buffer
self.targets = targets

let output: ([Element]) -> Void = { elements in
targets.forEach {
$0.write(items: elements)
}
}

self.timer = BulkBufferTimer(interval: debounceDueTime, queue: targetQueue) {
let elements = buffer.purge()
output(elements)
}

self._send = { [targetQueue] newElement in

targetQueue.async {
switch buffer.write(element: newElement) {
case .flowed(let elements):
// TODO: align interface of Collection
return output(elements.map { $0 })
case .stored:
break
}
}

}
self.timer = BulkBufferTimer(interval: debounceDueTime) { [weak self] in

guard let self else { return }

self._onFlush = {
let elements = buffer.purge()
output(elements)

self.targets.forEach {
$0.write(items: elements)
}

self.timer.tap()
}

}
Expand All @@ -65,15 +45,26 @@ public final class BulkSink<Element>: BulkSinkType {

}

public func send(_ element: Element) {
targetQueue.async {
self._send(element)
public func send(_ newElement: Element) {
targetQueue.async { [self] in
switch buffer.write(element: newElement) {
case .flowed(let elements):
// TODO: align interface of Collection
targets.forEach {
$0.write(items: elements)
}
case .stored:
break
}
}
}

public func flush() {
targetQueue.async {
self._onFlush()
targetQueue.async { [self] in
let elements = buffer.purge()
targets.forEach {
$0.write(items: elements)
}
}
}

Expand Down
Loading

0 comments on commit f1fecaf

Please sign in to comment.