My question is about how to design code that works well with object oriented design and asynchronous deferreds (instead of blocking code)
Ok two ways I am thinking about designing the class (are any of these good designs or am I forgetting something)
First Way
class Grooveshark(object):
def get_session(self):
d = # implementation detail (gets page)
d.addCallback(self.parse_session)# implmentation detail
# all in all this goes through and sets self.session to the session value (it does not return it though; should I set it and return it?)
self.session_time = time.time()
return d
def get_country_id(self):
# implmentation acts same as d just parses to diferrent id
# also it grabs the same page; ANNOYING having to get the page twice ugh
def get_token(self):
# relies on self.session being set
d = # implmentation detail
d.addCallback(self.parse_token)# implmentation detail
# at the end of the day it sets self.token and then fires the deferred (same as session does not send it through the deferred, again should I seem repetitive?)
return d
def construct_api_call(method, url, implmentation_arguments...)
# checks if session is hour old
if self.session_time - 3600 <= time.time() or self.session is None:
# update
d = get_session()
# some how pass deferred or something
d.addCallback(lambda ignored: self.get_country_id)
d.addCallback(lambda ignored: self.get_token())
d.addCallback(lambda ignored: self.construct_api_call(method, url, implmentation_arguments)
# if error retry
d.addErrback(lambda error: log.err(error))
d.addErrback(lambda ignored: self.construct_api_call(method, url, implmentation_arguments)
return d# would this work? problem: with this how do I get it so I can do this whole update and do this again with the deferred I returned
else:
#implmentation details
return d# fires when done with api call
Second Way
class Grooveshark(object): def get_session(self):
d = # implmentation detail
# differance this sends the session down the deferred callback and sets the instance var self.session (seems strange both modifying state and returning)
def get_token(self, session):
d = # gets token but uses session argument NOT intance variable
def get_country_id # same as first class
def construct_api_call(session, session_time, token, country_id, all the other args in above class):
# problems it requires user of api to store session etc also how do I return if needs update right now I just error
if self.session_time - 3600 <= time.time():
raise RuntimeError("You need to update your session, ugh why does the user have to store the session ugh")
else:
# does what above class does as well