Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

optimize fast path with Duration-based wait time #368

Merged
merged 10 commits into from
Oct 13, 2021
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## 0.14.1-dev
- [#364](https://github.com/tag1consulting/goose/pull/364) add link from the [Developer Documentation](https://docs.rs/goose) to [The Git Book](https://book.goose.rs)
- [#368](https://github.com/tag1consulting/goose/pull/368) optimize fastpath if no delay between tasks

## 0.14.0 September 15, 2021
- [#361](https://github.com/tag1consulting/goose/pull/361) convert `README.md` (and enhance) into [`The Goose Book`](https://book.goose.rs/)
Expand Down
3 changes: 1 addition & 2 deletions examples/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@
//! See the License for the specific language governing permissions and
//! limitations under the License.

use std::time::Duration;

use goose::prelude::*;
use tokio::time::Duration;

#[tokio::main]
async fn main() -> Result<(), GooseError> {
Expand Down
3 changes: 1 addition & 2 deletions examples/simple_closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
//! limitations under the License.

use goose::prelude::*;

use std::boxed::Box;
use std::sync::Arc;
use std::time::Duration;
use tokio::time::Duration;

#[tokio::main]
async fn main() -> Result<(), GooseError> {
Expand Down
3 changes: 1 addition & 2 deletions examples/simple_with_session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@
//! See the License for the specific language governing permissions and
//! limitations under the License.

use std::time::Duration;

use goose::prelude::*;
use serde::Deserialize;
use tokio::time::Duration;

struct Session {
jwt_token: String,
Expand Down
5 changes: 2 additions & 3 deletions examples/umami/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ mod common;
mod english;
mod spanish;

use std::time::Duration;

use goose::prelude::*;
use std::time::Duration;
jeremyandrews marked this conversation as resolved.
Show resolved Hide resolved

use crate::admin::*;
use crate::english::*;
Expand Down Expand Up @@ -73,7 +72,7 @@ async fn main() -> Result<(), GooseError> {
.register_taskset(
taskset!("Admin user")
.set_weight(1)?
.set_wait_time(Duration::from_secs(0), Duration::from_secs(3))?
.set_wait_time(Duration::from_secs(3), Duration::from_secs(10))?
jeremyandrews marked this conversation as resolved.
Show resolved Hide resolved
.register_task(task!(log_in).set_on_start().set_name("auth /en/user/login"))
.register_task(task!(front_page_en).set_name("auth /").set_weight(2)?)
.register_task(task!(article_listing_en).set_name("auth /en/articles/"))
Expand Down
46 changes: 27 additions & 19 deletions src/goose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,15 @@
//!
//! ### Task Set Wait Time
//!
//! Wait time is specified as a low-high duration range. Each time a task completes in
//! the task set, the user will pause for a random number of milliseconds inclusively between
//! Wait time is specified as a low-high integer range. Each time a task completes in
//! the task set, the user will pause for a random number of seconds inclusively between
//! the low and high wait times. In the following example, users loading `foo` tasks will
//! sleep 0 to 3 seconds after each task completes, and users loading `bar` tasks will
//! sleep 5 to 10 seconds after each task completes.
//!
//! ```rust
//! use goose::prelude::*;
//! use std::time::Duration;
//! use tokio::time::Duration;
//!
//! let mut foo_tasks = taskset!("FooTasks").set_wait_time(Duration::from_secs(0), Duration::from_secs(3)).unwrap();
//! let mut bar_tasks = taskset!("BarTasks").set_wait_time(Duration::from_secs(5), Duration::from_secs(10)).unwrap();
Expand Down Expand Up @@ -293,10 +293,10 @@ use reqwest::{header, Client, ClientBuilder, RequestBuilder, Response};
use serde::{Deserialize, Serialize};
use std::hash::{Hash, Hasher};
use std::sync::Arc;
use std::time::Duration;
use std::{fmt, str};
use std::{future::Future, pin::Pin, time::Instant};
use tokio::sync::RwLock;
use tokio::time::Duration;
use url::Url;

use crate::logger::GooseLog;
Expand Down Expand Up @@ -472,7 +472,8 @@ pub struct GooseTaskSet {
pub task_sets_index: usize,
/// An integer value that controls the frequency that this task set will be assigned to a user.
pub weight: usize,
/// An range of duration indicating the interval a user will sleep after running a task.
/// A [`Duration`](https://doc.rust-lang.org/std/time/struct.Duration.html) range defining the
/// minimum and maximum time a [`GooseUser`] should sleep after running a task.
pub task_wait: Option<(Duration, Duration)>,
/// A vector containing one copy of each [`GooseTask`](./struct.GooseTask.html) that will
/// run by users running this task set.
Expand Down Expand Up @@ -591,14 +592,14 @@ impl GooseTaskSet {
self
}

/// Configure a duration per task_set to pause after running each task. The length of the pause will be randomly
/// selected from `min_wait` to `max_wait` inclusively. For example, if `min_wait` is `Duration::from_secs(0)` and
/// `max_wait` is `Duration::from_secs(2)`, the user will randomly sleep between 0 and 2_000 milliseconds after each task completes.
/// Configure a task_set to to pause after running each task. The length of the pause will be randomly
/// selected from `min_weight` to `max_wait` inclusively. For example, if `min_wait` is `0` and
/// `max_weight` is `2`, the user will randomly sleep for 0, 1 or 2 seconds after each task completes.
///
/// # Example
/// ```rust
/// use goose::prelude::*;
/// use std::time::Duration;
/// use tokio::time::Duration;
///
/// #[tokio::main]
/// async fn main() -> Result<(), GooseError> {
Expand All @@ -609,16 +610,16 @@ impl GooseTaskSet {
/// ```
pub fn set_wait_time(
mut self,
min_wait: Duration,
max_wait: Duration,
min_wait: tokio::time::Duration,
max_wait: tokio::time::Duration,
) -> Result<Self, GooseError> {
trace!(
"{} set_wait time: min: {}ms max: {}ms",
"{} set_wait time: min: {:?} max: {:?}",
self.name,
min_wait.as_millis(),
max_wait.as_millis()
min_wait,
max_wait
);
if min_wait > max_wait {
if min_wait.as_millis() > max_wait.as_millis() {
return Err(GooseError::InvalidWaitTime {
min_wait,
max_wait,
Expand All @@ -627,7 +628,7 @@ impl GooseTaskSet {
.to_string(),
});
}
self.task_wait.replace((min_wait, max_wait));
self.task_wait = Some((min_wait, max_wait));

Ok(self)
}
Expand Down Expand Up @@ -2245,7 +2246,7 @@ impl GooseUser {
/// # Example
/// ```rust
/// use goose::prelude::*;
/// use std::time::Duration;
/// use tokio::time::Duration;
///
/// #[tokio::main]
/// async fn main() -> Result<(), GooseError> {
Expand Down Expand Up @@ -2714,14 +2715,18 @@ mod tests {
assert_eq!(task_set.tasks.len(), 3);
assert_eq!(task_set.weighted_tasks.len(), 0);
assert_eq!(task_set.task_sets_index, usize::max_value());
assert_eq!(task_set.task_wait, None);

// Host field can be changed.
task_set = task_set.set_host("https://bar.example.com/");
assert_eq!(task_set.host, Some("https://bar.example.com/".to_string()));

// Wait time only affects wait time fields.
task_set = task_set
.set_wait_time(Duration::from_secs(1), Duration::from_secs(10))
.set_wait_time(
tokio::time::Duration::from_secs(1),
tokio::time::Duration::from_secs(10),
)
.unwrap();
assert_eq!(
task_set.task_wait,
Expand All @@ -2735,7 +2740,10 @@ mod tests {

// Wait time can be changed.
task_set = task_set
.set_wait_time(Duration::from_secs(3), Duration::from_secs(9))
.set_wait_time(
tokio::time::Duration::from_secs(3),
tokio::time::Duration::from_secs(9),
)
.unwrap();
assert_eq!(
task_set.task_wait,
Expand Down
9 changes: 4 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@
//! helper, for example to set a timeout on this specific request:
//!
//! ```rust
//! use std::time;
//! use tokio::time::Duration;
//!
//! use goose::prelude::*;
//!
//! async fn loadtest_bar(user: &mut GooseUser) -> GooseTaskResult {
//! let request_builder = user.goose_get("/path/to/bar")?;
//! let _goose = user.goose_send(request_builder.timeout(time::Duration::from_secs(3)), None).await?;
//! let _goose = user.goose_send(request_builder.timeout(Duration::from_secs(3)), None).await?;
//!
//! Ok(())
//! }
Expand Down Expand Up @@ -468,7 +468,6 @@ use std::sync::{
atomic::{AtomicBool, AtomicUsize, Ordering},
Arc,
};
use std::time::Duration;
use std::{fmt, io, time};
use tokio::fs::File;

Expand Down Expand Up @@ -551,9 +550,9 @@ pub enum GooseError {
/// Invalid wait time specified.
InvalidWaitTime {
// The specified minimum wait time.
min_wait: Duration,
min_wait: tokio::time::Duration,
// The specified maximum wait time.
max_wait: Duration,
max_wait: tokio::time::Duration,
/// An optional explanation of the error.
detail: String,
},
Expand Down
Loading