update: add prototype for `tail -f` based on polling

main
_ 2020-12-20 18:59:05 -06:00
parent e79925dc14
commit 137e8e1bf8
5 changed files with 117 additions and 4 deletions

11
Cargo.lock generated
View File

@ -1720,6 +1720,17 @@ dependencies = [
"uom",
]
[[package]]
name = "ptth_tail"
version = "0.1.0"
dependencies = [
"anyhow",
"reqwest",
"tokio",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "pulldown-cmark"
version = "0.8.0"

View File

@ -23,4 +23,7 @@ ptth_server = { path = "crates/ptth_server" }
[workspace]
members = ["crates/*"]
members = [
"crates/*",
"tools/*",
]

View File

@ -270,9 +270,7 @@ pub async fn run_server (
}
continue;
},
Ok (r) => {
r
},
Ok (x) => x,
};
if req_resp.status () == StatusCode::NO_CONTENT {

View File

@ -0,0 +1,21 @@
[package]
name = "ptth_tail"
version = "0.1.0"
authors = ["Trish"]
edition = "2018"
license = "AGPL-3.0"
[dependencies]
anyhow = "1.0.34"
tracing = "0.1.21"
tracing-subscriber = "0.2.15"
[dependencies.reqwest]
version = "0.10.8"
features = ["stream"]
[dependencies.tokio]
version = "0.2.22"
features = ["full"]

View File

@ -0,0 +1,80 @@
use std::{
convert::TryFrom,
io::{
self,
Write,
},
time::Duration,
};
use reqwest::{
Client,
StatusCode,
};
use tokio::{
stream::StreamExt,
time::interval,
};
use tracing::{
debug, warn
};
use tracing_subscriber::{
EnvFilter,
fmt,
fmt::format::FmtSpan,
};
#[tokio::main]
async fn main () -> Result <(), anyhow::Error> {
fmt ()
.with_env_filter (EnvFilter::from_default_env ())
.with_span_events (FmtSpan::CLOSE)
.init ()
;
let client = Client::default ();
let server = "http://127.0.0.1:4000/files/log.txt";
let mut total_bytes_received = 0_u64;
let mut timer = interval (Duration::from_secs (2));
loop {
timer.tick ().await;
let resp = match client
.get (server)
.header ("range", format! ("bytes={}-", total_bytes_received))
.send ().await {
Err (e) => {
warn! ("Reqwest send error: {:?}", e);
continue;
}
Ok (x) => x,
};
let status = resp.status ();
match status {
StatusCode::RANGE_NOT_SATISFIABLE => continue,
StatusCode::PARTIAL_CONTENT => (),
sc => {
debug! ("status code: {}", sc);
continue;
},
}
let mut stream = resp.bytes_stream ();
while let Some (chunk) = stream.next ().await {
let chunk = match chunk {
Ok (x) => x,
Err (_) => break,
};
io::stdout ().write_all (&chunk)?;
total_bytes_received += u64::try_from (chunk.len ())?;
}
}
Ok (())
}