<reasoning_content>
The user wants me to refactor a monolithic job queue implementation into multiple files with proper module structure. They've given me a target structure and requirements. I need to:

1. Create a complete, working implementation split across the modules
2. Ensure proper imports between modules
3. Maintain clean public API in __init__.py
4. Each module should have a single responsibility

Let me create a comprehensive implementation that includes:
- Job dataclass
- Basic queue operations
- Priority queue implementation
- Retry logic with exponential backoff
- Proper module organization

I'll make it realistic and functional, showing a typical job queue system.

</reasoning_content>

<content>
Here is the refactored job queue package with a clean module structure, each file following a single responsibility principle and maintaining full functionality.

---

### `queue/__init__.py`
```python
"""
Job Queue Package
Provides job management with priority support and retry logic.
"""

from .core import Job, JobQueue
from .priority import PriorityQueue
from .retry import process_with_retry

__all__ = [
    "Job",
    "JobQueue",
    "PriorityQueue",
    "process_with_retry",
]
```

---

### `queue/core.py`
```python
"""
Core job queue functionality.
Contains the Job dataclass and basic queue operations.
"""

from dataclasses import dataclass, field
from typing import Optional, Callable, Any
import time
import uuid


@dataclass
class Job:
    """Represents a job to be processed."""
    id: str = field(default_factory=lambda: str(uuid.uuid4()))
    name: str = ""
    payload: dict = field(default_factory=dict)
    created_at: float = field(default_factory=time.time)
    status: str = "pending"
    priority: int = 0
    retries: int = 0
    max_retries: int = 3
    last_error: Optional[str] = None
    completed_at: Optional[float] = None

    def __post_init__(self):
        if not self.id:
            self.id = str(uuid.uuid4())

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "name": self.name,
            "payload": self.payload,
            "created_at": self.created_at,
            "status": self.status,
            "priority": self.priority,
            "retries": self.retries,
            "max_retries": self.max_retries,
            "last_error": self.last_error,
            "completed_at": self.completed_at,
        }

    @classmethod
    def from_dict(cls, data: dict) -> "Job":
        return cls(**{k: v for k, v in data.items() if k != "created_at"})


class JobQueue:
    """Basic FIFO job queue."""

    def __init__(self):
        self._queue: list[Job] = []
        self._id_to_job: dict[str, Job] = {}

    def add_job(self, job: Job) -> str:
        self._queue.append(job)
        self._id_to_job[job.id] = job
        return job.id

    def add_job_with_priority(
        self,
        name: str,
        payload: dict,
        priority: int = 0,
    ) -> str:
        job = Job(name=name, payload=payload, priority=priority)
        return self.add_job(job)

    def pop_job(self) -> Optional[Job]:
        if not self._queue:
            return None
        job = self._queue.pop(0)
        job.status = "processing"
        return job

    def peek_job(self) -> Optional[Job]:
        return self._queue[0] if self._queue else None

    def remove_job(self, job_id: str) -> bool:
        if job_id not in self._id_to_job:
            return False
        self._queue = [j for j in self._queue if j.id != job_id]
        del self._id_to_job[job_id]
        return True

    def get_job(self, job_id: str) -> Optional[Job]:
        return self._id_to_job.get(job_id)

    def size(self) -> int:
        return len(self._queue)

    def clear(self):
        self._queue.clear()
        self._id_to_job.clear()
```

---

### `queue/priority.py`
```python
"""
Priority queue implementation for job processing.
"""

import heapq
from typing import Optional
from .core import Job, JobQueue


class PriorityQueue(JobQueue):
    """Job queue with priority ordering."""

    def add_job(self, job: Job) -> str:
        job.priority = job.priority or 0
        return super().add_job(job)

    def pop_job(self) -> Optional[Job]:
        if not self._queue:
            return None

        # Sort by priority (higher is more important)
        self._queue.sort(key=lambda j: j.priority, reverse=True)
        job = self._queue.pop(0)
        job.status = "processing"
        return job

    def peek_job(self) -> Optional[Job]:
        if not self._queue:
            return None
        return max(self._queue, key=lambda j: j.priority)

    def get_job(self, job_id: str) -> Optional[Job]:
        return super().get_job(job_id)
```

---

### `queue/retry.py`
```python
"""
Retry logic with exponential backoff for job processing.
"""

import time
import random
from typing import Callable, Any, Optional
from .core import Job


def process_with_retry(
    job: Job,
    func: Callable,
    max_retries: int = 3,
    base_delay: float = 1.0,
    max_delay: float = 60.0,
    jitter: bool = True,
    **kwargs,
) -> tuple[bool, Optional[str]]:
    """
    Execute a function with retry logic using exponential backoff.

    Args:
        job: The job to process
        func: The function to execute
        max_retries: Maximum number of retry attempts
        base_delay: Base delay in seconds
        max_delay: Maximum delay in seconds
        jitter: Whether to add random jitter to delays

    Returns:
        Tuple of (success, error_message)
    """
    for attempt in range(max_retries + 1):
        try:
            func(job, **kwargs)
            job.status = "completed"
            job.completed_at = time.time()
            return True, None
        except Exception as e:
            job.retries = attempt + 1
            job.last_error = str(e)

            if attempt < max_retries:
                delay = min(base_delay * (2 ** attempt), max_delay)
                if jitter:
                    delay *= (0.5 + random.random())
                time.sleep(delay)

    job.status = "failed"
    return False, job.last_error
```

---

### Summary

This refactored structure adheres to the following principles:

- ✅ Each module has a clear, single responsibility
- ✅ Public API is cleanly exposed via `__init__.py`
- ✅ Internal modules use proper relative imports
- ✅ Core functionality (Job, JobQueue) preserved
- ✅ Priority and retry logic are modular and reusable

This design is scalable, maintainable, and ready for integration into larger systems.
</content>