Rewrite cache and content provider
Provider should maintain its own database ("cache") and directly respond to clients requests. It should synchronize independently from widgets calls (but of course sometime some of these would trigger CommaFeed requests).
class Provider:
def get_articles(self, cb, feed_id, no=20, offset=0, unread=True):
if self.enough_entries(feed_id, no, offset):
cb(self.articles(feed_id, no, offset))
elif maybe_cf_has_more_articles(feed_id, no, offset):
# async_call should call cb(None) when nothing is fetched and properly update
# "maybe_more" variable (or something like that)
self._async_call(client.get_articles, cb, id=feed_id, limit=no, offset=offset, readType=unread)
else:
cb(None)
Of course, it can be implemented as a cache decorators (the way it is implemented now), but this will be hell of a lot harder and dirtier, because decorators would have to know about Provider interface details:
# module: cache
# we'll need to write a separate decorator for (almost) each Provider method.
def get_articles(fn):
def _wrapped(obj, cb, feed_id, no=20, offset=0, unread=True):
if enough_entries(feed_id, no, offset):
cb(entries(feed_id, no, offset)
else:
my_cb = functoo.partial(articles_wrap, real_cb=cb)
return fn(my_cb, feed_id, no, offset, unread)
return _wrapped
return _dec
# module: content
class Provider:
@cache.get_articles
def get_articles(self, cb, feed_id, no=20, offset=0, unread=True):
self._async_call(client.get_articles, cb, id=feed_id, limit=no, offset=offset, readType=unread)
So for a sake of being clear, simple and explicit, it'll be better to just implement it in Provider.