@@ -25,10 +25,11 @@ public class MBLoggerCoreDataManager {
2525 static let model = " CDLogMessage "
2626 static let dbSizeLimitKB : Int = 10_000
2727 static let operationLimitBeforeNeedToDelete = 20
28- static let batchSize = 10
28+ // static let batchSize = 10
2929 }
3030
31- private var logBuffer : [ LogMessage ] = [ ]
31+ private var logQueue : [ LogMessage ] = [ ]
32+ private var isWriting = false
3233
3334 private let queue = DispatchQueue ( label: " com.Mindbox.loggerManager " , qos: . utility)
3435 private var persistentStoreDescription : NSPersistentStoreDescription ?
@@ -85,122 +86,78 @@ public class MBLoggerCoreDataManager {
8586 } ( )
8687
8788 // MARK: - CRUD Operations
88- // public func create(message: String, timestamp: Date, completion: (() -> Void)? = nil) {
89- // queue.async {
90- // do {
91- // let isTimeToDelete = self.writeCount == 0
92- // self.writeCount += 1
93- // if isTimeToDelete && self.getDBFileSize() > Constants.dbSizeLimitKB {
94- // try self.delete()
95- // }
96- //
97- // try self.context.executePerformAndWait {
98- // let entity = CDLogMessage(context: self.context)
99- // entity.message = message
100- // entity.timestamp = timestamp
101- // try self.saveEvent(withContext: self.context)
102- //
103- // completion?()
104- // }
105- // } catch {}
106- // }
107- // }
108-
10989 public func create( message: String , timestamp: Date , completion: ( ( ) -> Void ) ? = nil ) {
110- guard #available ( iOS 15 . 0 , * ) else { return }
111-
112- let signpostID = Self . signposter . makeSignpostID ( )
90+ queue . async { [ weak self ] in
91+ guard let self = self else { return }
92+ self . logQueue . append ( LogMessage ( timestamp : timestamp , message : message ) )
11393
114- let state = Self . signposter. beginInterval ( #function, id: signpostID, " Start creating " )
115-
116- queue. async {
117- Self . signposter. emitEvent ( " Start creating LogMessage for buffer " , id: signpostID)
118- self . logBuffer. append ( LogMessage ( timestamp: timestamp, message: message) )
119-
120- if self . logBuffer. count >= Constants . batchSize {
121- Self . signposter. emitEvent ( " Start flushing buffer if logBuffer is full " , id: signpostID)
122- self . flushBuffer ( )
123- Self . signposter. endInterval ( #function, state, " End flushing buffer " )
124- completion ? ( )
125- return
94+ if !self . isWriting {
95+ self . writeNextBatch ( )
12696 }
12797
128- Self . signposter. endInterval ( #function, state, " End creating LogMessage for buffer " )
12998 completion ? ( )
13099 }
131100 }
132101
133- private func flushBuffer( ) {
134- guard #available( iOS 15 . 0 , * ) else { return }
135-
136- let signpostID = Self . signposterFlushBuffer. makeSignpostID ( )
102+ private func writeNextBatch( ) {
103+ guard !logQueue. isEmpty else { return }
137104
138- let state = Self . signposterFlushBuffer. beginInterval ( #function, id: signpostID, " Start flushing buffer " )
139-
140- guard !logBuffer. isEmpty else {
141- Self . signposterFlushBuffer. endInterval ( #function, state, " LogBuffer isEmpty " )
142- return
143- }
105+ isWriting = true
106+ let logsToWrite = logQueue
107+ logQueue. removeAll ( )
144108
145109 if #available( iOS 13 . 0 , * ) {
146- // Use NSBatchInsertRequest for iOS 13 and above
147- Self . signposterFlushBuffer. emitEvent ( " Core Data Insert Batch Operation Started " , id: signpostID)
148- performBatchInsert ( )
110+ performBatchInsert ( logs: logsToWrite)
149111 } else {
150- // Fallback to context-based insertion for iOS 12
151- performContextInsertion ( )
112+ performContextInsertion ( logs: logsToWrite)
152113 }
153-
154- Self . signposterFlushBuffer. endInterval ( #function, state, " End flushing buffer " )
155- checkDatabaseSizeAndDeleteIfNeeded ( )
156- //
157- // do {
158- // try context.executePerformAndWait {
159- // for log in self.logBuffer {
160- // Self.signposterFlushBuffer.emitEvent("CDLog creating for context", id: signpostID)
161- // let entity = CDLogMessage(context: self.context)
162- // entity.message = log.message
163- // entity.timestamp = log.timestamp
164- // }
165- //
166- // Self.signposterFlushBuffer.emitEvent("Core Data Save Context Operation Started", id: signpostID)
167- // try self.saveEvent(withContext: self.context)
168- // self.logBuffer.removeAll()
169- // self.checkDatabaseSizeAndDeleteIfNeeded()
170- // Self.signposterFlushBuffer.endInterval(#function, state, "End flushing buffer")
171- // }
172- // } catch {
173- // print("Failed to flush logs: \(error)")
174- // Self.signposterFlushBuffer.endInterval(#function, state, "Error occurred during flushing buffer")
175- // }
176114 }
177115
178116 @available ( iOS 13 . 0 , * )
179- private func performBatchInsert( ) {
180- let insertData = logBuffer. map { [ " message " : $0. message, " timestamp " : $0. timestamp] }
117+ private func performBatchInsert( logs: [ LogMessage ] ) {
118+ print ( #function)
119+ print ( logs. count)
120+ let insertData = logs. map { [ " message " : $0. message, " timestamp " : $0. timestamp] }
181121 let insertRequest = NSBatchInsertRequest ( entityName: Constants . model, objects: insertData)
182122
183- do {
184- try context. execute ( insertRequest)
185- logBuffer. removeAll ( )
186- } catch {
187- print ( " Failed to batch insert logs: \( error) " )
123+ context. perform { [ weak self] in
124+ guard let self = self else { return }
125+ do {
126+ try self . context. execute ( insertRequest)
127+ self . finishWriting ( )
128+ } catch {
129+ print ( " Failed to batch insert logs: \( error) " )
130+ self . finishWriting ( )
131+ }
188132 }
189133 }
190134
191- private func performContextInsertion( ) {
192- do {
193- try context. executePerformAndWait {
194- for log in self . logBuffer {
135+ private func performContextInsertion( logs: [ LogMessage ] ) {
136+ context. perform { [ weak self] in
137+ guard let self = self else { return }
138+ do {
139+ for log in logs {
195140 let entity = CDLogMessage ( context: self . context)
196141 entity. message = log. message
197142 entity. timestamp = log. timestamp
198143 }
199144 try self . saveEvent ( withContext: self . context)
200- self . logBuffer. removeAll ( )
145+ self . finishWriting ( )
146+ } catch {
147+ print ( " Failed to flush logs: \( error) " )
148+ self . finishWriting ( )
149+ }
150+ }
151+ }
152+
153+ private func finishWriting( ) {
154+ self . queue. async { [ weak self] in
155+ guard let self = self else { return }
156+ self . isWriting = false
157+ self . checkDatabaseSizeAndDeleteIfNeeded ( )
158+ if !self . logQueue. isEmpty {
159+ self . writeNextBatch ( )
201160 }
202- } catch {
203- print ( " Failed to flush logs: \( error) " )
204161 }
205162 }
206163
0 commit comments