➕ update: add prototype for `tail -f` based on polling
parent
e79925dc14
commit
137e8e1bf8
|
@ -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"
|
||||
|
|
|
@ -23,4 +23,7 @@ ptth_server = { path = "crates/ptth_server" }
|
|||
|
||||
[workspace]
|
||||
|
||||
members = ["crates/*"]
|
||||
members = [
|
||||
"crates/*",
|
||||
"tools/*",
|
||||
]
|
||||
|
|
|
@ -270,9 +270,7 @@ pub async fn run_server (
|
|||
}
|
||||
continue;
|
||||
},
|
||||
Ok (r) => {
|
||||
r
|
||||
},
|
||||
Ok (x) => x,
|
||||
};
|
||||
|
||||
if req_resp.status () == StatusCode::NO_CONTENT {
|
||||
|
|
|
@ -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"]
|
|
@ -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 (())
|
||||
}
|
Loading…
Reference in New Issue