def req(self,
            is_search,
            path,
            meth,
            params=None,
            data=None,
            request_options=None):
        """Perform an HTTPS request with retry logic."""

        # Merge params and request_options params.
        params = {} if params is None else params.copy()
        if request_options is not None and request_options.parameters is not None:
            params.update(request_options.parameters)
        params = urlify(params)

        # Merge headers and request_options headers.
        headers = {} if self.headers is None else self.headers.copy()
        if request_options is not None and request_options.headers is not None:
            headers.update(request_options.headers)

        if data is not None:
            data = json.dumps(data, cls=CustomJSONEncoder)

        hosts = self._get_hosts(is_search)
        timeout = self.search_timeout if is_search else self.timeout

        exceptions = {}
        for i, host in enumerate(hosts):
            old_timeout = None
            if i > 1:
                timeout += 10
                old_timeout = self.conn_timeout
                yield from self.set_conn_timeout(self.conn_timeout + 2)

            try:
                coro = self._req(host, path, meth, timeout, params, data,
                                 is_search)
                return (yield from coro)
            except AlgoliaException as e:
                newrelic.agent.record_exception()
                raise e
            # TODO: Handle task canceling.
            except Exception as e:
                newrelic.agent.record_exception()
                self._rotate_hosts(is_search)
                self._dns_timer = time.time()
                exceptions[host] = '%s: %s' % (e.__class__.__name__, str(e))
            finally:
                if old_timeout is not None:
                    yield from self.set_conn_timeout(old_timeout)
        raise AlgoliaException('Unreachable hosts: %s', exceptions)
Example #2
0
 def _req(self, host, path, meth, timeout, params, data, is_search):
     """Perform an HTTPS request with aiohttp's ClientSession."""
     if is_search and self.http_search:
         url = 'http://%s%s' % (host, path)
     else:
         url = 'https://%s%s' % (host, path)
     req = self.session.request(meth, url, params=params, data=data,
                                headers=self.headers)
     res = yield from req
     with async_timeout.timeout(timeout):
         if res.status // 100 == 2:
             return (yield from res.json())
         elif res.status // 100 == 4:
             message = 'HTTP Code: %d' % res.status
             try:
                 message = (yield from res.json())['message']
             finally:
                 raise AlgoliaException(message)
     # TODO: Check this for replacement.
     res.raise_for_status()
Example #3
0
    def delete_ab_test(self, ab_test_id):
        if ab_test_id == '':
            raise AlgoliaException('ab_test_id cannot be empty')

        return self._req('/2/abtests/%s' % safe(ab_test_id), 'DELETE')
Example #4
0
    def stop_ab_test(self, ab_test_id):
        if ab_test_id == '':
            raise AlgoliaException('ab_test_id cannot be empty')

        return self._req('/2/abtests/%s/stop' % safe(ab_test_id), 'POST')