quinjet 0.0.52

A fast, live, keyboard-first Git source-control interface for the terminal
#[cfg_attr(not(test), expect(clippy::wildcard_imports, reason = "shared"))]
use super::*;

pub(crate) struct GitWorker {
    mailbox: Arc<SharedMailbox>,
    github_mailbox: Arc<SharedMailbox>,
    conversation_mailbox: Arc<SharedMailbox>,
    review_mailbox: Arc<SharedMailbox>,
    local_preview_mailbox: Arc<SharedMailbox>,
    pull_request_preview_mailbox: Arc<SharedMailbox>,
    warm_mailbox: Arc<SharedMailbox>,
    warm_generation: Arc<AtomicU64>,
    events: Receiver<WorkerEvent>,
}

impl GitWorker {
    #[expect(
        clippy::expect_used,
        reason = "the interface cannot run without its worker threads"
    )]
    pub(crate) fn start(repository: Repository) -> Self {
        let mailbox = new_mailbox();
        let github_mailbox = new_mailbox();
        let conversation_mailbox = new_mailbox();
        let review_mailbox = new_mailbox();
        let local_preview_mailbox = new_mailbox();
        let pull_request_preview_mailbox = new_mailbox();
        let warm_mailbox = new_mailbox();
        let warm_generation = Arc::new(AtomicU64::new(0));
        let worker_warm_generation = Arc::clone(&warm_generation);
        let worker_mailbox = Arc::clone(&mailbox);
        let worker_github_mailbox = Arc::clone(&github_mailbox);
        let worker_conversation_mailbox = Arc::clone(&conversation_mailbox);
        let worker_review_mailbox = Arc::clone(&review_mailbox);
        let worker_local_preview_mailbox = Arc::clone(&local_preview_mailbox);
        let worker_pull_request_preview_mailbox = Arc::clone(&pull_request_preview_mailbox);
        let worker_warm_mailbox = Arc::clone(&warm_mailbox);
        let github_repository = repository.clone_for_worker();
        let conversation_repository = repository.clone_for_worker();
        let review_repository = repository.clone_for_worker();
        let local_preview_repository = repository.clone_for_worker();
        let pull_request_preview_repository = repository.clone_for_worker();
        let warm_repository = repository.clone_for_worker();
        let (event_tx, event_rx) = unbounded();
        let github_events = event_tx.clone();
        let conversation_events = event_tx.clone();
        let review_events = event_tx.clone();
        let local_preview_events = event_tx.clone();
        let pull_request_preview_events = event_tx.clone();
        let warm_events = event_tx.clone();
        drop(
            thread::Builder::new()
                .name("quinjet-git".to_owned())
                .spawn(move || run_worker(&repository, &worker_mailbox, &event_tx))
                .expect("failed to start Git worker"),
        );
        drop(
            thread::Builder::new()
                .name("quinjet-github".to_owned())
                .spawn(move || {
                    run_worker(&github_repository, &worker_github_mailbox, &github_events);
                })
                .expect("failed to start GitHub metadata worker"),
        );
        drop(
            thread::Builder::new()
                .name("quinjet-conversation".to_owned())
                .spawn(move || {
                    run_worker(
                        &conversation_repository,
                        &worker_conversation_mailbox,
                        &conversation_events,
                    );
                })
                .expect("failed to start conversation worker"),
        );
        drop(
            thread::Builder::new()
                .name("quinjet-review".to_owned())
                .spawn(move || {
                    run_worker(&review_repository, &worker_review_mailbox, &review_events);
                })
                .expect("failed to start review worker"),
        );
        drop(
            thread::Builder::new()
                .name("quinjet-preview".to_owned())
                .spawn(move || {
                    run_worker(
                        &local_preview_repository,
                        &worker_local_preview_mailbox,
                        &local_preview_events,
                    );
                })
                .expect("failed to start local preview worker"),
        );
        drop(
            thread::Builder::new()
                .name("quinjet-pr-preview".to_owned())
                .spawn(move || {
                    run_worker(
                        &pull_request_preview_repository,
                        &worker_pull_request_preview_mailbox,
                        &pull_request_preview_events,
                    );
                })
                .expect("failed to start pull-request preview worker"),
        );
        drop(
            thread::Builder::new()
                .name("quinjet-warm".to_owned())
                .spawn(move || {
                    run_warm_worker(
                        &warm_repository,
                        &worker_warm_mailbox,
                        &warm_events,
                        &worker_warm_generation,
                    );
                })
                .expect("failed to start log warm-up worker"),
        );
        Self {
            mailbox,
            github_mailbox,
            conversation_mailbox,
            review_mailbox,
            local_preview_mailbox,
            pull_request_preview_mailbox,
            warm_mailbox,
            warm_generation,
            events: event_rx,
        }
    }

    #[doc = " Queue work without blocking the render thread. Read requests occupy fixed"]
    #[doc = " mailbox slots and replace obsolete requests; repository mutations remain an"]
    #[doc = " ordered queue and are additionally serialized by the app's busy state."]
    pub(crate) fn send(&self, mut command: WorkerCommand) -> bool {
        if let WorkerCommand::PrefetchCheckRunLogs { generation, .. } = &mut command {
            *generation = self.warm_generation.fetch_add(1, Ordering::SeqCst) + 1;
        }
        let target = match worker_lane(&command) {
            WorkerLane::GitHubMetadata => &self.github_mailbox,
            WorkerLane::Conversation => &self.conversation_mailbox,
            WorkerLane::Review => &self.review_mailbox,
            WorkerLane::LocalPreview => &self.local_preview_mailbox,
            WorkerLane::PullRequestPreview => &self.pull_request_preview_mailbox,
            WorkerLane::Warm => &self.warm_mailbox,
            WorkerLane::Background => &self.mailbox,
        };
        let Ok(mut mailbox) = target.state.lock() else {
            return false;
        };
        if mailbox.shutdown {
            return false;
        }
        mailbox.push(command);
        drop(mailbox);
        target.ready.notify_one();
        true
    }

    pub(crate) const fn events(&self) -> &Receiver<WorkerEvent> {
        &self.events
    }
}

impl Drop for GitWorker {
    fn drop(&mut self) {
        shutdown_mailbox(&self.mailbox);
        shutdown_mailbox(&self.github_mailbox);
        shutdown_mailbox(&self.conversation_mailbox);
        shutdown_mailbox(&self.review_mailbox);
        shutdown_mailbox(&self.local_preview_mailbox);
        shutdown_mailbox(&self.pull_request_preview_mailbox);
        shutdown_mailbox(&self.warm_mailbox);
    }
}