Be warned I'm only on my first cup of coffee :)
On 07/25/2013 12:20 PM, Yavuz Selim YILMAZ 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. 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).
The reason we use the
thread pool executor is because the onPostExcute
method runs on the UI thread. If your Pipe is running form a service
that means that things happening on onSuccess would block the UI
thread. This wouldn't be obvious to the user.
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),
So the threading bits
aren't explicitly defined in the Pipes 101 doc.
What the docs say to do will get you around this issue though. If you
use the Pipeline get methods which take in some form of context
(Activity, Fragment, fragment activity, etc) then you will have
onSuccess run on the UI thread. Otherwise you want.
Sounds like a trip to the JIRA mobile for better docs.
In general you want to use these methods because it tells lets AG do
some smart things behind the scenes with respect to managing the
network, data caching, etc.
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.
So, my first question is, can somebody point me where these threading
designs were discussed?
Probably not. The best thread I can think of would be back
from
February but it really doesn't define anything.
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).
The goals behind the design were to leverage as much
of than Android API
to handle the activity lifecycle as possible. It did mean that there
are somethings which just have to be "known" and the docs should
highlight them. IE if you are calling things from an Activity or
Fragment then you should pass the context to the pipeline.get method.
If the docs aren't clear (or if we need to explain the full
implications) then that is a JIRA.
If people have better ideas then that is a ML thread and then maybe a
JIRA :)
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(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/aerogear-dev