def fetch_parameter_with_info(self, force_update=False):
        """
            Called by agent to retrieve parameters
            By default, pulls from PS ONLY WHEN the parameter hash changes
                to prevent duplicate fetching. No-op when duplicate.
            Caching can be overriden by force_update

        Args:
            force_update: forces download of parameter, regardless of
                currently cached hash

        Returns:
            (param or None, info or None)
        """
        try:
            if force_update:
                response = self._client.request('parameter')
            else:
                response = self._client.request('parameter:' + self._last_hash)
        except ZmqTimeoutError:
            self.on_fetch_parameter_failed()
            return None, None
        self.on_fetch_parameter_success()
        param, info = response
        if info is None:
            return None, None

        self._last_hash = info['hash']
        return param, info

            Called by agent to retrieve parameters
            By default, pulls from PS ONLY WHEN the parameter hash changes
                to prevent duplicate fetching. No-op when duplicate.
            Caching can be overriden by force_update

        Args:
            force_update: forces download of parameter, regardless of
                currently cached hash

        Returns:
            (param or None, info or None)
        
surreal/distributed/parameter_server.py