Hi Yavuz,

thanks for your feedback!

please find my answer inline.

On Jul 25, 2013, at 7:20 PM, Yavuz Selim YILMAZ <yavuzsel@buffalo.edu> wrote:

Hi all,

When I was using AeroGear iOS, I needed to read from pipe and execute the success and failure blocks in background (for background data syncronization, a basic one which provides eventual data consistency). What I did first was this:

dispatch a thread
    read from pipe
        --- READ ---
        success
            --- SUCCESS BLOCK ---
        failure
            --- FAILURE BLOCK ---
            
However, when I checked, I realized that the success and failure blocks were being executed on the main thread, not on the thread that I initiated the read.

correct on your assumption, the success() block is executed on the main thread. AeroGear networking stack builds on top of AFNetworking lib, where the provided success block is, by default, called back on the main thread.  Although there is an 'option' to override the default behaviour by providing your own dispatch queues for succ/fail callback. Mind creating a JIRA for that, not sure yet the details but would like to have a look at.

A fact is, that most net libraries do make that assumption, basically for covering most usage case scenarios, e.g networking on the background, update UI on the success block. That said, nothing prevents you, on the success block to 'dispatch' another thread to do some other work (eg. dispatch_async etc), as I presume you did in your example.


Then I needed to modify the code and do like this (I know all "--- READ ---"s are already in background):

read from pipe
    --- READ ---
    success
        dispatch a thread
            --- SUCCESS BLOCK ---
    failure
        dispatch a thread
            --- FAILURE BLOCK ---
            
At that time, I was going to ask the reason behind dispatching back to the main queue for success and failure blocks, but then I thought the idea is coming from Android's AsyncTask.
So my wrong assumption made sense as I thought having similar way of handling the end-developer (hope you get what I mean by end-developer) operations (in this case read from pipe) would help to use same/similar software architectures for different platforms (iOS and Android in this case).

Then I started to taste AeroGear Android from the last week. Keeping my hard times with multithreading on iOS in mind, I was expecting to see the read from pipe code something like this:

create AsyncTask
    doInBackground
        --- READ ---
    onPostExecute
        success
            --- SUCCESS BLOCK ---
        failure
            --- FAILURE BLOCK ---
            
However, what I've seen on RestAdapter was quite different:

create new thread
    --- READ ---
    success
        --- SUCCESS BLOCK ---
    failure
        --- FAILURE BLOCK ---

And here, success and failure blocks are being executed on the background thread instead of on the UI thread. I checked why not using AsyncTask for this operation (as I was using it for my network operations if I need to touch the UI thread at onProgress and at onPostExecute), and I realized that there is a reason behind using ThreadPoolExecutor (no deep research though, I only know it is recommended considering the operations might take longer). So, in Android case, making sure the availability of the UI thread when executing success and failure blocks is left to the end-developer as far as I could see (please correct me if I am wrong), while in iOS case the execution of the success or failure blocks indicates that the main thread is up and running at that time. The difference is maybe because of the way iOS and Android handles the execution of the background threads. But, when first tasting the libs for both platforms, I did not feel comfortable with (it was not so obvious) on which thread the success and failure blocks are executed.

I will leave Summers and Passos to comment on that better, but my initially guess is you didn't wrap the returned Pipe with the 'Loaders' API (eg. Pipeline.get(String, ..))

So, my first question is, can somebody point me where these threading designs were discussed? I am curious about the idea behind these designs (platform pushes that way? easy to implement? common way of doing network operations? or any other specific reason?), and hoping to learn new things from there (actually I am sure I will).

It's basically common way of doing network operation and that's the reason you see this workflow.


Second and the last thing, I think somewhere in the guides and docs, the threading (best practices when using AeroGear) should be emphasized/mentioned/explained. Because, although things are smooth and easy when the operations take little amount of time, things are becoming more complicated when the operations take longer as the device users' app usage pattern is unknown. (e.g. for Android, I needed to check thread name/id to actually realize the success/failure blocks were being executed on the background thread (e.g. Pipes 101 mentions to be aware of Android Activity Lifecycle, but not so clear what happens during the execution - is it going to stop? is it going to execute on UI thread or background? will I need to check if UI thread is there or not? etc.). And for iOS, I needed to have a really blocking success/failure code to realize it was running on the main thread, since then I was looking for some other parts to see why scrolling was not smooth).

Kind regards,

---
Yavuz Selim Yilmaz
SUNY at Buffalo
Computer Science and Engineering
PhD Candidate

_______________________________________________
aerogear-dev mailing list
aerogear-dev@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/aerogear-dev