def test_rate_limit():
    assert redis.exists(POLL_SIMPLE_THROTTLE)
    assert update_package_list() is None

    redis.delete(POLL_SIMPLE_THROTTLE)
    assert not redis.exists(POLL_SIMPLE_THROTTLE)
    assert list() == update_package_list()

    assert redis.exists(POLL_SIMPLE_THROTTLE)
    assert update_package_list() is None
Example #2
0
def sync():
    """Sync local database with data from PyPI's API through a Celery task."""
    if redis.exists(POLL_SIMPLE_THROTTLE):
        flash.warning(
            'Already sycned once within the past hour. Not syncing until lock expires.'
        )
        return redirect(url_for('.index'))

    # Schedule the task.
    task = update_package_list.delay()  # Schedule the task to execute ASAP.

    # Attempt to obtain the results.
    for _ in range(int(WAIT_UP_TO / SLEEP_FOR)):
        time.sleep(SLEEP_FOR)
        if not task.ready():
            continue  # Task is still running.
        results = task.get(propagate=False)

        if isinstance(results, Exception):
            # The task crashed probably because of a bug in the code.
            if str(results) == 'Failed to acquire lock.':
                # Never mind, no bug. The task was probably running from Celery Beat when the user tried to run a second
                # instance of the same task.
                # Since the user is expecting this task to update the database, we'll tell them that results should be
                # updated within the minute, since the previously-running task should finish shortly.
                flash.info(
                    'Task scheduled, any new packages will appear within 1 minute.'
                )
                return redirect(url_for('.index'))
            raise results  # HTTP 500.

        if not results:
            flash.info('No new packages found.')
            return redirect(url_for('.index'))

        if len(results) < 5:
            flash.info('New packages: {}'.format(', '.join(results)))
        else:
            flash.modal('New packages found:\n{}'.format(', '.join(results)))
        return redirect(url_for('.index'))

    # If we get here, the timeout has expired and the task is still running.
    flash.info(
        'Task scheduled, any new packages will appear within 15 minutes.')
    return redirect(url_for('.index'))
def sync():
    """Sync local database with data from PyPI's API through a Celery task."""
    if redis.exists(POLL_SIMPLE_THROTTLE):
        flash.warning('Already sycned once within the past hour. Not syncing until lock expires.')
        return redirect(url_for('.index'))

    # Schedule the task.
    task = update_package_list.delay()  # Schedule the task to execute ASAP.

    # Attempt to obtain the results.
    for _ in range(int(WAIT_UP_TO / SLEEP_FOR)):
        time.sleep(SLEEP_FOR)
        if not task.ready():
            continue  # Task is still running.
        results = task.get(propagate=False)

        if isinstance(results, Exception):
            # The task crashed probably because of a bug in the code.
            if str(results) == 'Failed to acquire lock.':
                # Never mind, no bug. The task was probably running from Celery Beat when the user tried to run a second
                # instance of the same task.
                # Since the user is expecting this task to update the database, we'll tell them that results should be
                # updated within the minute, since the previously-running task should finish shortly.
                flash.info('Task scheduled, any new packages will appear within 1 minute.')
                return redirect(url_for('.index'))
            raise results  # HTTP 500.

        if not results:
            flash.info('No new packages found.')
            return redirect(url_for('.index'))

        if len(results) < 5:
            flash.info('New packages: {}'.format(', '.join(results)))
        else:
            flash.modal('New packages found:\n{}'.format(', '.join(results)))
        return redirect(url_for('.index'))

    # If we get here, the timeout has expired and the task is still running.
    flash.info('Task scheduled, any new packages will appear within 15 minutes.')
    return redirect(url_for('.index'))