From 1b31209fa9bc1fb97c9052d09bad6af4f381ffd6 Mon Sep 17 00:00:00 2001 From: Yuuya Ono Date: Fri, 4 Oct 2024 18:22:15 +0900 Subject: [PATCH 1/3] Introduce BufferedOutput#sendBufferedLogs --- Sources/Puree/Logger.swift | 6 ++++++ Sources/Puree/Output/BufferedOutput.swift | 24 ++++++++++++----------- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/Sources/Puree/Logger.swift b/Sources/Puree/Logger.swift index 624e0b0..77ad214 100644 --- a/Sources/Puree/Logger.swift +++ b/Sources/Puree/Logger.swift @@ -79,6 +79,12 @@ public final class Logger { } } + public func sendBufferedLogs() { + dispatchQueue.sync { + outputs.forEach { ($0 as? BufferedOutput)?.sendBufferedLogs() } + } + } + public func suspend() { dispatchQueue.sync { outputs.forEach { $0.suspend() } diff --git a/Sources/Puree/Output/BufferedOutput.swift b/Sources/Puree/Output/BufferedOutput.swift index 4bc9571..ca4e1d3 100644 --- a/Sources/Puree/Output/BufferedOutput.swift +++ b/Sources/Puree/Output/BufferedOutput.swift @@ -71,17 +71,13 @@ open class BufferedOutput: InstantiatableOutput { public func start() { reloadLogStore() - readWriteQueue.sync { - flush() - } + sendBufferedLogs() setUpTimer() } public func resume() { reloadLogStore() - readWriteQueue.sync { - flush() - } + sendBufferedLogs() setUpTimer() } @@ -100,19 +96,25 @@ open class BufferedOutput: InstantiatableOutput { logStore.add(log, for: storageGroup, completion: nil) if buffer.count >= logLimit { - flush() + writeBufferedLogs() } else if let logSizeLimit = configuration.chunkDataSizeLimit { let currentBufferedLogSize = buffer.reduce(0, { (size, log) -> Int in size + (log.userData?.count ?? 0) }) if currentBufferedLogSize >= logSizeLimit { - flush() + writeBufferedLogs() } } } } + public func sendBufferedLogs() { + readWriteQueue.sync { + writeBufferedLogs() + } + } + open func write(_ chunk: Chunk, completion: @escaping (Bool) -> Void) { completion(false) } @@ -138,12 +140,12 @@ open class BufferedOutput: InstantiatableOutput { if let lastFlushDate = lastFlushDate { if currentDate.timeIntervalSince(lastFlushDate) > flushInterval { readWriteQueue.async { - self.flush() + self.writeBufferedLogs() } } } else { readWriteQueue.async { - self.flush() + self.writeBufferedLogs() } } } @@ -165,7 +167,7 @@ open class BufferedOutput: InstantiatableOutput { } } - private func flush() { + private func writeBufferedLogs() { dispatchPrecondition(condition: .onQueue(readWriteQueue)) lastFlushDate = currentDate From e2b9b0ef8980d5844f8314ee659cf3bdf883ff79 Mon Sep 17 00:00:00 2001 From: Yuuya Ono Date: Fri, 4 Oct 2024 18:48:19 +0900 Subject: [PATCH 2/3] Add test for sendBufferedLogs --- .../Output/BufferedOutputTests.swift | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Tests/PureeTests/Output/BufferedOutputTests.swift b/Tests/PureeTests/Output/BufferedOutputTests.swift index 59859df..2ab5aee 100644 --- a/Tests/PureeTests/Output/BufferedOutputTests.swift +++ b/Tests/PureeTests/Output/BufferedOutputTests.swift @@ -63,6 +63,20 @@ class BufferedOutputTests: XCTestCase { XCTAssertEqual(output.calledWriteCount, 1) } + func testBufferedOutputSendBufferedLogs() { + output.configuration.logEntryCountLimit = 10 + + XCTAssertEqual(logStore.logs(for: "pv_TestingBufferedOutput").count, 0) + XCTAssertEqual(output.calledWriteCount, 0) + + output.emit(log: makeLog()) + output.sendBufferedLogs() + output.waitUntilCurrentQueuedJobFinished() + + XCTAssertEqual(logStore.logs(for: "pv_TestingBufferedOutput").count, 0) + XCTAssertEqual(output.calledWriteCount, 1) + } + func testBufferedOutputFlushedByInterval() { output.configuration.logEntryCountLimit = 10 output.configuration.flushInterval = 1 @@ -291,6 +305,28 @@ class BufferedOutputAsyncTests: XCTestCase { XCTAssertEqual(output.calledWriteCount, 1) } + func testBufferedOutputSendBufferedLogs() { + output.configuration.logEntryCountLimit = 10 + + let expectation = self.expectation(description: "async writing") + output.writeCallback = { + expectation.fulfill() + } + output.waitUntilCurrentCompletionBlock = { [weak self] in + self?.wait(for: [expectation], timeout: 1.0) + } + + XCTAssertEqual(logStore.logs(for: "pv_TestingBufferedOutput").count, 0) + XCTAssertEqual(output.calledWriteCount, 0) + + output.emit(log: makeLog()) + output.sendBufferedLogs() + output.waitUntilCurrentQueuedJobFinished() + + XCTAssertEqual(logStore.logs(for: "pv_TestingBufferedOutput").count, 0) + XCTAssertEqual(output.calledWriteCount, 1) + } + func testBufferedOutputFlushedByInterval() { output.configuration.logEntryCountLimit = 10 output.configuration.flushInterval = 1 From 998b519f70507e60ab8738a8bef30dca7063eb0d Mon Sep 17 00:00:00 2001 From: Yuuya Ono Date: Fri, 4 Oct 2024 18:49:08 +0900 Subject: [PATCH 3/3] Follow rename --- Tests/PureeTests/Output/BufferedOutputTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/PureeTests/Output/BufferedOutputTests.swift b/Tests/PureeTests/Output/BufferedOutputTests.swift index 2ab5aee..67ca584 100644 --- a/Tests/PureeTests/Output/BufferedOutputTests.swift +++ b/Tests/PureeTests/Output/BufferedOutputTests.swift @@ -101,7 +101,7 @@ class BufferedOutputTests: XCTestCase { XCTAssertEqual(output.calledWriteCount, 0) output.writeCallback = { - XCTFail("flush should not be called") + XCTFail("writeBufferedLogs should not be called") } sleep(2) } @@ -351,7 +351,7 @@ class BufferedOutputAsyncTests: XCTestCase { XCTAssertEqual(output.calledWriteCount, 0) output.writeCallback = { - XCTFail("flush should not be called") + XCTFail("writeBufferedLogs should not be called") } sleep(2) }