Skip to content

bug: cancel operation is not durable — feeders overwrite CANCELLED status #20

Description

@ChefControl

Description

The cancel operation (DELETE /api/v1/crawls/:id) sets all PENDING/IN-PROGRESS URLs to CANCELLED atomically, but feeders that are already mid-processing overwrite the CANCELLED status back to COMPLETED and continue creating new PENDING children. This effectively undoes the cancel.

Steps to Reproduce

  1. Start a deep crawl (e.g., https://wikipedia.org at depth 5)
  2. Wait until feeders are actively processing (multiple IN-PROGRESS jobs)
  3. Cancel the crawl via DELETE /api/v1/crawls/:id
  4. Observe: the crawl continues growing, cancelled count stays at 0

Root Cause

Two issues in feeder/src/job.rs:

1. update_job_status unconditionally overwrites status (line 82)

MATCH (n:URL {name: $name, http_type: $http_type, current_depth: $current_depth, crawl_id: $crawl_id})
SET n.job_status = $status, n.attempts = $attempts

When a feeder finishes processing a job, it calls update_job_status(graph, job, "COMPLETED", ...) which overwrites the CANCELLED status set by the cancel operation.

Fix: Add a guard clause:

MATCH (n:URL {name: $name, http_type: $http_type, current_depth: $current_depth, crawl_id: $crawl_id})
WHERE n.job_status <> 'CANCELLED'
SET n.job_status = $status, n.attempts = $attempts

2. batch_create_children doesn't check for cancellation (line 167)

After a feeder completes fetching HTML and resolving DNS, it creates new PENDING children without checking if the crawl was cancelled in the meantime. These new children get picked up by other feeders, perpetuating the crawl.

Fix: Check cancellation before creating children in feeding(), or have batch_create_children skip creation if the crawl is cancelled.

3. is_cancelled check is a one-shot (line 269)

The cancellation check at the top of feeding() only runs once. If cancel fires after this check but before update_job_status, the feeder won't notice.

Expected Behavior

After cancel, the crawl should stop within seconds. No new children should be created, and no CANCELLED statuses should be overwritten.

Affected Files

  • feeder/src/job.rsupdate_job_status, batch_create_children, feeding

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions