Exemplo n.º 1
0
 async def acquire(self):
     for connection in self.connections:
         if not connection.is_busy:
             return connection
     else:
         await self._lock.acquire()
         for connection in self.connections:
             if not connection.is_busy:
                 self._lock.release()
                 return connection
         if len(self.connections) < self.max_connections:
             try:
                 connection = await self.connect()
             except Exception as e:
                 logger.error('Could not connect to server: %s', str(e))
                 self._lock.release()
                 raise ConnectionError()
             self.connections.append(connection)
             self._lock.release()
             return connection
         else:
             self._lock.release()
             logger.warning('Pool is busy, wait...')
             while True:
                 await asyncio.sleep(0.01)
                 for connection in self.connections:
                     if not connection.is_busy:
                         return connection
Exemplo n.º 2
0
 def on_response_received(self, headers):
     notification_id = headers.get(b'apns-id').decode('utf8')
     status = headers.get(b':status').decode('utf8')
     if status == APNS_RESPONSE_CODE.SUCCESS:
         request = self.requests.pop(notification_id, None)
         if request:
             result = NotificationResult(notification_id, status)
             request.set_result(result)
         else:
             logger.warning(
                 'Got response for unknown notification request %s',
                 notification_id)
     else:
         self.request_statuses[notification_id] = status
Exemplo n.º 3
0
 def data_received(self, data):
     for event in self.conn.receive_data(data):
         if isinstance(event, ResponseReceived):
             headers = dict(event.headers)
             self.on_response_received(headers)
         elif isinstance(event, DataReceived):
             self.on_data_received(event.data, event.stream_id)
         elif isinstance(event, RemoteSettingsChanged):
             self.on_remote_settings_changed(event.changed_settings)
         elif isinstance(event, StreamEnded):
             self.on_stream_ended(event.stream_id)
         elif isinstance(event, ConnectionTerminated):
             self.on_connection_terminated(event)
         elif isinstance(event, WindowUpdated):
             pass
         else:
             logger.warning('Unknown event: %s', event)
     self.flush()
Exemplo n.º 4
0
    def on_data_received(self, data, stream_id):
        data = json.loads(data.decode())
        reason = data.get('reason', '')
        if not reason:
            return

        notification_id = self.request_streams.pop(stream_id, None)
        if notification_id:
            request = self.requests.pop(notification_id, None)
            if request:
                # TODO: Теоретически здесь может быть ошибка, если нет ключа
                status = self.request_statuses.pop(notification_id)
                result = NotificationResult(notification_id,
                                            status,
                                            description=reason)
                request.set_result(result)
            else:
                logger.warning('Could not find request %s', notification_id)
        else:
            logger.warning('Could not find notification by stream %s',
                           stream_id)
Exemplo n.º 5
0
 async def send_notification(self, request):
     attempt = 0
     while True:
         attempt += 1
         if attempt > self.MAX_ATTEMPTS:
             logger.warning('Trying to send notification %s: attempt #%s',
                            request.notification_id, attempt)
         logger.debug('Notification %s: waiting for connection',
                      request.notification_id)
         try:
             connection = await self.acquire()
         except ConnectionError:
             logger.warning(
                 'Could not send notification %s: '
                 'ConnectionError', request.notification_id)
             await asyncio.sleep(1)
             continue
         logger.debug('Notification %s: connection %s acquired',
                      request.notification_id, connection)
         try:
             response = await connection.send_notification(request)
             return response
         except NoAvailableStreamIDError:
             connection.close()
         except ConnectionClosed:
             logger.warning(
                 'Could not send notification %s: '
                 'ConnectionClosed', request.notification_id)
         except FlowControlError:
             logger.debug('Got FlowControlError for notification %s',
                          request.notification_id)
             await asyncio.sleep(1)
Exemplo n.º 6
0
 def on_stream_ended(self, stream_id):
     if stream_id % 2 == 0:
         logger.warning('End stream: %d', stream_id)
     self.free_channels.release()
Exemplo n.º 7
0
 def on_connection_terminated(self, event):
     logger.warning(
         'Connection %s terminated: code=%s, additional_data=%s, '
         'last_stream_id=%s', self, event.error_code, event.additional_data,
         event.last_stream_id)
     self.close()