Using DispatchSemaphore to control async execution

I’ve been debugging the upcoming OPML Import functionality of NewsWave and this bug was driving me nuts:  in some cases and for no apparent reason URLSessions would fail without a callback. 

At first the bug seemed random, but after a bit of testing I realized the more feeds I tried to import, the more likely the bug would materialize. 

After looking at error codes from Xcode, the issue seemed to be related to having too many URLSessions opened in parallel. What can I do to fix this? Well, DispatchSemaphore of course! 

Transit

DispatchSemaphore works by allowing certain execution cycles to go through and holding the rest until you signal its time to continue. Here’s an example of how it works, in this case I’m allowing up to 20 simultaneous queries:

 

 

let semaphoreOfImportQueries = DispatchSemaphore(value: 20) //Starting
with 20 credits.

for iteratorOfFeeds in feedImportQueries{

       //Wait reduces semaphoreOfImportQueries by
1, if it reaches 0 the execution will wait here

semaphoreOfImportQueries.wait() 

 

       self.functionThatCallsAnAPIAndExecutesAsync(completionHandler: { _ in

           //Signal allows the next process to start by adding 1 to semaphoreOfImportQueries

semaphoreOfImportQueries.signal() 

 
           

        })

}

This is a great tool to have in your toolbox when dealing with URL Sessions. Important though, this should always be executed on a background thread else you’ll block the main queue.

 

Marc

—-

 

 

 

Twitter -> @MarcMasVi     |     Micro.blog -> @MarcMV