class ImpressionsCountSyncTask(BaseSynchronizationTask):
    """Impressions synchronization task uses an asynctask.AsyncTask to send impressions."""

    _PERIOD = 1800  # 30 * 60 # 30 minutes

    def __init__(self, synchronize_counters):
        """
        Class constructor.

        :param synchronize_counters: Handler
        :type synchronize_counters: func

        """
        self._task = AsyncTask(synchronize_counters, self._PERIOD, on_stop=synchronize_counters)

    def start(self):
        """Start executing the impressions synchronization task."""
        self._task.start()

    def stop(self, event=None):
        """Stop executing the impressions synchronization task."""
        self._task.stop(event)

    def is_running(self):
        """
        Return whether the task is running or not.

        :return: True if the task is running. False otherwise.
        :rtype: bool
        """
        return self._task.running()

    def flush(self):
        """Flush impressions in storage."""
        self._task.force_execution()
Пример #2
0
class EventsSyncTask(BaseSynchronizationTask):
    """Events synchronization task uses an asynctask.AsyncTask to send events."""
    def __init__(self, synchronize_events, period):
        """
        Class constructor.

        :param synchronize_events: Events Api object to send data to the backend
        :type synchronize_events: splitio.api.events.EventsAPI
        :param period: How many seconds to wait between subsequent event pushes to the BE.
        :type period: int

        """
        self._period = period
        self._task = AsyncTask(synchronize_events,
                               self._period,
                               on_stop=synchronize_events)

    def start(self):
        """Start executing the events synchronization task."""
        self._task.start()

    def stop(self, event=None):
        """Stop executing the events synchronization task."""
        self._task.stop(event)

    def flush(self):
        """Flush events in storage."""
        _LOGGER.debug('Forcing flush execution for events')
        self._task.force_execution()

    def is_running(self):
        """
        Return whether the task is running or not.

        :return: True if the task is running. False otherwise.
        :rtype: bool
        """
        return self._task.running()
class ImpressionsSyncTask(BaseSynchronizationTask):
    """Impressions synchronization task uses an asynctask.AsyncTask to send impressions."""

    def __init__(self, synchronize_impressions, period):
        """
        Class constructor.

        :param synchronize_impressions: sender
        :type synchronize_impressions: func
        :param period: How many seconds to wait between subsequent impressions pushes to the BE.
        :type period: int

        """
        self._period = period
        self._task = AsyncTask(synchronize_impressions, self._period,
                               on_stop=synchronize_impressions)

    def start(self):
        """Start executing the impressions synchronization task."""
        self._task.start()

    def stop(self, event=None):
        """Stop executing the impressions synchronization task."""
        self._task.stop(event)

    def is_running(self):
        """
        Return whether the task is running or not.

        :return: True if the task is running. False otherwise.
        :rtype: bool
        """
        return self._task.running()

    def flush(self):
        """Flush impressions in storage."""
        _LOGGER.debug('Forcing flush execution for impressions')
        self._task.force_execution()
Пример #4
0
class EventsSyncTask(BaseSynchronizationTask):
    """Events synchronization task uses an asynctask.AsyncTask to send events."""
    def __init__(self, events_api, storage, period, bulk_size):
        """
        Class constructor.

        :param events_api: Events Api object to send data to the backend
        :type events_api: splitio.api.events.EventsAPI
        :param storage: Events Storage
        :type storage: splitio.storage.EventStorage
        :param period: How many seconds to wait between subsequent event pushes to the BE.
        :type period: int
        :param bulk_size: How many events to send per push.
        :type bulk_size: int
        """
        self._logger = logging.getLogger(self.__class__.__name__)
        self._events_api = events_api
        self._storage = storage
        self._period = period
        self._failed = queue.Queue()
        self._bulk_size = bulk_size
        self._task = AsyncTask(self._send_events,
                               self._period,
                               on_stop=self._send_events)

    def _get_failed(self):
        """Return up to <BULK_SIZE> events stored in the failed eventes queue."""
        events = []
        count = 0
        while count < self._bulk_size:
            try:
                events.append(self._failed.get(False))
                count += 1
            except queue.Empty:
                # If no more items in queue, break the loop
                break
        return events

    def _add_to_failed_queue(self, events):
        """
        Add events that were about to be sent to a secondary queue for failed sends.

        :param events: List of events that failed to be pushed.
        :type events: list
        """
        for event in events:
            self._failed.put(event, False)

    def _send_events(self):
        """Send events from both the failed and new queues."""
        to_send = self._get_failed()
        if len(to_send) < self._bulk_size:
            # If the amount of previously failed items is less than the bulk
            # size, try to complete with new events from storage
            to_send.extend(
                self._storage.pop_many(self._bulk_size - len(to_send)))

        if not to_send:
            return

        try:
            self._events_api.flush_events(to_send)
        except APIException as exc:
            self._logger.error(
                'Exception raised while reporting events: %s -- %d',
                exc.message, exc.status_code)
            self._add_to_failed_queue(to_send)

    def start(self):
        """Start executing the events synchronization task."""
        self._task.start()

    def stop(self, event=None):
        """Stop executing the events synchronization task."""
        self._task.stop(event)

    def flush(self):
        """Flush events in storage."""
        self._task.force_execution()

    def is_running(self):
        """
        Return whether the task is running or not.

        :return: True if the task is running. False otherwise.
        :rtype: bool
        """
        return self._task.running()