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?
--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to