v0.2.7-pre.003
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-config-lib/src/lib.rs
|
||||
// version: 16
|
||||
// version: 17
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -154,9 +154,9 @@ pub use self::registry::DEFAULT_COMPOSITE_SCHEMA_FILENAME;
|
||||
pub use self::registry::DEFAULT_STD_LOGGING_FILENAME;
|
||||
/// Default physical filename for the standard Logging JSON Schema document.
|
||||
pub use self::registry::DEFAULT_STD_LOGGING_SCHEMA_FILENAME;
|
||||
/// Default physical filename for the standard HTTP Transport configuration document.
|
||||
/// Default physical filename for the standard HTTP + WebSocket Transport configuration document.
|
||||
pub use self::registry::DEFAULT_STD_TRANSPORT_FILENAME;
|
||||
/// Default physical filename for the standard HTTP Transport JSON Schema document.
|
||||
/// Default physical filename for the standard HTTP + WebSocket Transport JSON Schema document.
|
||||
pub use self::registry::DEFAULT_STD_TRANSPORT_SCHEMA_FILENAME;
|
||||
/// Default physical filename for the standard Wallet configuration document.
|
||||
pub use self::registry::DEFAULT_STD_WALLET_FILENAME;
|
||||
@@ -168,13 +168,13 @@ pub use self::registry::FILE_ID_COMPOSITE_KSP_APP_WALLET_DESK;
|
||||
pub use self::registry::FILE_ID_SCHEMA_COMPOSITE;
|
||||
/// Logical file identifier for the standard Logging JSON Schema document.
|
||||
pub use self::registry::FILE_ID_SCHEMA_STD_LOGGING;
|
||||
/// Logical file identifier for the standard HTTP Transport JSON Schema document.
|
||||
/// Logical file identifier for the standard HTTP + WebSocket Transport JSON Schema document.
|
||||
pub use self::registry::FILE_ID_SCHEMA_STD_TRANSPORT;
|
||||
/// Logical file identifier for the standard Wallet JSON Schema document.
|
||||
pub use self::registry::FILE_ID_SCHEMA_STD_WALLET;
|
||||
/// Logical file identifier for the standard Logging configuration document.
|
||||
pub use self::registry::FILE_ID_STD_LOGGING;
|
||||
/// Logical file identifier for the standard HTTP Transport configuration document.
|
||||
/// Logical file identifier for the standard HTTP + WebSocket Transport configuration document.
|
||||
pub use self::registry::FILE_ID_STD_TRANSPORT;
|
||||
/// Logical file identifier for the standard Wallet configuration document.
|
||||
pub use self::registry::FILE_ID_STD_WALLET;
|
||||
@@ -188,7 +188,7 @@ pub use self::sensitivity::REDACTED_CONFIG_VALUE;
|
||||
pub use self::sensitivity::ResolvedConfigJson;
|
||||
/// One resolved Config string preserving real/safe representations and provenance.
|
||||
pub use self::sensitivity::ResolvedConfigText;
|
||||
/// Effective standard HTTP Transport configuration mapped to `ksp_onchain_transport_lib::HttpTransportSettings`.
|
||||
/// Effective standard Transport configuration mapped to HTTP and optional WebSocket runtime settings.
|
||||
pub use self::transport::ResolvedTransportConfig;
|
||||
/// Effective standard Wallet configuration resolved to validated filesystem roots.
|
||||
pub use self::wallet::ResolvedWalletConfig;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-config-lib/src/registry.rs
|
||||
// version: 8
|
||||
// version: 9
|
||||
|
||||
/// Bootstrap argument used to replace a known Config filename mapping.
|
||||
pub const ARG_FILE_MAP: &str = "--filemap";
|
||||
@@ -11,9 +11,9 @@ pub const DEFAULT_COMPOSITE_SCHEMA_FILENAME: &str = "composite.schema.json";
|
||||
pub const DEFAULT_STD_LOGGING_FILENAME: &str = "std.logging.json";
|
||||
/// Default physical filename for the standard Logging JSON Schema document.
|
||||
pub const DEFAULT_STD_LOGGING_SCHEMA_FILENAME: &str = "std.logging.schema.json";
|
||||
/// Default physical filename for the standard HTTP Transport configuration document.
|
||||
/// Default physical filename for the standard HTTP + WebSocket Transport configuration document.
|
||||
pub const DEFAULT_STD_TRANSPORT_FILENAME: &str = "std.transport.json";
|
||||
/// Default physical filename for the standard HTTP Transport JSON Schema document.
|
||||
/// Default physical filename for the standard HTTP + WebSocket Transport JSON Schema document.
|
||||
pub const DEFAULT_STD_TRANSPORT_SCHEMA_FILENAME: &str = "std.transport.schema.json";
|
||||
/// Default physical filename for the standard Wallet configuration document.
|
||||
pub const DEFAULT_STD_WALLET_FILENAME: &str = "std.wallet.json";
|
||||
@@ -25,13 +25,13 @@ pub const FILE_ID_COMPOSITE_KSP_APP_WALLET_DESK: &str = "cfg.composite.ksp-app-w
|
||||
pub const FILE_ID_SCHEMA_COMPOSITE: &str = "schema.composite";
|
||||
/// Logical file identifier for the standard Logging JSON Schema document.
|
||||
pub const FILE_ID_SCHEMA_STD_LOGGING: &str = "schema.std.logging";
|
||||
/// Logical file identifier for the standard HTTP Transport JSON Schema document.
|
||||
/// Logical file identifier for the standard HTTP + WebSocket Transport JSON Schema document.
|
||||
pub const FILE_ID_SCHEMA_STD_TRANSPORT: &str = "schema.std.transport";
|
||||
/// Logical file identifier for the standard Wallet JSON Schema document.
|
||||
pub const FILE_ID_SCHEMA_STD_WALLET: &str = "schema.std.wallet";
|
||||
/// Logical file identifier for the standard Logging configuration document.
|
||||
pub const FILE_ID_STD_LOGGING: &str = "cfg.std.logging";
|
||||
/// Logical file identifier for the standard HTTP Transport configuration document.
|
||||
/// Logical file identifier for the standard HTTP + WebSocket Transport configuration document.
|
||||
pub const FILE_ID_STD_TRANSPORT: &str = "cfg.std.transport";
|
||||
/// Logical file identifier for the standard Wallet configuration document.
|
||||
pub const FILE_ID_STD_WALLET: &str = "cfg.std.wallet";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// file: crates/ksp-config-lib/src/transport.rs
|
||||
// version: 2
|
||||
// version: 3
|
||||
|
||||
/// Effective standard HTTP Transport configuration resolved from Config and mapped to the Transport runtime contract.
|
||||
/// Effective standard on-chain Transport configuration resolved from Config and mapped to HTTP and optional WebSocket runtime contracts.
|
||||
#[derive(Clone, Eq, PartialEq)]
|
||||
pub struct ResolvedTransportConfig {
|
||||
file_id: crate::ConfigFileId,
|
||||
@@ -10,6 +10,7 @@ pub struct ResolvedTransportConfig {
|
||||
selection_source: crate::ConfigProfileSelectionSource,
|
||||
effective: crate::ResolvedConfigJson,
|
||||
settings: ksp_onchain_transport_lib::HttpTransportSettings,
|
||||
ws_settings: std::option::Option<ksp_onchain_transport_lib::WsTransportSettings>,
|
||||
}
|
||||
|
||||
impl ResolvedTransportConfig {
|
||||
@@ -47,16 +48,43 @@ impl ResolvedTransportConfig {
|
||||
}
|
||||
|
||||
/// Returns the validated runtime HTTP Transport settings.
|
||||
///
|
||||
/// This compatibility accessor keeps the HTTP contract introduced before Transport V2.
|
||||
#[must_use]
|
||||
pub const fn settings(&self) -> &ksp_onchain_transport_lib::HttpTransportSettings {
|
||||
return &self.settings;
|
||||
}
|
||||
|
||||
/// Returns the validated runtime HTTP Transport settings.
|
||||
#[must_use]
|
||||
pub const fn http_settings(&self) -> &ksp_onchain_transport_lib::HttpTransportSettings {
|
||||
return &self.settings;
|
||||
}
|
||||
|
||||
/// Returns validated WebSocket Transport settings when the selected document uses format V2.
|
||||
///
|
||||
/// Backward-compatible V1 HTTP-only documents return [`std::option::Option::None`].
|
||||
#[must_use]
|
||||
pub fn ws_settings(&self) -> std::option::Option<&ksp_onchain_transport_lib::WsTransportSettings> {
|
||||
return self.ws_settings.as_ref();
|
||||
}
|
||||
|
||||
/// Consumes this resolved Config and returns the mapped runtime HTTP Transport settings.
|
||||
#[must_use]
|
||||
pub fn into_settings(self) -> ksp_onchain_transport_lib::HttpTransportSettings {
|
||||
return self.settings;
|
||||
}
|
||||
|
||||
/// Consumes this resolved Config and returns both HTTP and optional WebSocket runtime settings.
|
||||
#[must_use]
|
||||
pub fn into_transport_settings(
|
||||
self,
|
||||
) -> (
|
||||
ksp_onchain_transport_lib::HttpTransportSettings,
|
||||
std::option::Option<ksp_onchain_transport_lib::WsTransportSettings>,
|
||||
) {
|
||||
return (self.settings, self.ws_settings);
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for ResolvedTransportConfig {
|
||||
@@ -68,16 +96,16 @@ impl std::fmt::Debug for ResolvedTransportConfig {
|
||||
.field("profile_id", &self.profile_id)
|
||||
.field("selection_source", &self.selection_source)
|
||||
.field("effective", &self.effective)
|
||||
.field("has_ws_settings", &self.ws_settings.is_some())
|
||||
.finish_non_exhaustive();
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::ConfigDocumentEngine {
|
||||
/// Loads the standard HTTP Transport document, selects a profile, resolves environment placeholders and maps it to Transport runtime settings.
|
||||
/// Loads the standard Transport document, selects a profile, resolves environment placeholders and maps HTTP plus optional WebSocket runtime settings.
|
||||
///
|
||||
/// `requested_profile = None` uses the document `default_profile`; `Some(profile_id)` requests an explicit profile. Secret endpoint URLs are allowed
|
||||
/// because the Transport URL wrapper owns runtime redaction. Invalid environment-resolved values are reported as
|
||||
/// [`crate::ERROR_CODE_EFFECTIVE_CONFIG_INVALID`] without copying endpoint URL values into ordinary error context.
|
||||
/// because Transport URL wrappers own runtime redaction. V1 documents remain HTTP-only; V2 documents require WebSocket defaults and endpoints.
|
||||
pub fn load_resolved_transport_config(
|
||||
&self,
|
||||
requested_profile: std::option::Option<&str>,
|
||||
@@ -96,7 +124,7 @@ impl crate::ConfigDocumentEngine {
|
||||
return resolve_transport_profile(&profile, environment);
|
||||
}
|
||||
|
||||
/// Maps an already resolved standard Transport profile to the runtime HTTP Transport adapter while preserving its selection provenance.
|
||||
/// Maps an already resolved standard Transport profile to HTTP plus optional WebSocket runtime adapters while preserving selection provenance.
|
||||
///
|
||||
/// This entry point is intended for profiles selected by a composite. The profile must reference `cfg.std.transport`.
|
||||
pub fn resolve_transport_config_profile(
|
||||
@@ -121,7 +149,11 @@ struct EffectiveTransportSource {
|
||||
format_version: u32,
|
||||
profile_id: String,
|
||||
retry: EffectiveRetrySource,
|
||||
#[serde(default)]
|
||||
ws_defaults: std::option::Option<EffectiveWsSessionSource>,
|
||||
endpoints: std::vec::Vec<EffectiveEndpointSource>,
|
||||
#[serde(default)]
|
||||
ws_endpoints: std::option::Option<std::vec::Vec<EffectiveWsEndpointSource>>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
@@ -165,7 +197,69 @@ struct EffectiveLimitsSource {
|
||||
pause_after_rate_limit_ms: std::option::Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct EffectiveWsSessionSource {
|
||||
command_timeout_ms: u64,
|
||||
close_timeout_ms: u64,
|
||||
reconnect: EffectiveWsReconnectSource,
|
||||
resubscribe: String,
|
||||
command_queue_capacity: usize,
|
||||
notification_queue_capacity: usize,
|
||||
max_active_subscriptions: usize,
|
||||
max_pending_requests: usize,
|
||||
max_message_size_bytes: usize,
|
||||
max_frame_size_bytes: usize,
|
||||
max_write_buffer_size_bytes: usize,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct EffectiveWsReconnectSource {
|
||||
max_retries: u32,
|
||||
initial_backoff_ms: u64,
|
||||
max_backoff_ms: u64,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct EffectiveWsEndpointSource {
|
||||
name: String,
|
||||
enabled: bool,
|
||||
provider: String,
|
||||
cluster: String,
|
||||
kind: String,
|
||||
url: String,
|
||||
#[serde(default)]
|
||||
session: std::option::Option<EffectiveWsSessionOverrideSource>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct EffectiveWsSessionOverrideSource {
|
||||
command_timeout_ms: std::option::Option<u64>,
|
||||
close_timeout_ms: std::option::Option<u64>,
|
||||
reconnect: std::option::Option<EffectiveWsReconnectOverrideSource>,
|
||||
resubscribe: std::option::Option<String>,
|
||||
command_queue_capacity: std::option::Option<usize>,
|
||||
notification_queue_capacity: std::option::Option<usize>,
|
||||
max_active_subscriptions: std::option::Option<usize>,
|
||||
max_pending_requests: std::option::Option<usize>,
|
||||
max_message_size_bytes: std::option::Option<usize>,
|
||||
max_frame_size_bytes: std::option::Option<usize>,
|
||||
max_write_buffer_size_bytes: std::option::Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
struct EffectiveWsReconnectOverrideSource {
|
||||
max_retries: std::option::Option<u32>,
|
||||
initial_backoff_ms: std::option::Option<u64>,
|
||||
max_backoff_ms: std::option::Option<u64>,
|
||||
}
|
||||
|
||||
fn resolve_transport_profile(profile: &crate::ResolvedConfigProfile, environment: &crate::ConfigEnvironment) -> ksp_core_lib::Result<ResolvedTransportConfig> {
|
||||
ksp_logging_lib::trace!(target: crate::TRACING_TARGET, profile_id = profile.profile_id(), "mapping standard Transport Config profile");
|
||||
let effective = profile.resolve_effective_environment_detailed(environment);
|
||||
let effective = match effective {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -180,12 +274,10 @@ fn resolve_transport_profile(profile: &crate::ResolvedConfigProfile, environment
|
||||
);
|
||||
},
|
||||
};
|
||||
if source.format_version != 1 {
|
||||
return std::result::Result::Err(effective_error(profile, "effective Transport format_version is unsupported"));
|
||||
}
|
||||
if source.profile_id != profile.profile_id() {
|
||||
return std::result::Result::Err(effective_error(profile, "effective Transport profile_id does not match the selected profile"));
|
||||
}
|
||||
let format_version = source.format_version;
|
||||
let retry = ksp_onchain_transport_lib::HttpRetrySettings::new(
|
||||
source.retry.max_retries,
|
||||
std::time::Duration::from_millis(source.retry.initial_backoff_ms),
|
||||
@@ -197,14 +289,24 @@ fn resolve_transport_profile(profile: &crate::ResolvedConfigProfile, environment
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let settings = ksp_onchain_transport_lib::HttpTransportSettings::new(endpoints, retry);
|
||||
let validation = settings.validate();
|
||||
if let std::result::Result::Err(error) = validation {
|
||||
return std::result::Result::Err(transport_contract_error(profile, "effective Transport settings fail the Transport runtime contract", &error));
|
||||
if let std::result::Result::Err(error) = settings.validate() {
|
||||
return std::result::Result::Err(transport_contract_error(profile, "effective HTTP Transport settings fail the Transport runtime contract", &error));
|
||||
}
|
||||
let ws_settings = map_optional_ws_settings(format_version, source.ws_defaults, source.ws_endpoints, profile);
|
||||
let ws_settings = match ws_settings {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let ws_endpoint_count = match ws_settings.as_ref() {
|
||||
std::option::Option::Some(value) => value.endpoints().len(),
|
||||
std::option::Option::None => 0_usize,
|
||||
};
|
||||
ksp_logging_lib::debug!(
|
||||
target: crate::TRACING_TARGET,
|
||||
profile_id = profile.profile_id(),
|
||||
endpoint_count = settings.endpoints().len(),
|
||||
format_version,
|
||||
http_endpoint_count = settings.endpoints().len(),
|
||||
ws_endpoint_count,
|
||||
"mapped standard Transport Config to runtime settings"
|
||||
);
|
||||
return std::result::Result::Ok(ResolvedTransportConfig {
|
||||
@@ -214,9 +316,49 @@ fn resolve_transport_profile(profile: &crate::ResolvedConfigProfile, environment
|
||||
selection_source: profile.selection_source(),
|
||||
effective,
|
||||
settings,
|
||||
ws_settings,
|
||||
});
|
||||
}
|
||||
|
||||
fn map_optional_ws_settings(
|
||||
format_version: u32,
|
||||
defaults: std::option::Option<EffectiveWsSessionSource>,
|
||||
sources: std::option::Option<std::vec::Vec<EffectiveWsEndpointSource>>,
|
||||
profile: &crate::ResolvedConfigProfile,
|
||||
) -> ksp_core_lib::Result<std::option::Option<ksp_onchain_transport_lib::WsTransportSettings>> {
|
||||
return match format_version {
|
||||
1 => {
|
||||
if defaults.is_some() || sources.is_some() {
|
||||
std::result::Result::Err(effective_error(profile, "Transport V1 must remain HTTP-only"))
|
||||
} else {
|
||||
ksp_logging_lib::trace!(target: crate::TRACING_TARGET, profile_id = profile.profile_id(), "mapped backward-compatible Transport V1 without WebSocket settings");
|
||||
std::result::Result::Ok(std::option::Option::None)
|
||||
}
|
||||
},
|
||||
2 => {
|
||||
let defaults = match defaults {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::result::Result::Err(effective_error(profile, "Transport V2 requires ws_defaults")),
|
||||
};
|
||||
let sources = match sources {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => return std::result::Result::Err(effective_error(profile, "Transport V2 profile requires ws_endpoints")),
|
||||
};
|
||||
let endpoints = map_ws_endpoints(sources, &defaults, profile);
|
||||
let endpoints = match endpoints {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let settings = ksp_onchain_transport_lib::WsTransportSettings::new(endpoints);
|
||||
if let std::result::Result::Err(error) = settings.validate() {
|
||||
return std::result::Result::Err(transport_contract_error(profile, "effective WebSocket Transport settings fail the Transport runtime contract", &error));
|
||||
}
|
||||
std::result::Result::Ok(std::option::Option::Some(settings))
|
||||
},
|
||||
_ => std::result::Result::Err(effective_error(profile, "effective Transport format_version is unsupported")),
|
||||
};
|
||||
}
|
||||
|
||||
fn map_endpoints(
|
||||
sources: std::vec::Vec<EffectiveEndpointSource>,
|
||||
profile: &crate::ResolvedConfigProfile,
|
||||
@@ -229,7 +371,7 @@ fn map_endpoints(
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(
|
||||
transport_contract_error(profile, "effective endpoint URL is invalid", &error).with_context("endpoint_name", endpoint_name),
|
||||
transport_contract_error(profile, "effective HTTP endpoint URL is invalid", &error).with_context("endpoint_name", endpoint_name),
|
||||
);
|
||||
},
|
||||
};
|
||||
@@ -253,6 +395,171 @@ fn map_endpoints(
|
||||
return std::result::Result::Ok(endpoints);
|
||||
}
|
||||
|
||||
fn map_ws_endpoints(
|
||||
sources: std::vec::Vec<EffectiveWsEndpointSource>,
|
||||
defaults: &EffectiveWsSessionSource,
|
||||
profile: &crate::ResolvedConfigProfile,
|
||||
) -> ksp_core_lib::Result<std::vec::Vec<ksp_onchain_transport_lib::WsEndpointSettings>> {
|
||||
let mut endpoints = std::vec::Vec::<ksp_onchain_transport_lib::WsEndpointSettings>::with_capacity(sources.len());
|
||||
for source in sources {
|
||||
let endpoint_name = source.name.clone();
|
||||
let protocol = map_ws_protocol_kind(source.kind.as_str(), profile, endpoint_name.as_str());
|
||||
let protocol = match protocol {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let url = ksp_onchain_transport_lib::WsEndpointUrl::parse(source.url);
|
||||
let url = match url {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
return std::result::Result::Err(
|
||||
transport_contract_error(profile, "effective WebSocket endpoint URL is invalid", &error).with_context("endpoint_name", endpoint_name),
|
||||
);
|
||||
},
|
||||
};
|
||||
let session = map_ws_session_settings(defaults, source.session.as_ref(), profile, endpoint_name.as_str());
|
||||
let session = match session {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
endpoints.push(ksp_onchain_transport_lib::WsEndpointSettings::new(
|
||||
source.name,
|
||||
source.enabled,
|
||||
ksp_onchain_transport_lib::WsProviderName::new(source.provider),
|
||||
ksp_onchain_transport_lib::WsClusterName::new(source.cluster),
|
||||
protocol,
|
||||
url,
|
||||
session,
|
||||
));
|
||||
}
|
||||
return std::result::Result::Ok(endpoints);
|
||||
}
|
||||
|
||||
fn map_ws_protocol_kind(
|
||||
value: &str,
|
||||
profile: &crate::ResolvedConfigProfile,
|
||||
endpoint_name: &str,
|
||||
) -> ksp_core_lib::Result<ksp_onchain_transport_lib::WsProtocolKind> {
|
||||
return match value {
|
||||
"solana_standard" => std::result::Result::Ok(ksp_onchain_transport_lib::WsProtocolKind::SolanaStandard),
|
||||
_ => std::result::Result::Err(
|
||||
effective_error(profile, "effective WebSocket protocol kind is unsupported")
|
||||
.with_context("endpoint_name", endpoint_name)
|
||||
.with_context("ws_kind", value),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
fn map_ws_session_settings(
|
||||
defaults: &EffectiveWsSessionSource,
|
||||
overrides: std::option::Option<&EffectiveWsSessionOverrideSource>,
|
||||
profile: &crate::ResolvedConfigProfile,
|
||||
endpoint_name: &str,
|
||||
) -> ksp_core_lib::Result<ksp_onchain_transport_lib::WsSessionSettings> {
|
||||
let mut command_timeout_ms = defaults.command_timeout_ms;
|
||||
let mut close_timeout_ms = defaults.close_timeout_ms;
|
||||
let mut reconnect_max_retries = defaults.reconnect.max_retries;
|
||||
let mut reconnect_initial_backoff_ms = defaults.reconnect.initial_backoff_ms;
|
||||
let mut reconnect_max_backoff_ms = defaults.reconnect.max_backoff_ms;
|
||||
let mut resubscribe_text = defaults.resubscribe.clone();
|
||||
let mut command_queue_capacity = defaults.command_queue_capacity;
|
||||
let mut notification_queue_capacity = defaults.notification_queue_capacity;
|
||||
let mut max_active_subscriptions = defaults.max_active_subscriptions;
|
||||
let mut max_pending_requests = defaults.max_pending_requests;
|
||||
let mut max_message_size_bytes = defaults.max_message_size_bytes;
|
||||
let mut max_frame_size_bytes = defaults.max_frame_size_bytes;
|
||||
let mut max_write_buffer_size_bytes = defaults.max_write_buffer_size_bytes;
|
||||
if let std::option::Option::Some(overrides) = overrides {
|
||||
if let std::option::Option::Some(value) = overrides.command_timeout_ms {
|
||||
command_timeout_ms = value;
|
||||
}
|
||||
if let std::option::Option::Some(value) = overrides.close_timeout_ms {
|
||||
close_timeout_ms = value;
|
||||
}
|
||||
if let std::option::Option::Some(reconnect) = overrides.reconnect.as_ref() {
|
||||
if let std::option::Option::Some(value) = reconnect.max_retries {
|
||||
reconnect_max_retries = value;
|
||||
}
|
||||
if let std::option::Option::Some(value) = reconnect.initial_backoff_ms {
|
||||
reconnect_initial_backoff_ms = value;
|
||||
}
|
||||
if let std::option::Option::Some(value) = reconnect.max_backoff_ms {
|
||||
reconnect_max_backoff_ms = value;
|
||||
}
|
||||
}
|
||||
if let std::option::Option::Some(value) = overrides.resubscribe.as_ref() {
|
||||
resubscribe_text = value.clone();
|
||||
}
|
||||
if let std::option::Option::Some(value) = overrides.command_queue_capacity {
|
||||
command_queue_capacity = value;
|
||||
}
|
||||
if let std::option::Option::Some(value) = overrides.notification_queue_capacity {
|
||||
notification_queue_capacity = value;
|
||||
}
|
||||
if let std::option::Option::Some(value) = overrides.max_active_subscriptions {
|
||||
max_active_subscriptions = value;
|
||||
}
|
||||
if let std::option::Option::Some(value) = overrides.max_pending_requests {
|
||||
max_pending_requests = value;
|
||||
}
|
||||
if let std::option::Option::Some(value) = overrides.max_message_size_bytes {
|
||||
max_message_size_bytes = value;
|
||||
}
|
||||
if let std::option::Option::Some(value) = overrides.max_frame_size_bytes {
|
||||
max_frame_size_bytes = value;
|
||||
}
|
||||
if let std::option::Option::Some(value) = overrides.max_write_buffer_size_bytes {
|
||||
max_write_buffer_size_bytes = value;
|
||||
}
|
||||
}
|
||||
let reconnect = ksp_onchain_transport_lib::WsReconnectSettings::new(
|
||||
reconnect_max_retries,
|
||||
std::time::Duration::from_millis(reconnect_initial_backoff_ms),
|
||||
std::time::Duration::from_millis(reconnect_max_backoff_ms),
|
||||
);
|
||||
let resubscribe = map_ws_resubscribe_policy(resubscribe_text.as_str(), profile, endpoint_name);
|
||||
let resubscribe = match resubscribe {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let settings = ksp_onchain_transport_lib::WsSessionSettings::new(
|
||||
std::time::Duration::from_millis(command_timeout_ms),
|
||||
std::time::Duration::from_millis(close_timeout_ms),
|
||||
reconnect,
|
||||
resubscribe,
|
||||
command_queue_capacity,
|
||||
notification_queue_capacity,
|
||||
max_active_subscriptions,
|
||||
max_pending_requests,
|
||||
max_message_size_bytes,
|
||||
max_frame_size_bytes,
|
||||
max_write_buffer_size_bytes,
|
||||
);
|
||||
if let std::result::Result::Err(error) = settings.validate() {
|
||||
return std::result::Result::Err(
|
||||
transport_contract_error(profile, "effective WebSocket session settings fail the Transport runtime contract", &error)
|
||||
.with_context("endpoint_name", endpoint_name),
|
||||
);
|
||||
}
|
||||
return std::result::Result::Ok(settings);
|
||||
}
|
||||
|
||||
fn map_ws_resubscribe_policy(
|
||||
value: &str,
|
||||
profile: &crate::ResolvedConfigProfile,
|
||||
endpoint_name: &str,
|
||||
) -> ksp_core_lib::Result<ksp_onchain_transport_lib::WsResubscribePolicy> {
|
||||
return match value {
|
||||
"never" => std::result::Result::Ok(ksp_onchain_transport_lib::WsResubscribePolicy::Never),
|
||||
"active_subscriptions" => std::result::Result::Ok(ksp_onchain_transport_lib::WsResubscribePolicy::ActiveSubscriptions),
|
||||
_ => std::result::Result::Err(
|
||||
effective_error(profile, "effective WebSocket resubscribe policy is unsupported")
|
||||
.with_context("endpoint_name", endpoint_name)
|
||||
.with_context("resubscribe", value),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
fn map_roles(
|
||||
sources: std::vec::Vec<EffectiveRoleSource>,
|
||||
profile: &crate::ResolvedConfigProfile,
|
||||
|
||||
Reference in New Issue
Block a user