ios - Synchronous network calls blocking other calls on startup -
i have app hundreds of different network calls (http requests) rest service. calls done every single page of app , there of them. there requirement 2 requests have done (on startup or awake) before other network requests happens. result of these 2 requests config data needed before other following requests. (this requirement has many reason)
i have 1 central method requests. uses afnetworking , (of course) asynchronous handlers:
func get(path: string, var parameters: dictionary<string, string>? = nil) -> future<anyobject!> { let promise = promise<anyobject!>() manager.get(path, parameters: parameters, success: { (task: nsurlsessiondatatask!, response: anyobject!) -> void in // processing... promise.success(response) }) { (task: nsurlsessiondatatask!, error: nserror!) -> void in // failure handling... promise.failure(error) } return promise.future } the problem - how first 2 calls , block other calls until 2 succeed? obvious solution semaphore blocks thread (not main!) until 2 calls arrive if possible want avoid solution. (because of deadlocks, race conditions, how error handling, etc... usual suspects)
so there better solution this?
the synchronous order has be:
- 1st call
- wait successful response of 1st call
- 2nd call
- wait or successful response of 2nd call
- allow other calls (async) in order
i can not logic on upper layers of app because requests come every part of app, need rewrite everthing. want centrally on single request.
maybe possible promise/future pattern use, hints welcome.
thanks.
there couple of approaches tackle class of problem:
- you can use gcd (as shown in the answer linked to) using semaphores or dispatch groups.
- you can use asynchronous
nsoperationcustom subclass in conjunctionnsoperationqueue. - or can use promises.
but i'd suggest pick 1 of these three, don't try introduce dispatch/operation queue patterns existing futures/promises code. people suggest dispatch/operation queue approaches because how 1 solves type of problem (using futures not gained popular acceptance yet, , there competing promises/futures libraries out there). promises/futures designed solve precisely problem, , if you're using that, stick it.
on specifics of dispatch/operation approaches, explain why don't gcd approach , try convince use nsoperationqueue approach, that's moot if you're using promises/futures.
the challenge here, though, appear using old version of thomvis/brightfutures. current version takes 2 types generic. code below won't work you. i'll offer as suggestion, may illustrative.
for example, let's imagine had loginurl (the first request), , second request wanted perform after that, had array urls wanted run concurrently respect each other, after first 2 requests done. using 3.2.2 of brightfutures, might like:
get(loginurl).flatmap { responseobject -> future<anyobject!, nserror> in return self.get(secondrequesturl) }.flatmap { responseobject -> future<int, nserror> in return urls.map { self.get($0) }.fold(0) { sum, _ in sum + 1 } }.onsuccess { count in print("\(count) concurrent requests completed successfully") }.onfailure { error in print("not successful: \(error)") } judging code snippet, must using old version of brightfutures, above won't work written, illustrates basic idea. use capabilities of brightfutures manage these asynchronous tasks , control done sequentially , done concurrently.
Comments
Post a Comment