From aea1daa0fba0d4229e66ce621cbd097efce27013 Mon Sep 17 00:00:00 2001 From: "Michael S. Huang" Date: Wed, 29 Dec 2021 21:44:36 +0800 Subject: [PATCH 1/3] unit test works; but rate limit impl not working well yet --- Cargo.toml | 6 ++ src/cmd/fetch.rs | 37 +++++++++- tests/test_fetch.rs | 163 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 205 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 2cb2456c6..0c6536c3c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,9 +72,15 @@ vader_sentiment = { version = "0.1.1", optional = true } whatlang = { version = "0.12.0", optional = true } reqwest = { version = "0.11", features = ["blocking", "json", "rustls-tls"], default-features = false } jql = { version = "3.0.6", default-features = false } +governor = "0.4" +nonzero_ext = "0.3" [dev-dependencies] quickcheck = { version = "1", default-features = false } +tokio = { version = "1", features = ["rt", "time", "macros"] } +lazy_static = "=1.4.0" +actix-web = "3.3" +actix-governor = "0.2" [features] default = ["mimalloc"] diff --git a/src/cmd/fetch.rs b/src/cmd/fetch.rs index 77172a575..cb12ebb2c 100644 --- a/src/cmd/fetch.rs +++ b/src/cmd/fetch.rs @@ -120,6 +120,14 @@ pub fn run(argv: &[&str]) -> CliResult<()> { .build() .unwrap(); + use governor::{ + RateLimiter, + Quota + }; + + use nonzero_ext::nonzero; + let limiter = RateLimiter::direct(Quota::per_second(nonzero!(3u32))); + let mut include_existing_columns = false; if let Some(name) = &args.flag_new_column { @@ -152,7 +160,7 @@ pub fn run(argv: &[&str]) -> CliResult<()> { let url = String::from_utf8_lossy(&selected_col_value).to_string(); debug!("Fetching URL: {:?}", &url); - let final_value = get_cached_response(&url, &client, &args.flag_jql); + let final_value = get_cached_response(&url, &client, &limiter, &args.flag_jql); if include_existing_columns { record.push_field(final_value.as_bytes()); @@ -185,6 +193,18 @@ pub fn run(argv: &[&str]) -> CliResult<()> { Ok(()) } +use governor::{ + state::direct::NotKeyed, + state::InMemoryState, + clock::DefaultClock, + middleware::NoOpMiddleware +}; + +use std::{ + thread, + time, +}; + #[cached( key = "String", convert = r#"{ format!("{}", url) }"#, @@ -193,8 +213,23 @@ pub fn run(argv: &[&str]) -> CliResult<()> { fn get_cached_response( url: &str, client: &reqwest::blocking::Client, + limiter: &governor::RateLimiter, flag_jql: &Option, ) -> String { + + loop { + match limiter.check() { + Ok(()) => { + debug!("going ahead"); + break; + }, + _ => { + debug!("sleeping for 10 ms"); + thread::sleep(time::Duration::from_millis(10)); + } + } + }; + let resp = client.get(url).send().unwrap(); debug!("response: {:?}", &resp); let api_value = resp.text().unwrap(); diff --git a/tests/test_fetch.rs b/tests/test_fetch.rs index b53915807..f7700b9b5 100644 --- a/tests/test_fetch.rs +++ b/tests/test_fetch.rs @@ -1,3 +1,4 @@ + use crate::workdir::Workdir; #[test] @@ -76,3 +77,165 @@ fn fetch_jql() { ]; assert_eq!(got, expected); } + +use std::{ + thread, + sync::mpsc +}; + +use actix_web::{ + dev::Server, + middleware, + rt, + web, + App, + HttpRequest, + HttpServer, + Responder, + Result, +}; + +use serde::Serialize; +#[derive(Serialize)] +struct MyObj { + fullname: String, +} + +async fn index() -> impl Responder { + "Hello world!" +} + +/// handler with path parameters like `/user/{name}/` +/// returns Smurf fullname +async fn get_fullname( + req: HttpRequest, + web::Path((name,)): web::Path<(String,)>, +) -> Result { + println!("{:?}", req); + + let obj = MyObj { + fullname: format!("{} Smurf", name), + }; + + Ok(web::Json(obj)) + +} + +/// start an Actix Webserver with Rate Limiting via Governor +fn run_webserver(tx: mpsc::Sender) -> std::io::Result<()> { + let mut sys = rt::System::new("test"); + + use actix_governor::{ + Governor, + GovernorConfigBuilder, + GovernorConfig + }; + + // Allow bursts with up to five requests per IP address + // and replenishes one element every two seconds + let governor_conf:GovernorConfig = GovernorConfigBuilder::default() + .per_second(2) + .burst_size(5) + .finish() + .unwrap(); + + // srv is server controller type, `dev::Server` + let srv = HttpServer::new(move || { + App::new() + // enable logger + .wrap(middleware::Logger::default()) + .wrap(Governor::new(&governor_conf)) + .service(web::resource("/user/{name}").route(web::get().to(get_fullname))) + .service(web::resource("/").to(index)) + }) + .bind("127.0.0.1:8080")? + .run(); + + // send server controller to main thread + let _ = tx.send(srv.clone()); + + // run future + sys.block_on(srv) +} + +#[test] +fn fetch_ratelimit() { + + // start webserver with rate limiting + let (tx, rx) = mpsc::channel(); + + println!("START Webserver "); + thread::spawn(move || { + let _ = run_webserver(tx); + }); + + let srv = rx.recv().unwrap(); + + // proceed with usual unit test + let wrk = Workdir::new("fetch"); + wrk.create( + "data.csv", + vec![ + svec!["URL"], + svec!["http://localhost:8080/user/Smurfette"], + svec!["http://localhost:8080/user/Papa"], + svec!["http://localhost:8080/user/Clumsy"], + svec!["http://localhost:8080/user/Brainy"], + svec!["http://localhost:8080/user/Grouchy"], + svec!["http://localhost:8080/user/Hefty"], + svec!["http://localhost:8080/user/Greedy"], + svec!["http://localhost:8080/user/Jokey"], + svec!["http://localhost:8080/user/Chef"], + svec!["http://localhost:8080/user/Vanity"], + svec!["http://localhost:8080/user/Handy"], + svec!["http://localhost:8080/user/Scaredy"], + svec!["http://localhost:8080/user/Tracker"], + svec!["http://localhost:8080/user/Sloppy"], + svec!["http://localhost:8080/user/Harmony"], + svec!["http://localhost:8080/user/Painter"], + svec!["http://localhost:8080/user/Poet"], + svec!["http://localhost:8080/user/Farmer"], + svec!["http://localhost:8080/user/Natural"], + svec!["http://localhost:8080/user/Snappy"], + ], + ); + let mut cmd = wrk.command("fetch"); + cmd.arg("URL") + .arg("--new-column") + .arg("Fullname") + .arg("--jql") + .arg(r#"."fullname""#) + .arg("data.csv"); + + let got: Vec> = wrk.read_stdout(&mut cmd); + let expected = vec![ + svec!["URL", "Fullname"], + svec!["http://localhost:8080/user/Smurfette", "Smurfette Smurf"], + svec!["http://localhost:8080/user/Papa", "Papa Smurf"], + svec!["http://localhost:8080/user/Clumsy", "Clumsy Smurf"], + svec!["http://localhost:8080/user/Brainy", "Brainy Smurf"], + svec!["http://localhost:8080/user/Grouchy", "Grouchy Smurf"], + svec!["http://localhost:8080/user/Hefty", "Hefty Smurf"], + svec!["http://localhost:8080/user/Greedy", "Greedy Smurf"], + svec!["http://localhost:8080/user/Jokey", "Jokey Smurf"], + svec!["http://localhost:8080/user/Chef", "Chef Smurf"], + svec!["http://localhost:8080/user/Vanity", "Vanity Smurf"], + svec!["http://localhost:8080/user/Handy", "Handy Smurf"], + svec!["http://localhost:8080/user/Scaredy", "Scaredy Smurf"], + svec!["http://localhost:8080/user/Tracker", "Tracker Smurf"], + svec!["http://localhost:8080/user/Sloppy", "Sloppy Smurf"], + svec!["http://localhost:8080/user/Harmony", "Harmony Smurf"], + svec!["http://localhost:8080/user/Painter", "Painter Smurf"], + svec!["http://localhost:8080/user/Poet", "Poet Smurf"], + svec!["http://localhost:8080/user/Farmer", "Farmer Smurf"], + svec!["http://localhost:8080/user/Natural", "Natural Smurf"], + svec!["http://localhost:8080/user/Snappy", "Snappy Smurf"], + ]; + assert_eq!(got, expected); + + // init stop webserver and wait until server gracefully exit + println!("STOPPING Webserver"); + rt::System::new("").block_on(srv.stop(true)); + +} + From 4530e47a50f9496a59a95e34b277cd306ff8dbfc Mon Sep 17 00:00:00 2001 From: "Michael S. Huang" Date: Thu, 30 Dec 2021 22:20:40 +0800 Subject: [PATCH 2/3] set rate limit from command line arg; integration test passes --- Cargo.lock | 1403 +++++++++++++++++++++++++++++++++++++++---- Cargo.toml | 3 - src/cmd/fetch.rs | 28 +- tests/test_fetch.rs | 9 +- 4 files changed, 1328 insertions(+), 115 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bb7586e46..7441c0f1a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,279 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "actix-codec" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78d1833b3838dbe990df0f1f87baf640cf6146e898166afe401839d1b001e570" +dependencies = [ + "bitflags", + "bytes 0.5.6", + "futures-core", + "futures-sink", + "log", + "pin-project 0.4.28", + "tokio 0.2.25", + "tokio-util 0.3.1", +] + +[[package]] +name = "actix-connect" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177837a10863f15ba8d3ae3ec12fac1099099529ed20083a27fdfe247381d0dc" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "derive_more", + "either", + "futures-util", + "http", + "log", + "trust-dns-proto", + "trust-dns-resolver", +] + +[[package]] +name = "actix-governor" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d457f3a38bd653eb59b1683bcde01a07e85ea403285f3611a54b250e57d78d9a" +dependencies = [ + "actix-web", + "futures", + "governor 0.3.2", + "log", +] + +[[package]] +name = "actix-http" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cb8958da437716f3f31b0e76f8daf36554128517d7df37ceba7df00f09622ee" +dependencies = [ + "actix-codec", + "actix-connect", + "actix-rt", + "actix-service", + "actix-threadpool", + "actix-utils", + "base64", + "bitflags", + "brotli2", + "bytes 0.5.6", + "cookie", + "copyless", + "derive_more", + "either", + "encoding_rs", + "flate2", + "futures-channel", + "futures-core", + "futures-util", + "fxhash", + "h2 0.2.7", + "http", + "httparse", + "indexmap", + "itoa 0.4.8", + "language-tags", + "lazy_static", + "log", + "mime", + "percent-encoding", + "pin-project 1.0.8", + "rand 0.7.3", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "sha-1 0.9.8", + "slab", + "time 0.2.27", +] + +[[package]] +name = "actix-macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ca8ce00b267af8ccebbd647de0d61e0674b6e61185cc7a592ff88772bed655" +dependencies = [ + "quote", + "syn", +] + +[[package]] +name = "actix-router" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ad299af73649e1fc893e333ccf86f377751eb95ff875d095131574c6f43452c" +dependencies = [ + "bytestring", + "http", + "log", + "regex", + "serde", +] + +[[package]] +name = "actix-rt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "143fcc2912e0d1de2bcf4e2f720d2a60c28652ab4179685a1ee159e0fb3db227" +dependencies = [ + "actix-macros", + "actix-threadpool", + "copyless", + "futures-channel", + "futures-util", + "smallvec", + "tokio 0.2.25", +] + +[[package]] +name = "actix-server" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45407e6e672ca24784baa667c5d32ef109ccdd8d5e0b5ebb9ef8a67f4dfb708e" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "futures-channel", + "futures-util", + "log", + "mio 0.6.23", + "mio-uds", + "num_cpus", + "slab", + "socket2 0.3.19", +] + +[[package]] +name = "actix-service" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0052435d581b5be835d11f4eb3bce417c8af18d87ddf8ace99f8e67e595882bb" +dependencies = [ + "futures-util", + "pin-project 0.4.28", +] + +[[package]] +name = "actix-testing" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47239ca38799ab74ee6a8a94d1ce857014b2ac36f242f70f3f75a66f691e791c" +dependencies = [ + "actix-macros", + "actix-rt", + "actix-server", + "actix-service", + "log", + "socket2 0.3.19", +] + +[[package]] +name = "actix-threadpool" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d209f04d002854b9afd3743032a27b066158817965bf5d036824d19ac2cc0e30" +dependencies = [ + "derive_more", + "futures-channel", + "lazy_static", + "log", + "num_cpus", + "parking_lot", + "threadpool", +] + +[[package]] +name = "actix-tls" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24789b7d7361cf5503a504ebe1c10806896f61e96eca9a7350e23001aca715fb" +dependencies = [ + "actix-codec", + "actix-service", + "actix-utils", + "futures-util", +] + +[[package]] +name = "actix-utils" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9022dec56632d1d7979e59af14f0597a28a830a9c1c7fec8b2327eb9f16b5a" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "bitflags", + "bytes 0.5.6", + "either", + "futures-channel", + "futures-sink", + "futures-util", + "log", + "pin-project 0.4.28", + "slab", +] + +[[package]] +name = "actix-web" +version = "3.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6534a126df581caf443ba2751cab42092c89b3f1d06a9d829b1e17edfe3e277" +dependencies = [ + "actix-codec", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-testing", + "actix-threadpool", + "actix-tls", + "actix-utils", + "actix-web-codegen", + "awc", + "bytes 0.5.6", + "derive_more", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "fxhash", + "log", + "mime", + "pin-project 1.0.8", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "socket2 0.3.19", + "time 0.2.27", + "tinyvec", + "url", +] + +[[package]] +name = "actix-web-codegen" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad26f77093333e0e7c6ffe54ebe3582d908a104e448723eec6d43d08b07143fb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "adler" version = "1.0.2" @@ -29,7 +302,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -103,9 +376,9 @@ dependencies = [ "parking", "polling", "slab", - "socket2", + "socket2 0.4.2", "waker-fn", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -140,7 +413,7 @@ dependencies = [ "libc", "once_cell", "signal-hook", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -176,7 +449,7 @@ dependencies = [ "memchr", "num_cpus", "once_cell", - "pin-project-lite", + "pin-project-lite 0.2.7", "pin-utils", "slab", "wasm-bindgen-futures", @@ -188,6 +461,17 @@ version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e91831deabf0d6d7ec49552e489aed63b7456a7a3c46cff62adad428110b0af0" +[[package]] +name = "async-trait" +version = "0.1.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "061a7acccaa286c011ddc30970520b98fa40e00c9d644633fb26b5fc63a265e3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "atomic-waker" version = "1.0.0" @@ -202,7 +486,7 @@ checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ "hermit-abi", "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -211,6 +495,36 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "awc" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b381e490e7b0cfc37ebc54079b0413d8093ef43d14a4e4747083f7fa47a9e691" +dependencies = [ + "actix-codec", + "actix-http", + "actix-rt", + "actix-service", + "base64", + "bytes 0.5.6", + "cfg-if 1.0.0", + "derive_more", + "futures-core", + "log", + "mime", + "percent-encoding", + "rand 0.7.3", + "serde", + "serde_json", + "serde_urlencoded", +] + +[[package]] +name = "base-x" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" + [[package]] name = "base64" version = "0.13.0" @@ -232,7 +546,16 @@ dependencies = [ "block-padding", "byte-tools", "byteorder", - "generic-array", + "generic-array 0.12.4", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.4", ] [[package]] @@ -258,6 +581,26 @@ dependencies = [ "once_cell", ] +[[package]] +name = "brotli-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "brotli2" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" +dependencies = [ + "brotli-sys", + "libc", +] + [[package]] name = "bstr" version = "0.2.17" @@ -288,12 +631,27 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" + [[package]] name = "bytes" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +[[package]] +name = "bytestring" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90706ba19e97b90786e19dc0d5e2abd80008d99d4c0c5d1ad0b5e72cec7c494d" +dependencies = [ + "bytes 1.1.0", +] + [[package]] name = "cache-padded" version = "1.1.1" @@ -369,7 +727,7 @@ dependencies = [ "num-integer", "num-traits", "time 0.1.43", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -391,7 +749,45 @@ dependencies = [ "libc", "once_cell", "terminal_size", - "winapi", + "winapi 0.3.9", +] + +[[package]] +name = "const_fn" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cookie" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951" +dependencies = [ + "percent-encoding", + "time 0.2.27", + "version_check", +] + +[[package]] +name = "copyless" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" + +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", ] [[package]] @@ -606,25 +1002,74 @@ dependencies = [ ] [[package]] -name = "dateparser" -version = "0.1.6" +name = "dashmap" +version = "4.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dcee48ba66b79ba92dab399f218228f98c5d601ca85127fbc1ad60caf237d8" +checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" dependencies = [ - "anyhow", - "chrono", - "lazy_static", - "regex", + "cfg-if 1.0.0", + "num_cpus", ] [[package]] -name = "digest" -version = "0.8.1" +name = "dashmap" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +checksum = "b799062aaf67eb976af3bdca031ee6f846d2f0a5710ddbb0d2efee33f3cc4760" dependencies = [ - "generic-array", -] + "cfg-if 1.0.0", + "num_cpus", + "parking_lot", +] + +[[package]] +name = "dateparser" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dcee48ba66b79ba92dab399f218228f98c5d601ca85127fbc1ad60caf237d8" +dependencies = [ + "anyhow", + "chrono", + "lazy_static", + "regex", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.4", +] + +[[package]] +name = "discard" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" [[package]] name = "docopt" @@ -659,6 +1104,18 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "enum-as-inner" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c5f0096a91d210159eceb2ff5e1c4da18388a170e1e3ce948aac9c8fdbbf595" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "eudex" version = "0.1.1" @@ -695,7 +1152,7 @@ dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -750,26 +1207,69 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" +[[package]] +name = "fuchsia-zircon" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" +dependencies = [ + "bitflags", + "fuchsia-zircon-sys", +] + +[[package]] +name = "fuchsia-zircon-sys" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" + +[[package]] +name = "futures" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28560757fe2bb34e79f907794bb6b22ae8b0e5c669b638a1132f2592b19035b4" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +checksum = "ba3dda0b6588335f360afc675d0564c17a77a2bda81ca178a4b6081bd86c7f0b" dependencies = [ "futures-core", + "futures-sink", ] [[package]] name = "futures-core" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" +checksum = "d0c8ff0461b82559810cdccfde3215c3f373807f5e5232b71479bff7bb2583d7" + +[[package]] +name = "futures-executor" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29d6d2ff5bb10fb95c85b8ce46538a2e5f5e7fdc755623a7d4529ab8a4ed9d2a" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] [[package]] name = "futures-io" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" +checksum = "b1f9d34af5a1aac6fb380f735fe510746c38067c5bf16c7fd250280503c971b2" [[package]] name = "futures-lite" @@ -782,38 +1282,66 @@ dependencies = [ "futures-io", "memchr", "parking", - "pin-project-lite", + "pin-project-lite 0.2.7", "waker-fn", ] +[[package]] +name = "futures-macro" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbd947adfffb0efc70599b3ddcf7b5597bb5fa9e245eb99f62b3a5f7bb8bd3c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" +checksum = "e3055baccb68d74ff6480350f8d6eb8fcfa3aa11bdc1a1ae3afdd0514617d508" [[package]] name = "futures-task" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" +checksum = "6ee7c6485c30167ce4dfb83ac568a849fe53274c831081476ee13e0dce1aad72" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" [[package]] name = "futures-util" -version = "0.3.17" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +checksum = "d9b5cf40b47a271f77a8b1bec03ca09044d99d2372c0de244e66430761127164" dependencies = [ - "autocfg", + "futures-channel", "futures-core", "futures-io", + "futures-macro", + "futures-sink", "futures-task", "memchr", - "pin-project-lite", + "pin-project-lite 0.2.7", "pin-utils", "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "generic-array" version = "0.12.4" @@ -823,6 +1351,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -864,13 +1402,67 @@ dependencies = [ "web-sys", ] +[[package]] +name = "governor" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06c5d2f987ee8f6dff3fa1a352058dc59b990e447e4c7846aa7d804971314f7b" +dependencies = [ + "dashmap 4.0.2", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext 0.2.0", + "parking_lot", + "quanta 0.4.1", + "rand 0.8.4", + "smallvec", +] + +[[package]] +name = "governor" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3de427a64787873c3b196285e6684cddbf0ae7d1d8d56eaafbb4120c4cb641" +dependencies = [ + "dashmap 5.0.0", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext 0.3.0", + "parking_lot", + "quanta 0.9.3", + "rand 0.8.4", + "smallvec", +] + +[[package]] +name = "h2" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e4728fd124914ad25e99e3d15a9361a879f6620f63cb56bbb08f95abb97a535" +dependencies = [ + "bytes 0.5.6", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio 0.2.25", + "tokio-util 0.3.1", + "tracing", + "tracing-futures", +] + [[package]] name = "h2" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f072413d126e57991455e0a922b31e4c8ba7c2ffbebf6b78b4f8521397d65cd" dependencies = [ - "bytes", + "bytes 1.1.0", "fnv", "futures-core", "futures-sink", @@ -878,8 +1470,8 @@ dependencies = [ "http", "indexmap", "slab", - "tokio", - "tokio-util", + "tokio 1.15.0", + "tokio-util 0.6.9", "tracing", ] @@ -893,12 +1485,31 @@ dependencies = [ "autocfg", ] +[[package]] +name = "hashbrown" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b62f79061a0bc2e046024cb7ba44b08419ed238ecbd9adbd787434b9e8c25" +dependencies = [ + "ahash", + "autocfg", +] + [[package]] name = "hashbrown" version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "hermit-abi" version = "0.1.19" @@ -918,13 +1529,24 @@ dependencies = [ "lua52-sys", ] +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi 0.3.9", +] + [[package]] name = "http" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" dependencies = [ - "bytes", + "bytes 1.1.0", "fnv", "itoa 0.4.8", ] @@ -935,9 +1557,9 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" dependencies = [ - "bytes", + "bytes 1.1.0", "http", - "pin-project-lite", + "pin-project-lite 0.2.7", ] [[package]] @@ -958,19 +1580,19 @@ version = "0.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55" dependencies = [ - "bytes", + "bytes 1.1.0", "futures-channel", "futures-core", "futures-util", - "h2", + "h2 0.3.9", "http", "http-body", "httparse", "httpdate", "itoa 0.4.8", - "pin-project-lite", - "socket2", - "tokio", + "pin-project-lite 0.2.7", + "socket2 0.4.2", + "tokio 1.15.0", "tower-service", "tracing", "want", @@ -985,7 +1607,7 @@ dependencies = [ "http", "hyper", "rustls", - "tokio", + "tokio 1.15.0", "tokio-rustls", ] @@ -1038,6 +1660,27 @@ dependencies = [ "cfg-if 1.0.0", ] +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "ipconfig" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" +dependencies = [ + "socket2 0.3.19", + "widestring", + "winapi 0.3.9", + "winreg 0.6.2", +] + [[package]] name = "ipnet" version = "2.3.1" @@ -1097,6 +1740,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "kernel32-sys" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" +dependencies = [ + "winapi 0.2.8", + "winapi-build", +] + [[package]] name = "kv-log-macro" version = "1.0.7" @@ -1106,6 +1759,12 @@ dependencies = [ "log", ] +[[package]] +name = "language-tags" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" + [[package]] name = "lazy_static" version = "1.4.0" @@ -1139,6 +1798,15 @@ version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +[[package]] +name = "lock_api" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +dependencies = [ + "scopeguard", +] + [[package]] name = "log" version = "0.4.14" @@ -1149,6 +1817,15 @@ dependencies = [ "value-bag", ] +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + [[package]] name = "lua52-sys" version = "0.1.2" @@ -1160,12 +1837,27 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "mach" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b823e83b2affd8f40a9ee8c29dbc56404c1e34cd2710921f2801e2cf29527afa" +dependencies = [ + "libc", +] + [[package]] name = "maplit" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + [[package]] name = "matches" version = "0.1.9" @@ -1227,6 +1919,25 @@ dependencies = [ "autocfg", ] +[[package]] +name = "mio" +version = "0.6.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" +dependencies = [ + "cfg-if 0.1.10", + "fuchsia-zircon", + "fuchsia-zircon-sys", + "iovec", + "kernel32-sys", + "libc", + "log", + "miow 0.2.2", + "net2", + "slab", + "winapi 0.2.8", +] + [[package]] name = "mio" version = "0.7.14" @@ -1235,9 +1946,32 @@ checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" dependencies = [ "libc", "log", - "miow", + "miow 0.3.7", "ntapi", - "winapi", + "winapi 0.3.9", +] + +[[package]] +name = "mio-uds" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0" +dependencies = [ + "iovec", + "libc", + "mio 0.6.23", +] + +[[package]] +name = "miow" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" +dependencies = [ + "kernel32-sys", + "net2", + "winapi 0.2.8", + "ws2_32-sys", ] [[package]] @@ -1246,16 +1980,48 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" dependencies = [ - "winapi", + "winapi 0.3.9", +] + +[[package]] +name = "net2" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae" +dependencies = [ + "cfg-if 0.1.10", + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" +dependencies = [ + "hashbrown 0.8.2", ] +[[package]] +name = "nonzero_ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44a1290799eababa63ea60af0cbc3f03363e328e58f32fb0294798ed3e85f444" + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + [[package]] name = "ntapi" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1364,12 +2130,43 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + [[package]] name = "parking" version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi 0.3.9", +] + [[package]] name = "percent-encoding" version = "2.1.0" @@ -1377,48 +2174,94 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] -name = "pest" -version = "2.1.3" +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pest_meta" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +dependencies = [ + "maplit", + "pest", + "sha-1 0.8.2", +] + +[[package]] +name = "pin-project" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +checksum = "918192b5c59119d51e0cd221f4d49dde9112824ba717369e903c97d076083d0f" dependencies = [ - "ucd-trie", + "pin-project-internal 0.4.28", ] [[package]] -name = "pest_derive" -version = "2.1.0" +name = "pin-project" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833d1ae558dc601e9a60366421196a8d94bc0ac980476d0b67e1d0988d72b2d0" +checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" dependencies = [ - "pest", - "pest_generator", + "pin-project-internal 1.0.8", ] [[package]] -name = "pest_generator" -version = "2.1.3" +name = "pin-project-internal" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99b8db626e31e5b81787b9783425769681b347011cc59471e33ea46d2ea0cf55" +checksum = "3be26700300be6d9d23264c73211d8190e755b6b5ca7a1b28230025511b52a5e" dependencies = [ - "pest", - "pest_meta", "proc-macro2", "quote", "syn", ] [[package]] -name = "pest_meta" -version = "2.1.3" +name = "pin-project-internal" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54be6e404f5317079812fc8f9f5279de376d8856929e21c184ecf6bbd692a11d" +checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" dependencies = [ - "maplit", - "pest", - "sha-1", + "proc-macro2", + "quote", + "syn", ] +[[package]] +name = "pin-project-lite" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" + [[package]] name = "pin-project-lite" version = "0.2.7" @@ -1447,7 +2290,7 @@ dependencies = [ "libc", "log", "wepoll-ffi", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1456,6 +2299,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + [[package]] name = "proc-macro2" version = "1.0.34" @@ -1469,6 +2318,8 @@ dependencies = [ name = "qsv" version = "0.25.2-beta" dependencies = [ + "actix-governor", + "actix-web", "byteorder", "cached", "censor", @@ -1482,6 +2333,7 @@ dependencies = [ "eudex", "filetime", "flexi_logger", + "governor 0.4.0", "hlua", "indicatif", "itertools", @@ -1519,6 +2371,32 @@ dependencies = [ "num-traits", ] +[[package]] +name = "quanta" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98dc777a7a39b76b1a26ae9d3f691f4c1bc0455090aa0b64dfa8cb7fc34c135" +dependencies = [ + "libc", + "winapi 0.3.9", +] + +[[package]] +name = "quanta" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20afe714292d5e879d8b12740aa223c6a88f118af41870e8b6196e39a02238a8" +dependencies = [ + "crossbeam-utils 0.8.5", + "libc", + "mach", + "once_cell", + "raw-cpuid", + "wasi 0.10.2+wasi-snapshot-preview1", + "web-sys", + "winapi 0.3.9", +] + [[package]] name = "quick-csv" version = "0.1.6" @@ -1528,6 +2406,12 @@ dependencies = [ "rustc-serialize", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quick-xml" version = "0.20.0" @@ -1565,7 +2449,7 @@ dependencies = [ "libc", "rand_core 0.3.1", "rdrand", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1664,6 +2548,15 @@ dependencies = [ "rand_core 0.6.3", ] +[[package]] +name = "raw-cpuid" +version = "10.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "929f54e29691d4e6a9cc558479de70db7aa3d98cd6fe7ab86d7507aa2886b9d2" +dependencies = [ + "bitflags", +] + [[package]] name = "rayon" version = "1.5.1" @@ -1736,7 +2629,7 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" dependencies = [ - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1746,7 +2639,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07bea77bc708afa10e59905c3d4af7c8fd43c9214251673095ff8b14345fcbc5" dependencies = [ "base64", - "bytes", + "bytes 1.1.0", "encoding_rs", "futures-core", "futures-util", @@ -1760,20 +2653,30 @@ dependencies = [ "log", "mime", "percent-encoding", - "pin-project-lite", + "pin-project-lite 0.2.7", "rustls", "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", - "tokio", + "tokio 1.15.0", "tokio-rustls", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", "webpki-roots", - "winreg", + "winreg 0.7.0", +] + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", ] [[package]] @@ -1801,7 +2704,7 @@ dependencies = [ "spin", "untrusted", "web-sys", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -1810,6 +2713,24 @@ version = "0.3.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.4", +] + [[package]] name = "rustls" version = "0.20.2" @@ -1871,21 +2792,42 @@ dependencies = [ "quick-xml", "regex", "reqwest", - "semver", + "semver 0.11.0", "serde_json", "tempfile", "zip", ] +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser 0.7.0", +] + [[package]] name = "semver" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" dependencies = [ - "semver-parser", + "semver-parser 0.10.2", ] +[[package]] +name = "semver" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + [[package]] name = "semver-parser" version = "0.10.2" @@ -1957,12 +2899,31 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df" dependencies = [ - "block-buffer", - "digest", + "block-buffer 0.7.3", + "digest 0.8.1", "fake-simd", - "opaque-debug", + "opaque-debug 0.2.3", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", ] +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" + [[package]] name = "signal-hook" version = "0.3.12" @@ -1988,6 +2949,23 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" +[[package]] +name = "smallvec" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" + +[[package]] +name = "socket2" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "winapi 0.3.9", +] + [[package]] name = "socket2" version = "0.4.2" @@ -1995,7 +2973,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" dependencies = [ "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2004,6 +2982,64 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "standback" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" +dependencies = [ + "version_check", +] + +[[package]] +name = "stdweb" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" +dependencies = [ + "discard", + "rustc_version 0.2.3", + "stdweb-derive", + "stdweb-internal-macros", + "stdweb-internal-runtime", + "wasm-bindgen", +] + +[[package]] +name = "stdweb-derive" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "stdweb-internal-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" +dependencies = [ + "base-x", + "proc-macro2", + "quote", + "serde", + "serde_derive", + "serde_json", + "sha1", + "syn", +] + +[[package]] +name = "stdweb-internal-runtime" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" + [[package]] name = "strsim" version = "0.10.0" @@ -2041,7 +3077,7 @@ dependencies = [ "rand 0.8.4", "redox_syscall", "remove_dir_all", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2051,7 +3087,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" dependencies = [ "libc", - "winapi", + "winapi 0.3.9", ] [[package]] @@ -2117,7 +3153,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" dependencies = [ "libc", - "winapi", + "winapi 0.3.9", +] + +[[package]] +name = "time" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" +dependencies = [ + "const_fn", + "libc", + "standback", + "stdweb", + "time-macros 0.1.1", + "version_check", + "winapi 0.3.9", ] [[package]] @@ -2128,7 +3179,17 @@ checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad" dependencies = [ "itoa 0.4.8", "libc", - "time-macros", + "time-macros 0.2.3", +] + +[[package]] +name = "time-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" +dependencies = [ + "proc-macro-hack", + "time-macros-impl", ] [[package]] @@ -2137,6 +3198,19 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6" +[[package]] +name = "time-macros-impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "standback", + "syn", +] + [[package]] name = "tinyvec" version = "1.5.1" @@ -2162,19 +3236,39 @@ dependencies = [ "regex", ] +[[package]] +name = "tokio" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" +dependencies = [ + "bytes 0.5.6", + "futures-core", + "iovec", + "lazy_static", + "libc", + "memchr", + "mio 0.6.23", + "mio-uds", + "pin-project-lite 0.1.12", + "signal-hook-registry", + "slab", + "winapi 0.3.9", +] + [[package]] name = "tokio" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" dependencies = [ - "bytes", + "bytes 1.1.0", "libc", "memchr", - "mio", + "mio 0.7.14", "num_cpus", - "pin-project-lite", - "winapi", + "pin-project-lite 0.2.7", + "winapi 0.3.9", ] [[package]] @@ -2184,22 +3278,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b" dependencies = [ "rustls", - "tokio", + "tokio 1.15.0", "webpki 0.22.0", ] +[[package]] +name = "tokio-util" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be8242891f2b6cbef26a2d7e8605133c2c554cd35b3e4948ea892d6d68436499" +dependencies = [ + "bytes 0.5.6", + "futures-core", + "futures-sink", + "log", + "pin-project-lite 0.1.12", + "tokio 0.2.25", +] + [[package]] name = "tokio-util" version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" dependencies = [ - "bytes", + "bytes 1.1.0", "futures-core", "futures-sink", "log", - "pin-project-lite", - "tokio", + "pin-project-lite 0.2.7", + "tokio 1.15.0", ] [[package]] @@ -2215,7 +3323,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" dependencies = [ "cfg-if 1.0.0", - "pin-project-lite", + "log", + "pin-project-lite 0.2.7", "tracing-core", ] @@ -2228,6 +3337,55 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project 1.0.8", + "tracing", +] + +[[package]] +name = "trust-dns-proto" +version = "0.19.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cad71a0c0d68ab9941d2fb6e82f8fb2e86d9945b94e1661dd0aaea2b88215a9" +dependencies = [ + "async-trait", + "cfg-if 1.0.0", + "enum-as-inner", + "futures", + "idna", + "lazy_static", + "log", + "rand 0.7.3", + "smallvec", + "thiserror", + "tokio 0.2.25", + "url", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.19.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "710f593b371175db53a26d0b38ed2978fafb9e9e8d3868b1acd753ea18df0ceb" +dependencies = [ + "cfg-if 0.1.10", + "futures", + "ipconfig", + "lazy_static", + "log", + "lru-cache", + "resolv-conf", + "smallvec", + "thiserror", + "tokio 0.2.25", + "trust-dns-proto", +] + [[package]] name = "try-lock" version = "0.2.3" @@ -2270,6 +3428,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + [[package]] name = "unicode-width" version = "0.1.9" @@ -2488,6 +3652,18 @@ dependencies = [ "hashbrown 0.7.2", ] +[[package]] +name = "widestring" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" + +[[package]] +name = "winapi" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" + [[package]] name = "winapi" version = "0.3.9" @@ -2498,6 +3674,12 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] +[[package]] +name = "winapi-build" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" + [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -2510,13 +3692,32 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "winreg" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "winreg" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" dependencies = [ - "winapi", + "winapi 0.3.9", +] + +[[package]] +name = "ws2_32-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" +dependencies = [ + "winapi 0.2.8", + "winapi-build", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0c6536c3c..785a3bcfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,12 +73,9 @@ whatlang = { version = "0.12.0", optional = true } reqwest = { version = "0.11", features = ["blocking", "json", "rustls-tls"], default-features = false } jql = { version = "3.0.6", default-features = false } governor = "0.4" -nonzero_ext = "0.3" [dev-dependencies] quickcheck = { version = "1", default-features = false } -tokio = { version = "1", features = ["rt", "time", "macros"] } -lazy_static = "=1.4.0" actix-web = "3.3" actix-governor = "0.2" diff --git a/src/cmd/fetch.rs b/src/cmd/fetch.rs index cb12ebb2c..1b7dff3b1 100644 --- a/src/cmd/fetch.rs +++ b/src/cmd/fetch.rs @@ -24,7 +24,7 @@ fetch options: -c, --new-column Put the fetched values in a new column instead. --jql Apply jql selector to API returned JSON value. -j, --jobs Number of concurrent requests. - --throttle Set throttle delay between requests in milliseconds. Recommend 1000 ms or greater (default: 5000 ms). + --rate-limit Rate Limit in Queries Per Second. [default: 5] --header File containing additional HTTP Request Headers. Useful for setting Authorization or overriding User Agent. --store-error On error, store HTTP error instead of blank value. --cookies Automatically store and send cookies. Useful for authenticated sessions. @@ -46,7 +46,7 @@ struct Args { flag_new_column: Option, flag_jql: Option, flag_jobs: Option, - flag_throttle: Option, + flag_rate_limit: Option, flag_header: Option, flag_store_error: bool, flag_cookies: bool, @@ -74,7 +74,7 @@ pub fn run(argv: &[&str]) -> CliResult<()> { new column: {:?}, jql: {:?}, threads: {:?}, - throttle delay: {:?}, + rate limit: {:?}, http header file: {:?}, store error: {:?}, store cookie: {:?}, @@ -87,7 +87,7 @@ pub fn run(argv: &[&str]) -> CliResult<()> { &args.flag_new_column, &args.flag_jql, &args.flag_jobs, - &args.flag_throttle, + &args.flag_rate_limit, &args.flag_header, &args.flag_store_error, &args.flag_cookies, @@ -114,6 +114,18 @@ pub fn run(argv: &[&str]) -> CliResult<()> { "Only one single URL column may be selected." ); + use std::num::NonZeroU32; + // default rate limit is 3 qps + let mut rate_limit: NonZeroU32 = NonZeroU32::new(5).unwrap(); + if let Some(qps) = args.flag_rate_limit { + assert!( + qps <= 30 && qps > 0, + "Rate Limit should be between 1 to 30 queries per second." + ); + rate_limit = NonZeroU32::new(qps).unwrap(); + } + + use reqwest::blocking::Client; let client = Client::builder() .user_agent(DEFAULT_USER_AGENT) @@ -125,8 +137,8 @@ pub fn run(argv: &[&str]) -> CliResult<()> { Quota }; - use nonzero_ext::nonzero; - let limiter = RateLimiter::direct(Quota::per_second(nonzero!(3u32))); + + let limiter = RateLimiter::direct(Quota::per_second(rate_limit)); let mut include_existing_columns = false; @@ -220,11 +232,11 @@ fn get_cached_response( loop { match limiter.check() { Ok(()) => { - debug!("going ahead"); + // debug!("going ahead"); break; }, _ => { - debug!("sleeping for 10 ms"); + // debug!("sleeping for 10 ms"); thread::sleep(time::Duration::from_millis(10)); } } diff --git a/tests/test_fetch.rs b/tests/test_fetch.rs index f7700b9b5..67e32cb35 100644 --- a/tests/test_fetch.rs +++ b/tests/test_fetch.rs @@ -15,7 +15,8 @@ fn fetch_simple() { ], ); let mut cmd = wrk.command("fetch"); - cmd.arg("URL").arg("data.csv"); + cmd.arg("URL") + .arg("data.csv"); let got: Vec> = wrk.read_stdout(&mut cmd); let expected = vec![ @@ -132,9 +133,9 @@ fn run_webserver(tx: mpsc::Sender) -> std::io::Result<()> { }; // Allow bursts with up to five requests per IP address - // and replenishes one element every two seconds + // and replenishes one element every 500 ms (2 qps) let governor_conf:GovernorConfig = GovernorConfigBuilder::default() - .per_second(2) + .per_millisecond(500) .burst_size(5) .finish() .unwrap(); @@ -205,6 +206,8 @@ fn fetch_ratelimit() { .arg("Fullname") .arg("--jql") .arg(r#"."fullname""#) + .arg("--rate-limit") + .arg("2") .arg("data.csv"); let got: Vec> = wrk.read_stdout(&mut cmd); From 5ec1bf31963c7d51a8fc42a5ffcb48c15cc7b64a Mon Sep 17 00:00:00 2001 From: "Michael S. Huang" Date: Thu, 30 Dec 2021 22:34:59 +0800 Subject: [PATCH 3/3] fix typo --- src/cmd/fetch.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cmd/fetch.rs b/src/cmd/fetch.rs index 1b7dff3b1..a0f8856c4 100644 --- a/src/cmd/fetch.rs +++ b/src/cmd/fetch.rs @@ -115,7 +115,7 @@ pub fn run(argv: &[&str]) -> CliResult<()> { ); use std::num::NonZeroU32; - // default rate limit is 3 qps + // default rate limit is actually set via docopt, so below init is just to satisfy compiler let mut rate_limit: NonZeroU32 = NonZeroU32::new(5).unwrap(); if let Some(qps) = args.flag_rate_limit { assert!(