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()
}