Hi Olivier
Hi Matej,
mato konecny wrote:
> Hi all,
>
> First of all, I am not Twisted nor Python expert, so this question is
> maybe trivial. The question is related to an IMDB plugin.
> Anyway, I created a layer between my resource provider (that does some
> HTTTP operations and returns deferred) and the controllers. This is
> mainly for caching and convenience purposes and works quite OK. What I
> do, I create a singleton of my extra layer (retriever) which then
> internally calls resource provider. The problem is that if user has
for
> example 20 movies in library, that means 20 defereds are fired almost
> instantly, resulting in 20 HTTP GETs (and some more because of the
> resource provider implementation).
> This is also bit annoying for user because then the responses to the
GET
> requests arrive asynchronously and therefore I want to implement a
> queueing mechanism. I got some inspiration from MediaScanner, so
create
> an object, in that one create deferred and put this in the queue and
> return created deferred. When the time comes, the object is taken out
of
> the queue, processed and (here comes my problem) how can I signal the
> original callee that "it's finished".
> Maybe this needs some code example, probably it's bit too long to post
> it here, but I can add it later if it clarifies what I am talking
about :)
What I don't really get is why you would want to queue requests and make
an asynchronous process synchronous. Elisa uses asynchrony to provide
the user a responsive UI and it is perfectly fine to receive delayed
answers when populating some part of the UI. Just make sure you display
some default image e.g. while waiting for the answer.
I already have this mechanism in place, the UI updates when the deferred is
fired. The issue is that I just retrieve all deferreds and all of them start at
the same time. This means 20x HTTP GET (search query), after that parsing,
another HTTP GET (get movie query), parsing, another HTTP GET (get poster
query) and then the deferred is "finished". The second and 3rd GETs are taking
time randomly and instead of getting all data and poster of movie 1, then movie
2 etc I get part of data from movie 1, then search result from movie 2, poster
result from movie 3. This is not the bigges issue though, scan is done only
once and the results are cached. I would like to cancel the deferreds if some
of the nodes in the GridView is clicked. There are then 2 possibilities: keep
hash of all deferreds and cancel them; or create a "queue" of incomming
requests and defer them one after eachother, when we need to cancel, we just
clear the queue.
As far as I understand, you don't need a queuing mechanism, just to
connect callbacks to your deferreds that will populate your UI (or take
whatever action needed) when fired.
If I misunderstood your problem don't hesitate to ask again, maybe with
a simple use case and/or code snippets.
OK, let me write some pseudocode, the full code is in my bazaar branch
(lp:~konecm/elisa/movie-library) It's bit longer but I think it might help
explaining... The mentioned branch contains the "stable" code where everything
is done the neat "deferred way" :)
class IMDBResourceProvider(...): .... get() ....
class MovieDataRetriever(singleton):
def enqueue(item, signal_done_cb)
item.dfr=Deferred()
set item in a queue
start scanning the queue if not started
def _scan()
def _done()
item.signal_done_cb()
if not queue empty:
next queue item
queue.get(item)
dfr=resourceprovider.get(item)...
dfr.addCallback(_done)
class ...(hieararchycontroller)
def node_clicked()
movieDataRetriever.queue=Queue()
...
class ListViewMode(...):
def get_image()
dfr = Deferred()
def _done_cb(res)
dfrcallbacks(res)
def _update_ui(res)
...update UI code...
movieDataRetriever.enqueue(item, _done_cb)
dfr.addCallback(_update_ui)
So, this is what I was able to get up and running, everything is now processed
one after eachother, I can cancel everything, let user see which element is
being currently processed... I am not very happy with the solution though, the
original "all deferred" solution was cleaner, but to cancel deferreds I would
have to create hash of all deferreds in the retriever and then operate on that
one, ending up with incomplete models etc.
One last thing - after clicking a node, the movie is not played, but detailed
information is shown, so if there are 20 movies being processed, then user will
wait pretty long time just to get info about one.
Cheers
Matej
> Cheers,
> Matej
Cheers,
Olivier
----------
www.inPage.sk ��� Domena, webhosting, e-mail a seo od 3 Sk/denne.