🔍 Overview

These Celery tasks monitor active Links and block them when they become unsafe or unreachable.

When a link is blocked, Link Switcher tries to switch traffic to the next backup link in Voluum via MirrorRule.

Main tasks:

  1. check_active_links_via_google_task — checks ACTIVE link domains via Google Safe Browsing.
  2. check_active_domains_via_dns_task — blocks domains that are not resolvable via DNS.
  3. rotation_check_active_links_task — blocks links whose rotation interval has expired.
  4. block_link_task — blocks a specific link and triggers switching.
  5. fix_pipelines_task — fixes failed switches in MirrorRule (safety net).

⏱ Schedule (Celery Beat)

Configured in config/settings.py:

  • check_active_links_via_google_task — every CHECK_ACTIVE_LINKS_INTERVAL seconds
  • rotation_check_active_links_task — every 15 minutes
  • fix_pipelines_task — every hour (minute 0)

📝 Task Definitions

@celery.task
def check_active_links_via_google_task():
    domain_map = Link.get_domains_map()
    if not domain_map:
        return
 
    VoluumController.load_data(landers=True, offers=True, campaigns=False)
 
    for chunk_domains in chunked(list(domain_map.keys())):
        unsafe_domains = GoogleSafeBrowsing.check_links(chunk_domains)
        if unsafe_domains is None:
            continue
        for unsafe_domain, reason in unsafe_domains.items():
            for obj in domain_map[unsafe_domain]:
                block_link_task.delay(link_id=obj.id, reason=reason)
 
    check_active_domains_via_dns_task.delay()
 
 
@celery.task
def block_link_task(link_id: int, reason: str = BlockReasons.UNKNOWN, action_by: str = "system"):
    try:
        link = Link.objects.get(id=link_id)
    except Link.DoesNotExist:
        return
 
    if link.status != LinkStatuses.ACTIVE:
        return
 
    link.set_block(reason=reason, with_switch=True, action_by=action_by)

NameTypeDescription
link_idintPrimary key of the Link to block.
reasonstrBlock reason (DNS / rotation / Google Safe Browsing threat type).
action_bystrActor causing the block (system or a username).

⚙️ Task Behavior & Flow

  1. Google Safe Browsing check

    • Groups active links by domain.
    • Calls Google Safe Browsing in batches.
    • Enqueues block_link_task for unsafe domains.
  2. DNS check

    • Blocks domains that fail DNS resolution using BlockReasons.DNS_NOT_RESOLVABLE.
  3. Rotation check

    • Blocks links with with_rotation=True when their rotation interval has expired using BlockReasons.ROTATION.
  4. Blocking & switching

    • block_link_task calls Link.set_block(..., with_switch=True).
    • Switching to the next backup is handled by MirrorRule.switch(...).
  5. Pipeline maintenance

    • fix_pipelines_task retries failed MirrorRule.switch() executions and cleans up mirror rules stuck in an inconsistent state.