Jiggle GCD Queues to Find Problems

To debug my threading issues and help bring forth future problems, I have created a simmple object that slows the current queue down:

let IsRunningTests = NSClassFromString("XCTestCase") != nil

struct QueueJigglePoint {

    /// Randomly interfere with the thread.
    static func jiggle() {
    
        guard !IsRunningTests else { return }
    
        #if DEBUG
            usleep(2*1000000) // 2 seconds
        #endif
    }

}

I got this idea from Brett Schuchert on pages 188–90 of Uncle Bob’s Clean Code. A Handbook of Agile Software Craftsmanship. There, interference with traditional threading should randomly sleep, yield, or fall through. Enqueued blocks are a lot less volatile, so I only came up with sleeping.

Randomizing the sleep interval is up next. But a fixed number of 2–10 seconds helps find UI-blocking code already.

Just throw in a QueueJigglePoint.jiggle() in NSManagedObjectContext.performBlock executions, when dispatching async to the background, or when reading files, for example.

Ideas to Solve Background Fetching and Saving Race Conditions with Core Data

I ran into problems with my Core Data Unit of Work/Transaction implementation the other day. I was not exercising good NSManagedObjectContext hygiene and end up with conflicts from time to time. Race conditions. Hate ‘em. The problem is that the parent–child setup of Core Data managed object contexts seems to work just fine for so-called “scratch pad” contexts: create a new child context, perform changes on in, then discard, or save to pass changes to the parent context.

Continue reading …