コード例 #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
コード例 #2
0
 async def send_notification(self, request):
     response = NotificationResult(request.notification_id,
                                   APNS_RESPONSE_CODE.BAD_REQUEST)
     response.description = "connection error"
     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)
         return response
     logger.debug('Notification %s: connection %s acquired',
                  request.notification_id, connection)
     response.description = "internal error"
     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)
     except:
         logger.debug('internal error for %s', request.notification_id)
     return response
コード例 #3
0
ファイル: connection.py プロジェクト: vitalerter/aioapns
 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.create_connection()
             except Exception as e:
                 logger.error("Could not connect to server: %s", str(e))
                 self._lock.release()
                 raise ConnectionError()
             self.connections.append(connection)
             logger.info("Connection established (total: %d)",
                         len(self.connections))
             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
コード例 #4
0
    async def send_notification(self, request):
        failed_attempts = 0
        while True:
            logger.debug('Notification %s: waiting for connection',
                         request.notification_id)
            try:
                connection = await self.acquire()
            except ConnectionError:
                failed_attempts += 1
                logger.warning('Could not send notification %s: '
                               'ConnectionError', request.notification_id)

                if self.max_connection_attempts \
                        and failed_attempts > self.max_connection_attempts:
                    logger.error('Failed to connect after %d attempts.',
                                 failed_attempts)
                    raise

                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)
コード例 #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)
         connection = await self.acquire()
         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)
コード例 #6
0
ファイル: connection.py プロジェクト: vitalerter/aioapns
 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()
コード例 #7
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
コード例 #8
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()
コード例 #9
0
ファイル: connection.py プロジェクト: Fatal1ty/aioapns
 async def send_notification(self, request):
     attempts = 0
     while attempts < self.max_connection_attempts:
         attempts += 1
         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)
     logger.error("Failed to send after %d attempts.", attempts)
     raise MaxAttemptsExceeded
コード例 #10
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)
コード例 #11
0
ファイル: connection.py プロジェクト: doordu/aioapns
 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:
             connection = await self.connect()
             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
コード例 #12
0
 def on_stream_ended(self, stream_id):
     if stream_id % 2 == 0:
         logger.warning('End stream: %d', stream_id)
     self.free_channels.release()