Example #1
0
 def __init__(self, client, mainwindow):
     self._init_multicall = Multicall(client)
     self.mainwindow = mainwindow
     self._calls_id = {}
Example #2
0
class InitMultiCall(object):
    """
    when started, join all calls needed by frontend in one multicall
    calls, additionnal id of service (can be empty):
        [(component_name1, service_name1, [count]), (component_name2, service_name2, [count])]
    """
    COMP_SERV_FORMAT = '%s-%s'
    def __init__(self, client, mainwindow):
        self._init_multicall = Multicall(client)
        self.mainwindow = mainwindow
        self._calls_id = {}

    def run(self):
        self._init_responses = self._init_multicall()
        assert len(self._calls_id) == len(self._init_responses),\
            "number of responses != number of calls (%s %s)" % (len(self._calls_id), len(self._init_responses))

    def listConfigCalls(self, pages, calls):
        """
        build list of init calls

        Search static method get_calls in frontend and frontend's base classes
        'get_calls' must return one iterable which contains tuple like that:
            (component_name1, service_name1, count)

        Third argument in tuples is not mandatory (it's 1 by default) :
            ('component', 'service') <=> ('component', 'service', 1)
        """

        if calls is not None:
            assert callable(calls), "InitMultiCall.__init__(...) : 'calls' parameter must be callable"
            for component_name, service_name in calls():
                self._addCall(component_name, service_name)

        #for frontend in tuple(pages.itervalues()):
        if isinstance(pages, dict):
            iterable = pages.itervalues()
        else:
            iterable = tuple(pages)
        for frontend in iterable:
            self.addCallsForFrontend(frontend)

    def addCallsForFrontend(self, frontend):
        if not isinstance(frontend, type):
            frontend = type(frontend)
        parents = getmro(frontend)
        for parent_class in parents:
            if not issubclass(parent_class, (ScrollArea, NuConfForm)):
                continue
            for call in parent_class.get_calls():
                if 2 == len(call):
                    call = call + (1,)
                component_name, service_name, count = call
                assert count >= 1, "count must be >= 1"
                for i in xrange(count):
                    self._addCall(component_name, service_name)


    def _addCall(self, component_name, service_name):
        """
        add service to dict call_id
        """
        service_id = self.COMP_SERV_FORMAT % (component_name, service_name)
        if service_id not in self._calls_id:
            # store index inside future response (append to self._calls_id)
            CallParam(service_id,self._calls_id)
            self._init_multicall.addCall(component_name, service_name)
        else:
            self._calls_id[service_id].increment()

    def isCached(self, component, service):
        service_id = self.COMP_SERV_FORMAT % (component, service)
        return self._calls_id.has_key(service_id)

    def getResponse(self, component, service):
        """
        service could not have parameters (static parameters could be implemented)
        """
        service_id = self.COMP_SERV_FORMAT % (component, service)
        assert not self._calls_id[service_id].done(), "getResponse for '%s' '%s' no more in cache" % (component, service)
        self._calls_id[service_id].decrement()
        result = self._init_responses[self._calls_id[service_id].getIndex()]
        if isinstance(result, RpcdError):
            self.mainwindow.writeError(result, "Error calling service '%s.%s'" % (component, service))
            return None

        return deepcopy(result)

    def clean(self):
        """
        response is not needed anymore
        """
        self._calls_id.clear()
        del self._init_responses[:]