Skip to content

Commit

Permalink
Expose a session timeout property through configuration and the builder.
Browse files Browse the repository at this point in the history
  • Loading branch information
locka99 committed Feb 27, 2019
1 parent 53e7278 commit 7a1022b
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 13 deletions.
8 changes: 8 additions & 0 deletions client/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,12 @@ impl ClientBuilder {
self.config.session_retry_interval = session_retry_interval;
self
}

/// Sets the session timeout period
pub fn session_timeout(mut self, session_timeout: u32) -> Self {
self.config.session_timeout = session_timeout;
self
}
}

#[test]
Expand All @@ -189,6 +195,7 @@ fn client_builder() {
.default_endpoint("http://default")
.session_retry_interval(1234)
.session_retry_limit(999)
.session_timeout(777)
// TODO user tokens, endpoints
;

Expand All @@ -204,4 +211,5 @@ fn client_builder() {
assert_eq!(c.default_endpoint, "http://default");
assert_eq!(c.session_retry_interval, 1234);
assert_eq!(c.session_retry_limit, 999);
assert_eq!(c.session_timeout, 777);
}
8 changes: 5 additions & 3 deletions client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,15 +122,17 @@ impl Client {
certificate_store.trust_unknown_certs = true;
}

let session_timeout = config.session_timeout as f64;

// The session retry policy dictates how many times to retry if connection to the server goes down
// and on what interval
let session_retry_policy = match config.session_retry_limit {
// Try forever
-1 => SessionRetryPolicy::infinity(config.session_retry_interval),
-1 => SessionRetryPolicy::infinity(session_timeout, config.session_retry_interval),
// Never try
0 => SessionRetryPolicy::never(),
0 => SessionRetryPolicy::never(session_timeout),
// Try this many times
session_retry_limit => SessionRetryPolicy::new(session_retry_limit as u32, config.session_retry_interval)
session_retry_limit => SessionRetryPolicy::new(session_timeout, session_retry_limit as u32, config.session_retry_interval)
};

Client {
Expand Down
3 changes: 3 additions & 0 deletions client/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ pub struct ClientConfig {
pub session_retry_limit: i32,
/// Retry interval in milliseconds
pub session_retry_interval: u32,
/// Session timeout period in milliseconds
pub session_timeout: u32,
}

impl Config for ClientConfig {
Expand Down Expand Up @@ -181,6 +183,7 @@ impl ClientConfig {
endpoints: BTreeMap::new(),
session_retry_limit: SessionRetryPolicy::DEFAULT_RETRY_LIMIT as i32,
session_retry_interval: SessionRetryPolicy::DEFAULT_RETRY_INTERVAL_MS,
session_timeout: 0,
}
}
}
Expand Down
5 changes: 3 additions & 2 deletions client/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,9 +520,8 @@ impl Session {
ByteString::null()
};

// TODO this should come from a configurable setting.
// Requested session timeout should be larger than your expected subscription rate.
let requested_session_timeout = std::f64::MAX;
let requested_session_timeout = self.session_retry_policy.session_timeout();

let request = CreateSessionRequest {
request_header: self.make_request_header(),
Expand Down Expand Up @@ -553,6 +552,8 @@ impl Session {
let _ = secure_channel.set_remote_cert_from_byte_string(&response.server_certificate);
}

self.session_retry_policy.set_session_timeout(response.revised_session_timeout);

debug!("Server nonce is {:?}", response.server_nonce);
debug!("Revised session timeout is {}", response.revised_session_timeout);

Expand Down
35 changes: 28 additions & 7 deletions client/src/session_retry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ pub enum Answer {
/// Once a connection succeeds, the retry limit is reset.
#[derive(Debug, PartialEq, Clone)]
pub struct SessionRetryPolicy {
/// The session timeout period in milliseconds. Used by client to run a keep-alive operation. Initially this
/// will contain your desired timeout period, but it will be adjusted when the session is created.
session_timeout: f64,
/// The maximum number of times to retry between failures before giving up. A value of 0 means
/// no retries, i.e. give up on first fail, None means no limit, i.e. infinity
retry_limit: Option<u32>,
Expand All @@ -36,7 +39,7 @@ pub struct SessionRetryPolicy {

impl Default for SessionRetryPolicy {
fn default() -> Self {
Self::new(Self::DEFAULT_RETRY_LIMIT, Self::DEFAULT_RETRY_INTERVAL_MS)
Self::new(Self::DEFAULT_SESSION_TIMEOUT_MS, Self::DEFAULT_RETRY_LIMIT, Self::DEFAULT_RETRY_INTERVAL_MS)
}
}

Expand All @@ -47,11 +50,15 @@ impl SessionRetryPolicy {
pub const DEFAULT_RETRY_INTERVAL_MS: u32 = 10000;
/// The minimum retry interval
pub const MIN_RETRY_INTERVAL_MS: u32 = 500;
/// The default session timeout interval in millis
pub const DEFAULT_SESSION_TIMEOUT_MS: f64 = std::f64::MAX;

/// Create a `SessionRetryPolicy` with a limit and interval
pub fn new(retry_limit: u32, retry_interval: u32) -> Self {
pub fn new(session_timeout: f64, retry_limit: u32, retry_interval: u32) -> Self {
let session_timeout = if session_timeout == 0.0 { Self::DEFAULT_SESSION_TIMEOUT_MS } else { session_timeout };
let retry_interval = if retry_interval < Self::MIN_RETRY_INTERVAL_MS { Self::MIN_RETRY_INTERVAL_MS } else { retry_interval };
SessionRetryPolicy {
session_timeout,
retry_count: 0,
last_attempt: Self::last_attempt_default(),
retry_limit: Some(retry_limit),
Expand All @@ -60,9 +67,11 @@ impl SessionRetryPolicy {
}

/// Create a `SessionRetryPolicy` that tries forever at the specified interval
pub fn infinity(retry_interval: u32) -> Self {
pub fn infinity(session_timeout: f64, retry_interval: u32) -> Self {
let session_timeout = if session_timeout == 0.0 { Self::DEFAULT_SESSION_TIMEOUT_MS } else { session_timeout };
let retry_interval = if retry_interval < Self::MIN_RETRY_INTERVAL_MS { Self::MIN_RETRY_INTERVAL_MS } else { retry_interval };
SessionRetryPolicy {
session_timeout,
retry_count: 0,
last_attempt: Self::last_attempt_default(),
retry_limit: None,
Expand All @@ -71,14 +80,22 @@ impl SessionRetryPolicy {
}

/// Create a `SessionRetryPolicy` that never tries again.
pub fn never() -> Self {
Self::new(0, 0)
pub fn never(session_timeout: f64) -> Self {
Self::new(session_timeout, 0, 0)
}

fn last_attempt_default() -> DateTime<Utc> {
Utc.ymd(1900, 1, 1).and_hms(0, 0, 0)
}

pub fn session_timeout(&self) -> f64 {
self.session_timeout
}

pub fn set_session_timeout(&mut self, session_timeout: f64) {
self.session_timeout = session_timeout;
}

pub fn retry_count(&self) -> u32 {
self.retry_count
}
Expand Down Expand Up @@ -133,6 +150,8 @@ fn session_retry() {
let last_attempt_expired = now - retry_interval - Duration::nanoseconds(1);
let last_attempt_wait = now - retry_interval + Duration::seconds(1);

assert_eq!(session_retry.session_timeout(), SessionRetryPolicy::DEFAULT_SESSION_TIMEOUT_MS);

session_retry.set_last_attempt(last_attempt_expired);
assert_eq!(session_retry.should_retry_connect(now), Answer::Retry);
session_retry.retry_count = SessionRetryPolicy::DEFAULT_RETRY_LIMIT - 1;
Expand All @@ -147,14 +166,16 @@ fn session_retry() {

#[test]
fn session_retry_infinity() {
let session_retry = SessionRetryPolicy::infinity(1000);
let session_retry = SessionRetryPolicy::infinity(444.444, 1000);
let now = Utc::now();
assert_eq!(session_retry.should_retry_connect(now), Answer::Retry);
assert_eq!(session_retry.session_timeout(), 444.444);
}

#[test]
fn session_retry_never() {
let mut session_retry = SessionRetryPolicy::never();
let mut session_retry = SessionRetryPolicy::never(987.123);
let now = Utc::now();
assert_eq!(session_retry.should_retry_connect(now), Answer::GiveUp);
assert_eq!(session_retry.session_timeout(), 987.123);
}
3 changes: 2 additions & 1 deletion samples/client.conf
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ endpoints:
security_mode: None
user_token_id: ANONYMOUS
session_retry_limit: 10
session_retry_interval: 10000
session_retry_interval: 10000
session_timeout: 0

0 comments on commit 7a1022b

Please sign in to comment.