Z
Zhang Weiwu
Problem:
library method request() requests data from external server. Sometimes, if a
request is failed, it should be ignored, like price inquiry - if we don't
get the price, then no decision could be made based on the price, then we
simply do nothing about it; Sometimes, if a request is failed, it should
retry, and if retry failed, it should throw an exception, like the case with
placing order.
The problem is how to write the retry/exception code once only, not
everywhere when needed.
Solution:
1. Inheritance. Add a new parameter 'critical' to the inherited method:
class New(requests.Session): # inherit a library class
def request(self, *args, critical = False, *kwargs):
if not critical:
return super().request(*args, *kwargs)
else:
result = super().request(*args, *kwargs)
if result.status_code != 200: # unsuccessful
result = super().request(*args, *kwargs)
if result.status_code != 200: # unsuccessful
raise SpecificException()
return result
class BusinessLogic:
....
def place_order(self, *args):
...
server.request(method, URL, critical = True)
Disadvantage: sometimes request is not called directly. The business logic
class may call other wrappers of request() (e.g. post() and get()), thus we
need repeat the above code to all the wrappers.
2. Use method 1, and also use decorator to add 'critical' paramter to all
wrappers of request()
class New(requests.Session): # inherit a library class
def AddCriticalParamter(func):
.... # add an optional parameter 'critical', which, if set,
.... # cause to retry and exception to func
@New.AddCriticalParameter
def get(self, *args, critical = False, *kwargs):
return super().request(*args, *kwargs)
@New.AddCriticalParameter
def post(self, *args, critical = False, *kwargs):
return super().request(*args, *kwargs)
class BusinessLogic:
....
def place_order(self, *args):
...
server.get(method, URL, critical = True)
3. Use a wrapper class in business logic
class New(requests.Session): # inherit a library class
def Critical(func):
.... # change behavior, add retry and exception to func
class BusinessLogic: ....
def place_order(self, *args):
...
critical(server.get)(method, URL)
4. Any other method?
Question is: 1) am I thinking along the right line? and 2) what method will
you use/recommend?
library method request() requests data from external server. Sometimes, if a
request is failed, it should be ignored, like price inquiry - if we don't
get the price, then no decision could be made based on the price, then we
simply do nothing about it; Sometimes, if a request is failed, it should
retry, and if retry failed, it should throw an exception, like the case with
placing order.
The problem is how to write the retry/exception code once only, not
everywhere when needed.
Solution:
1. Inheritance. Add a new parameter 'critical' to the inherited method:
class New(requests.Session): # inherit a library class
def request(self, *args, critical = False, *kwargs):
if not critical:
return super().request(*args, *kwargs)
else:
result = super().request(*args, *kwargs)
if result.status_code != 200: # unsuccessful
result = super().request(*args, *kwargs)
if result.status_code != 200: # unsuccessful
raise SpecificException()
return result
class BusinessLogic:
....
def place_order(self, *args):
...
server.request(method, URL, critical = True)
Disadvantage: sometimes request is not called directly. The business logic
class may call other wrappers of request() (e.g. post() and get()), thus we
need repeat the above code to all the wrappers.
2. Use method 1, and also use decorator to add 'critical' paramter to all
wrappers of request()
class New(requests.Session): # inherit a library class
def AddCriticalParamter(func):
.... # add an optional parameter 'critical', which, if set,
.... # cause to retry and exception to func
@New.AddCriticalParameter
def get(self, *args, critical = False, *kwargs):
return super().request(*args, *kwargs)
@New.AddCriticalParameter
def post(self, *args, critical = False, *kwargs):
return super().request(*args, *kwargs)
class BusinessLogic:
....
def place_order(self, *args):
...
server.get(method, URL, critical = True)
3. Use a wrapper class in business logic
class New(requests.Session): # inherit a library class
def Critical(func):
.... # change behavior, add retry and exception to func
class BusinessLogic: ....
def place_order(self, *args):
...
critical(server.get)(method, URL)
4. Any other method?
Question is: 1) am I thinking along the right line? and 2) what method will
you use/recommend?