fn replay()

in below/src/main.rs [760:831]


fn replay(
    logger: slog::Logger,
    errs: Receiver<Error>,
    time: String,
    below_config: &BelowConfig,
    host: Option<String>,
    port: Option<u16>,
    days_adjuster: Option<String>,
    snapshot: Option<String>,
) -> Result<()> {
    let timestamp =
        cliutil::system_time_from_date_and_adjuster(time.as_str(), days_adjuster.as_deref())?;

    let mut advance = match (host, snapshot) {
        (None, None) => {
            new_advance_local(logger.clone(), below_config.store_dir.clone(), timestamp)
        }
        (Some(host), None) => new_advance_remote(logger.clone(), host, port, timestamp)?,
        (None, Some(snapshot)) => {
            let mut tarball =
                Archive::new(fs::File::open(&snapshot).context("Failed to open snapshot file")?);
            let mut snapshot_dir = TempDir::new("snapshot_replay")?.into_path();
            tarball.unpack(&snapshot_dir)?;
            snapshot_dir.push(snapshot);
            new_advance_local(logger.clone(), snapshot_dir, timestamp)
        }
        (Some(_), Some(_)) => {
            bail!("--host and --snapshot are incompatible options")
        }
    };

    // Fill the last_sample for forward iteration. If no previous sample exists,
    // this should have no effect.
    advance.initialize();

    let model = match advance.jump_sample_to(timestamp) {
        Some(m) => m,
        None => bail!(
            "No initial sample could be found!\n\
            You may have provided a time in the future or no data was recorded during the provided time. \
            Please check your input and timezone.\n\
            If you are using remote, please make sure the below service on target host is running."
        ),
    };

    cliutil::check_initial_sample_time_with_requested_time(model.timestamp, timestamp);

    let mut view = view::View::new_with_advance(
        model,
        view::ViewMode::Replay(Rc::new(RefCell::new(advance))),
    );
    logutil::set_current_log_target(logutil::TargetLog::File);

    let sink = view.cb_sink().clone();
    thread::Builder::new()
        .name("replay_err_chan".to_owned())
        .spawn(move || {
            match errs.recv() {
                Ok(e) => {
                    error!(logger, "{:#}", e);
                }
                Err(_) => {
                    error!(logger, "error channel disconnected");
                }
            };
            sink.send(Box::new(|c| c.quit()))
                .expect("Failed to stop view");
        })
        .expect("Failed to spawn thread");

    view.run()
}