diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2020-08-18 13:40:03 +0200 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2020-08-18 17:18:20 +0200 |
| commit | 2940ff87341193a1278fc0e16de32a03e4025dc3 (patch) | |
| tree | a589edb7f11ba6b9beb3b5603803c316642d0209 | |
| parent | ec96a7e65a252533ed3634995dfcc64887ec3112 (diff) | |
| download | mullvadvpn-2940ff87341193a1278fc0e16de32a03e4025dc3.tar.xz mullvadvpn-2940ff87341193a1278fc0e16de32a03e4025dc3.zip | |
Watch file renames in the log streamer
| -rw-r--r-- | ios/MullvadVPN/Logging/LogStreamer.swift | 53 | ||||
| -rw-r--r-- | ios/MullvadVPN/Logging/TextFileStream.swift | 3 |
2 files changed, 48 insertions, 8 deletions
diff --git a/ios/MullvadVPN/Logging/LogStreamer.swift b/ios/MullvadVPN/Logging/LogStreamer.swift index aba7fec4d8..bd4583e8ce 100644 --- a/ios/MullvadVPN/Logging/LogStreamer.swift +++ b/ios/MullvadVPN/Logging/LogStreamer.swift @@ -17,9 +17,11 @@ class LogStreamer<Codec> where Codec: UnicodeCodec { private let fileURLs: [URL] private var remainingFileURLs: [URL] private var streams = [TextFileStream<Codec>]() + private var eventSources = [DispatchSourceFileSystemObject]() private let queue = DispatchQueue(label: "net.mullvad.MullvadVPN.LogStreamer<\(Codec.self)>") private var retry: DispatchWorkItem? private var handlerBlock: ((String) -> Void)? + private var isStarted = false init(fileURLs: [URL]) { self.fileURLs = fileURLs @@ -28,6 +30,9 @@ class LogStreamer<Codec> where Codec: UnicodeCodec { func start(handler: @escaping (String) -> Void) { queue.async { + guard !self.isStarted else { return } + + self.isStarted = true self.handlerBlock = handler self.poll() } @@ -35,9 +40,14 @@ class LogStreamer<Codec> where Codec: UnicodeCodec { func stop() { queue.async { + guard self.isStarted else { return } + + self.isStarted = false + self.retry?.cancel() self.handlerBlock = nil + self.eventSources.removeAll() self.streams.removeAll() self.remainingFileURLs = self.fileURLs } @@ -49,7 +59,15 @@ class LogStreamer<Codec> where Codec: UnicodeCodec { if let stream = TextFileStream<Codec>(fileURL: fileURL, separator: "\n") { streams.append(stream) - didAddStream(stream) + stream.read { [weak self] (s) in + guard let self = self else { return } + + self.queue.async { + self.handlerBlock?(s) + } + } + + addFileWatch(fileURL: fileURL, stream: stream) } else { failedURLs.append(fileURL) } @@ -68,20 +86,41 @@ class LogStreamer<Codec> where Codec: UnicodeCodec { private func scheduleRetry() { let workItem = DispatchWorkItem(block: { [weak self] in - self?.poll() + guard let self = self, self.isStarted else { return } + + self.poll() }) queue.asyncAfter(wallDeadline: .now() + .seconds(kLogPollIntervalSeconds), execute: workItem) retry = workItem } - private func didAddStream(_ stream: TextFileStream<Codec>) { - stream.read { [weak self] (s) in - guard let self = self else { return } + /// Watch file renames and re-add the stream once that happens + private func addFileWatch(fileURL: URL, stream: TextFileStream<Codec>) { + let source = DispatchSource.makeFileSystemObjectSource( + fileDescriptor: stream.fileDescriptor, + eventMask: .rename, + queue: queue + ) - self.queue.async { - self.handlerBlock?(s) + source.setEventHandler { [weak self, weak source] in + guard let self = self, self.isStarted else { return } + + // Cancel current event source + source?.cancel() + + // Release the stream + self.streams.removeAll { (s) -> Bool in + return stream === s } + + // Add the file URL to backlog & poll + self.remainingFileURLs.append(fileURL) + self.poll() } + + source.activate() + + eventSources.append(source) } } diff --git a/ios/MullvadVPN/Logging/TextFileStream.swift b/ios/MullvadVPN/Logging/TextFileStream.swift index a6a260aedd..de1aad6d91 100644 --- a/ios/MullvadVPN/Logging/TextFileStream.swift +++ b/ios/MullvadVPN/Logging/TextFileStream.swift @@ -12,8 +12,9 @@ import Foundation import Darwin class TextFileStream<Codec> where Codec: UnicodeCodec { + let fileDescriptor: Int32 + private let readSource: DispatchSourceRead - private let fileDescriptor: Int32 private let queue = DispatchQueue(label: "net.mullvad.MullvadVPN.TextFileStream<\(Codec.self)>") private let stringStream: StringStreamIterator<Codec> |
