-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DRAFT] Core Data Migration #176
base: main
Are you sure you want to change the base?
Conversation
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.OpenSSF Scorecard
Scanned Files
|
Generated by 🚫 Danger Swift against 40ff859 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NachoEmbrace great work here. A lotttt of work. One thought, regarding thread safety, given CoreData requires careful handling of contexts. Do we have something that does explicit handling of background contexts vs main context?
Thinking something like this
`public class CoreDataContextManager {
let mainContext: NSManagedObjectContext
let backgroundContext: NSManagedObjectContext
private let logger: InternalLogger
init(persistentContainer: NSPersistentContainer, logger: InternalLogger) {
self.logger = logger
// Main context for UI operations
mainContext = persistentContainer.viewContext
mainContext.automaticallyMergesChangesFromParent = true
// Background context for async operations
backgroundContext = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
backgroundContext.parent = mainContext
}
func performBackgroundTask(_ block: @escaping (NSManagedObjectContext) -> Void) {
backgroundContext.perform { [weak self] in
guard let self = self else { return }
block(self.backgroundContext)
do {
try self.backgroundContext.save()
self.mainContext.performAndWait {
try? self.mainContext.save()
}
} catch {
self.logger.error("Failed to save context: \(error)")
}
}
}
}`
which I know would be a good amount of added work but it could be used in some way like
`public func cleanUpSpans(date: Date? = nil) {
contextManager.performBackgroundTask { context in
let request = SpanRecord.createFetchRequest()
if let date = date {
request.predicate = NSPredicate(format: "endTime != nil AND endTime < %@", date as NSDate)
} else {
request.predicate = NSPredicate(format: "endTime != nil")
}
let spans = try? context.fetch(request)
spans?.forEach { context.delete($0) }
}
}`
I haven't found the need to use the I managed to make it stable by making all core data operations synchronous (which is not the best in terms of speed, to be fair); and also using a |
# Conflicts: # Project.swift
# Conflicts: # Sources/EmbraceCore/Internal/Tracing/StorageSpanExporter.swift # Sources/EmbraceStorageInternal/Migration/Migrations/Migrations+Current.swift # Sources/EmbraceStorageInternal/Queries/SpanRecord+SessionQuery.swift # Sources/EmbraceStorageInternal/Records/SpanRecord.swift # Tests/EmbraceCoreTests/IntegrationTests/EmbraceOTelStorageIntegration/SpanStorageIntegrationTests.swift # Tests/EmbraceCoreTests/Internal/EmbraceSpanProcessor+StorageTests.swift # Tests/EmbraceStorageInternalTests/FetchMethods/EmbraceStorage+SpanForSessionRecordTests.swift # Tests/EmbraceStorageInternalTests/Migration/Migrations/Migrations+CurrentTests.swift # Tests/EmbraceStorageInternalTests/SpanRecordTests.swift
EmbraceCommonInternal
to define our data model (ieEmbraceSession
,EmbraceSpan
, etc).SessionRecord
,SpanRecord
, etc objects directlyNSManagedObjects
and can't be initialized without a CoreData stackNote: Still missing some tests and A LOT of manual testing.