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@lists.jboss.org
https://lists.jboss.org/mailman/listinfo/aerogear-dev