Solid Queue의 핵심 기능들은 데이터베이스 테이블과 전용 프로세스를 통해 구현됩니다.
작업 스케줄링
Solid Queue는 미래의 특정 시점에 실행되도록 지정된 작업을 solid_queue_scheduled_executions
테이블에 저장합니다. 이 테이블은 예약된 작업의 실행 시간을 나타내는 scheduled_at
컬럼을 포함하며, solid_queue_ready_executions
테이블과 유사한 구조를 가집니다. Dispatcher
라는 프로세스는 이 테이블을 지속적으로 폴링하여 scheduled_at
시간이 지난 작업들을 감지하고 실행을 위해 준비합니다. 작업이 디스패치되면 해당 ScheduledExecution
레코드는 삭제되고 ReadyExecution
레코드가 생성되어 일반 작업자 프로세스에 의해 처리됩니다. Dispatcher
프로세스는 Solid Queue 시작 시 자동으로 실행되며, Supervisor
에 의해 관리됩니다.
반복 작업
반복 작업은 Cron 작업과 유사하게 주기적으로 실행되어야 하는 백그라운드 작업을 의미합니다. Solid Queue에서는 config/recurring.yml
파일을 통해 반복 작업을 설정하며, Fugit 라이브러리를 사용하여 ‘매일 정오’와 같은 사람 친화적인 스케줄 표현식을 파싱합니다. 반복 작업은 solid_queue_recurring_tasks
테이블에 저장된 RecurringTask
모델로 표현됩니다. Scheduler
프로세스는 Solid Queue 시작 시 가동되어 solid_queue_recurring_tasks
테이블을 쿼리하고, Concurrent::ScheduledTask
를 활용하여 다음 실행 시간을 예약하고 해당 작업을 큐에 추가합니다. 스케줄링 스레드가 중단되더라도 Cron 스케줄은 정적이므로 작업 실행의 연속성이 보장됩니다. 또한, RecurringExecution
레코드를 생성하여 동일한 작업이 동일한 시간에 여러 번 실행되는 것을 방지합니다.
동시성 제어
Solid Queue는 limits_concurrency
기능을 통해 특정 유형의 작업이 동시에 실행될 수 있는 수를 제한할 수 있습니다. 이 기능은 Semaphore
및 BlockedExecution
모델과 해당 데이터베이스 테이블을 기반으로 합니다. 작업이 limits_concurrency
와 함께 큐에 추가될 때, Solid Queue는 먼저 동시성 키(작업 클래스, 키, 그룹 이름 기반)에 따라 세마포어 잠금을 획득하려고 시도합니다. 세마포어를 획득할 수 있으면 작업이 큐에 추가되고, 그렇지 않으면 BlockedExecution
레코드가 생성됩니다. Semaphore
는 카운팅 세마포어 패턴을 구현하며, 작업 완료 시 세마포어를 해제합니다. 세마포어는 만료 기간을 가지며, 이는 작업자 프로세스 충돌 등으로 인해 잠금이 영구적으로 유지되는 것을 방지합니다. Dispatcher
는 ConcurrencyMaintenance
클래스를 통해 만료된 세마포어를 제거하고 차단된 작업을 해제하여 동시성 제한을 유지합니다.
AppSignal을 통한 모니터링
Solid Queue의 다양한 기능과 복잡한 내부 동작을 고려할 때, 효과적인 모니터링은 필수적입니다. AppSignal은 Solid Queue에 대한 내장 지원을 제공하여, 작업 실행 시간, 처리량, 실패율 등 중요한 지표에 대한 사전 구성된 대시보드를 제공합니다. Rails 애플리케이션에 AppSignal을 설치하기만 하면 자동으로 Solid Queue 사용을 감지하고 관련 대시보드를 생성합니다. 또한, AppSignal Alerts를 통해 작업 오류율이나 실행 시간과 같은 지표에 대한 알림을 설정하여 문제를 조기에 감지하고 해결할 수 있습니다.