Wrapper to call a given func on a syndic, best effort to get the one you asked for

def _call_syndic(self, func, args=(), kwargs=None, master_id=None):
        '''
        Wrapper to call a given func on a syndic, best effort to get the one you asked for
        '''
        if kwargs is None:
            kwargs = {}
        successful = False
        # Call for each master
        for master, syndic_future in self.iter_master_options(master_id):
            if not syndic_future.done() or syndic_future.exception():
                log.error(
                    'Unable to call %s on %s, that syndic is not connected',
                    func, master
                )
                continue

            try:
                getattr(syndic_future.result(), func)(*args, **kwargs)
                successful = True
            except SaltClientError:
                log.error(
                    'Unable to call %s on %s, trying another...',
                    func, master
                )
                self._mark_master_dead(master)
        if not successful:
            log.critical('Unable to call %s on any masters!', func)