diff --git a/Cargo.lock b/Cargo.lock index 197a57faf..3330108eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -256,7 +256,7 @@ dependencies = [ "addr2line", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.8.9", "object", "rustc-demangle", "windows-link", @@ -303,6 +303,7 @@ dependencies = [ "bd-pgv", "bd-proto", "bd-runtime", + "bd-session", "bd-shutdown", "bd-stats-common", "bd-test-helpers", @@ -1220,9 +1221,11 @@ name = "bd-session" version = "1.0.0" dependencies = [ "anyhow", - "bd-key-value", + "bd-client-common", "bd-log", + "bd-macros", "bd-proto", + "bd-proto-util", "bd-test-helpers", "bd-time", "bd-workspace-hack", @@ -1230,7 +1233,8 @@ dependencies = [ "log", "parking_lot", "pretty_assertions", - "serde", + "protobuf 4.0.0-alpha.0", + "tempfile", "thread_local", "time", "tokio", @@ -1438,7 +1442,7 @@ dependencies = [ "libc", "log", "memchr", - "miniz_oxide", + "miniz_oxide 0.9.1", "once_cell", "protobuf 4.0.0-alpha.0", "quote", @@ -1809,21 +1813,14 @@ dependencies = [ [[package]] name = "ctor" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "400a21f1014a968ec518c7ccdf9b4a4ed0cac8c56ccb6d604f8b91f00110501e" +checksum = "b8f521dd9c9e5f03986eb5c674b14b21e9ccf2eb9f98fecb681100214d5e9e4f" dependencies = [ - "ctor-proc-macro", - "dtor", "link-section", + "linktime-proc-macro", ] -[[package]] -name = "ctor-proc-macro" -version = "0.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a949c44fcacbbbb7ada007dc7acb34603dd97cd47de5d054f2b6493ecebb483" - [[package]] name = "cty" version = "0.2.2" @@ -1954,21 +1951,6 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" -[[package]] -name = "dtor" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96eb86b441d67a711e6e76b410de7135385fec1b8cd304e99d11c56ae542e2fc" -dependencies = [ - "dtor-proc-macro", -] - -[[package]] -name = "dtor-proc-macro" -version = "0.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2647271c92754afcb174e758003cfd1cbf1e43e5a7853d7b1813e63e19e39a73" - [[package]] name = "dunce" version = "1.0.5" @@ -2090,7 +2072,7 @@ dependencies = [ "crc32fast", "libz-ng-sys", "libz-sys", - "miniz_oxide", + "miniz_oxide 0.8.9", ] [[package]] @@ -2327,21 +2309,16 @@ checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "gungraun" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e2e7d17b75a18300d495a5e79970067b92d74e4858c28326e125f2d55b1b566" +checksum = "3bfa183cef2c88324b20de9727befd262c35592d9885ffd93b8b102536a81cf2" dependencies = [ "bincode 1.3.3", - "bindgen", - "cc", - "cfg-if", "cty", "derive_more", "gungraun-macros", "gungraun-runner", - "regex", - "rustc_version", - "strum", + "valgrind-requests", ] [[package]] @@ -2362,9 +2339,9 @@ dependencies = [ [[package]] name = "gungraun-runner" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19bb4c552085f983300b11694022d7584810dca3500c220962ab2353327fb45" +checksum = "2ebdac6d5fe0aa9d9623d690fbfdb759e0ed44115e0685b9abc4568fe47db364" dependencies = [ "serde", ] @@ -2950,9 +2927,15 @@ dependencies = [ [[package]] name = "link-section" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acde40189b7f4b102f876f43a98ec1f5899f96e9a144945d36d9ce0be7f99c7" +checksum = "0567ec9fe5ffdf9241cd90a7629f250a5f903d6ff4573cf7903308662d6fce40" + +[[package]] +name = "linktime-proc-macro" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44cd706ff0d503ee32b2071166510ca27e281228de10cd3aa8d35ff94560f81" [[package]] name = "linux-raw-sys" @@ -3097,6 +3080,16 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "miniz_oxide" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c" +dependencies = [ + "adler2", + "simd-adler32", +] + [[package]] name = "mio" version = "1.2.0" @@ -5269,6 +5262,21 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "valgrind-requests" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4642006c721443df751b1ec49d88094395bef73496d100044ebf61880e291ea9" +dependencies = [ + "bindgen", + "cc", + "cfg-if", + "cty", + "regex", + "rustc_version", + "strum", +] + [[package]] name = "valuable" version = "0.1.1" diff --git a/Cargo.toml b/Cargo.toml index 101bdc8c9..ac50a8ad2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -86,7 +86,7 @@ cmake = "0.1.58" color-backtrace = "0.7.2" concat-string = "1.0.1" crc32fast = "1.5.0" -ctor = "0.11.1" +ctor = "0.12.0" dashmap = "6.1.0" # Pinned due to https://github.com/google/flatbuffers/issues/8876 diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 000000000..c18303df1 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,308 @@ +# State Update Implementation Plan + +## Goal + +Implement the shared-core side of the new client state-update protocol while simplifying session +state ownership. + +The main design decision is: + +- `bd-session` owns durable session state directly using simple local file persistence. +- `Strategy` becomes the central orchestrator for load, mutate, persist, and deferred callback + execution. +- `fixed` and `activity_based` stop owning persistence and instead provide backend-specific state + transition logic. +- `bd-api` owns transport send and ack behavior for `HandshakeRequest.state_update`, + `ApiRequest::StateUpdate`, and `StateUpdateResponse`. + +## Scope + +Included: + +- `bd-session` persistence centralization +- durable started-session upload state +- `bd-api` request and response plumbing for the new protocol messages +- opaque entity rename and update flow on the client side +- test helper and constructor updates in shared-core + +Excluded for this pass: + +- loop-api server implementation +- broad replacement of `bd_key_value` outside of `bd-session` +- unrelated cleanup in other crates + +## Design Summary + +### Session State Ownership + +`bd-session` should stop depending on `bd_key_value::Store`. + +Instead: + +- add a local persistence module in `bd-session` +- persist one current session state file +- persist one pending started-session batch file +- do not add durable in-flight session upload state, since duplicates are acceptable +- keep runtime-only bookkeeping, such as activity write debounce timing, in memory unless restart + semantics require persistence + +### Strategy Structure + +`Strategy` in [bd-session/src/lib.rs](bd-session/src/lib.rs) should no longer be a thin enum +dispatcher. + +It should become the shared orchestration point that: + +1. lazily loads persisted state on first access +2. passes current state into the selected backend provider +3. persists returned state if it changed +4. updates cached in-memory state +5. runs any callbacks after releasing locks + +This keeps all persistence and callback ordering rules in one place. + +### Backend Structure + +The backend modules should be reduced to transition providers: + +- [bd-session/src/fixed.rs](bd-session/src/fixed.rs): fixed session generation and rotation rules +- [bd-session/src/activity_based.rs](bd-session/src/activity_based.rs): inactivity checks, last + activity update, optional rotation + +Each backend should operate on loaded state and return: + +- updated persisted state +- whether persistence is required +- any deferred callback actions to run after persistence succeeds + +### Transport Structure + +`bd-api` should remain responsible for protocol transport: + +- populate `HandshakeRequest.state_update` +- send `ApiRequest::StateUpdate` mid-stream when local state changes +- treat `HandshakeResponse` and `StateUpdateResponse` as atomic ack of the transmitted batch + +The durable source of truth for session-related updates should remain in `bd-session`, not in +`bd-api`. + +## Milestones + +### Milestone 1: Centralize `bd-session` Persistence + +Objective: + +- move all session persistence into `bd-session` +- make `Strategy` the central owner of load, mutate, persist, and callback flow + +Work: + +- add a local persistence module under `bd-session/src` +- define a shared persisted session schema that can represent both backends +- refactor [bd-session/src/lib.rs](bd-session/src/lib.rs) so `Strategy` becomes a struct with an + internal backend enum and owns cached state and persistence +- refactor [bd-session/src/fixed.rs](bd-session/src/fixed.rs) and + [bd-session/src/activity_based.rs](bd-session/src/activity_based.rs) into transition providers +- remove `pub use bd_key_value::Store` from [bd-session/src/lib.rs](bd-session/src/lib.rs) + +Review checkpoint: + +- `Strategy` clearly owns persistence +- backends no longer do file or store IO directly +- lazy initialization and callback-after-unlock behavior are preserved + +Exit criteria: + +- `bd-session` no longer depends on `bd_key_value::Store` +- current semantics for `session_id()`, `start_new_session()`, `flush()`, and + `previous_process_session_id()` remain intact + +### Milestone 2: Add Durable Started-Session Upload State + +Objective: + +- keep started-session updates durable across reconnects and process restart + +Work: + +- add pending batch persistence for started sessions in the same `bd-session` persistence module +- define atomic removal rules for acknowledged session batches without adding durable in-flight + state +- make both fixed and activity-based backends enqueue started-session events through the shared + orchestration layer + +Recommended semantics: + +- on local enqueue: append or merge into the pending batch +- on send: read the current pending snapshot and transmit it without moving it to a second durable + file +- on ack: atomically remove the acknowledged snapshot from the pending file, preserving any newer + appended entries +- on restart or disconnect before ack: resend from the remaining pending file; duplicates are + acceptable + +Review checkpoint: + +- all durable session-related state still has a single owner in `bd-session` +- no per-backend duplication of queue logic exists + +Exit criteria: + +- new sessions from startup, explicit rotation, and inactivity rollover all produce durable + started-session state + +### Milestone 3: Add `bd-api` State Update Transport + +Objective: + +- wire the new protocol messages into the mux client + +Work: + +- update [bd-api/src/api.rs](bd-api/src/api.rs) to populate `HandshakeRequest.state_update` +- add mid-stream `ApiRequest::StateUpdate` sending +- add `Response_type::StateUpdate` handling in response processing +- update [bd-test-helpers/src/test_api_server.rs](bd-test-helpers/src/test_api_server.rs) to + understand `Request_type::StateUpdate` and emit `StateUpdateResponse` + +Review checkpoint: + +- `bd-api` owns transport only +- durable session state still comes from `bd-session` + +Exit criteria: + +- handshake and mid-stream state update messages can be exercised in tests +- atomic batch ack semantics are implemented + +### Milestone 4: Rename Opaque User to Opaque Entity + +Objective: + +- align the client side with the new `opaque_entity_id` protocol shape + +Work: + +- rename `OPAQUE_USER_ID_KEY` to `OPAQUE_ENTITY_ID_KEY` in [bd-api/src/lib.rs](bd-api/src/lib.rs) +- update [bd-api/src/api.rs](bd-api/src/api.rs) to source entity changes from the new naming +- rename logger-facing APIs in [bd-logger/src/logger.rs](bd-logger/src/logger.rs), for example + `register_opaque_entity_id` +- add a clear or unset flow so logout can be expressed +- make live entity changes feed into the new state update transport path +- leave opaque entity persistence otherwise unchanged for this pass + +Review checkpoint: + +- naming is consistent across shared-core +- entity updates can be sent without waiting for reconnect + +Exit criteria: + +- tests cover initial state, update, and clear behavior + +### Milestone 5: Update Constructors and Shared Test Infrastructure + +Objective: + +- migrate shared-core callers to the new `bd-session` shape + +Work: + +- update [logger-cli/src/logger.rs](logger-cli/src/logger.rs) +- update [bd-logger/src/test/setup.rs](bd-logger/src/test/setup.rs) +- update direct session strategy constructions in logger and crash-handler tests +- update any helpers that currently assume `bd_key_value`-backed session state + +Review checkpoint: + +- constructor churn is contained +- no remaining in-workspace `bd-session` callers depend on the old store-based constructors + +Exit criteria: + +- all affected shared-core call sites compile against the new `Strategy` shape + +### Milestone 6: Validation and Cleanup + +Objective: + +- verify the refactor end to end before server-side work begins + +Work: + +- add or update `bd-session` tests for: + - lazy initialization + - previous-process recovery + - fixed strategy startup and explicit rotation + - activity-based rollover and debounce behavior + - callback-after-unlock ordering + - persistence corruption recovery +- add or update `bd-api` tests for: + - handshake includes state update + - mid-stream state update request emission + - `StateUpdateResponse` ack handling + - resend behavior after disconnect without ack +- run validation commands listed below + +Review checkpoint: + +- no hidden ownership split remains between `bd-session` and `bd-api` +- the client-side design is stable enough for server work to start later + +Exit criteria: + +- tests and lint pass for touched crates +- plan is approved for implementation continuation + +## File Targets + +Primary files expected to change: + +- [bd-session/src/lib.rs](bd-session/src/lib.rs) +- [bd-session/src/fixed.rs](bd-session/src/fixed.rs) +- [bd-session/src/activity_based.rs](bd-session/src/activity_based.rs) +- [bd-session/src/fixed_test.rs](bd-session/src/fixed_test.rs) +- [bd-session/src/activity_based_test.rs](bd-session/src/activity_based_test.rs) +- [bd-api/src/lib.rs](bd-api/src/lib.rs) +- [bd-api/src/api.rs](bd-api/src/api.rs) +- [bd-api/src/api_test.rs](bd-api/src/api_test.rs) +- [bd-test-helpers/src/test_api_server.rs](bd-test-helpers/src/test_api_server.rs) +- [bd-logger/src/logger.rs](bd-logger/src/logger.rs) +- [bd-logger/src/test/setup.rs](bd-logger/src/test/setup.rs) +- [logger-cli/src/logger.rs](logger-cli/src/logger.rs) + +Reference patterns: + +- [bd-client-common/src/safe_file_cache.rs](bd-client-common/src/safe_file_cache.rs) +- [bd-client-stats/src/file_manager.rs](bd-client-stats/src/file_manager.rs) + +## Validation + +Run from [shared-core](/Users/mklein/Source/shared-core): + +1. `get_errors` +2. `cargo nextest run -p bd-session` +3. `cargo nextest run -p bd-api` +4. `cargo nextest run -p bd-logger` +5. `cargo nextest run -p bd-crash-handler` if session recovery behavior there changes +6. `cargo clippy -p bd-session --bins --examples --tests -- --no-deps` +7. `cargo clippy -p bd-api --bins --examples --tests -- --no-deps` +8. `cargo clippy -p bd-logger --bins --examples --tests -- --no-deps` when touched +9. `cargo +nightly fmt` +10. `get_errors` + +## Resolved Decisions + +1. Started-session upload durability should use a single pending durable state. Duplicates are not + a concern, so there is no need for durable in-flight tracking. The important requirement is + atomic removal of acknowledged entries. +2. Opaque entity state should stay as-is for now. Do the required rename and protocol plumbing, + but do not restructure its persistence in this pass. +3. `Strategy` should become a struct with an internal backend enum, because that is the cleanest + way to centralize orchestration without layering hacks on top of the current public enum shape. + +## Recommendation + +Start with Milestone 1 and Milestone 2 together. With the simplified queue model, this no longer +requires durable in-flight machinery, so it is the cleanest way to land the persistence shape once +and avoid revisiting `Strategy` orchestration immediately afterward. diff --git a/api b/api index 900d87213..8a53553c1 160000 --- a/api +++ b/api @@ -1 +1 @@ -Subproject commit 900d872139153d3f4d4ee8ac98edc196b737311e +Subproject commit 8a53553c1a8698d7ba968f0430e992a63485ddec diff --git a/bd-api/Cargo.toml b/bd-api/Cargo.toml index 8d39e035a..f14dbf0b1 100644 --- a/bd-api/Cargo.toml +++ b/bd-api/Cargo.toml @@ -24,6 +24,7 @@ bd-network-quality.path = "../bd-network-quality" bd-pgv.path = "../bd-pgv" bd-proto.path = "../bd-proto" bd-runtime.path = "../bd-runtime" +bd-session.path = "../bd-session" bd-shutdown.path = "../bd-shutdown" bd-time.path = "../bd-time" bd-workspace-hack.workspace = true diff --git a/bd-api/src/api.rs b/bd-api/src/api.rs index 2f56bc1fb..1268d0346 100644 --- a/bd-api/src/api.rs +++ b/bd-api/src/api.rs @@ -13,7 +13,6 @@ use crate::network_quality::DISCONNECTED_OFFLINE_GRACE_PERIOD; use crate::upload::{self, StateTracker}; use crate::{ DataUpload, - OPAQUE_USER_ID_KEY, PlatformNetworkManager, PlatformNetworkStream, RuntimeBackoffPolicy, @@ -51,6 +50,7 @@ pub use bd_proto::protos::client::api::sankey_intent_response::{ Drop as SankeyPathUploadDecisionDrop, UploadImmediately as SankeyPathUploadDecisionImmediately, }; +use bd_proto::protos::client::api::state_update_request::OpaqueEntityUpdate; pub use bd_proto::protos::client::api::upload_artifact_intent_response::{ Decision as ArtifactIntentDecision, Drop as ArtifactIntentDecisionDrop, @@ -61,6 +61,7 @@ use bd_proto::protos::client::api::{ ClientKillFile, HandshakeRequest, PingRequest, + StateUpdateRequest, handshake_response, }; use bd_proto::protos::logging::payload::Data as ProtoData; @@ -88,6 +89,14 @@ struct StreamClosureInfo { retry_after: Option, } +// +// InFlightStateUpdate +// + +struct InFlightStateUpdate { + session_update: Option, +} + // // HandshakeResult // @@ -341,7 +350,9 @@ pub struct Api { data_upload_rx: Receiver, trigger_upload_tx: Sender, sleep_mode_active: watch::Receiver, - store: Arc, + session_strategy: Arc, + session_updates: watch::Receiver, + opaque_entity_updates: watch::Receiver>, static_metadata: Arc, @@ -403,6 +414,8 @@ impl Api { stats: &Scope, sleep_mode_active: watch::Receiver, store: Arc, + session_strategy: Arc, + opaque_entity_updates: watch::Receiver>, ) -> Self { let mut backoff_policy = RuntimeBackoffPolicy::new(runtime_loader.as_ref()); let generic_kill_duration = runtime_loader.register_duration_watch(); @@ -414,8 +427,8 @@ impl Api { let backoff = backoff_policy.backoff_mark_update(); - let reconnect_state = - crate::reconnect::ReconnectState::new(store.clone(), time_provider.clone()); + let reconnect_state = crate::reconnect::ReconnectState::new(store, time_provider.clone()); + let session_updates = session_strategy.subscribe_updates(); Self { sdk_directory, api_key, @@ -423,7 +436,9 @@ impl Api { static_metadata, data_upload_rx, trigger_upload_tx, - store, + session_strategy, + session_updates, + opaque_entity_updates, time_provider, network_quality_monitor, runtime_loader, @@ -474,7 +489,7 @@ impl Api { fn handshake_metadata(&self) -> HashMap { let metadata = self.static_metadata.collect(); - let mut handshake_metadata: HashMap<_, _> = metadata + metadata .iter() .map(|(k, v)| { ( @@ -485,21 +500,31 @@ impl Api { }, ) }) - .collect(); - - if let Some(opaque_user_id) = self.store.get_string(&OPAQUE_USER_ID_KEY) - && !opaque_user_id.is_empty() - { - handshake_metadata.insert( - "opaque_user_id".to_string(), - ProtoData { - data_type: Some(Data_type::StringData(opaque_user_id)), - ..Default::default() - }, - ); + .collect() + } + + fn current_opaque_entity_update(&self) -> OpaqueEntityUpdate { + OpaqueEntityUpdate { + opaque_entity_id: self.opaque_entity_updates.borrow().clone(), + ..Default::default() + } + } + + fn state_update_request( + &self, + session_update: Option<&StateUpdateRequest>, + include_opaque_entity: bool, + ) -> Option { + if session_update.is_none() && !include_opaque_entity { + return None; + } + + let mut request = session_update.cloned().unwrap_or_default(); + if include_opaque_entity { + request.opaque_entity_update = Some(self.current_opaque_entity_update()).into(); } - handshake_metadata + Some(request) } fn hash_api_key(&self) -> Vec { @@ -770,13 +795,10 @@ impl Api { log::debug!("sending handshake"); let last_disconnect_reason = self.last_disconnect_reason.take(); - stream_state - .send_request( - self - .handshake_request(handshake_metadata, last_disconnect_reason) - .await, - ) - .await?; + let (handshake_request, handshake_state_update) = self + .handshake_request(handshake_metadata, last_disconnect_reason) + .await; + stream_state.send_request(handshake_request).await?; log::debug!("waiting for handshake"); @@ -788,10 +810,20 @@ impl Api { configuration_update_status, remaining_responses, } => { + self + .session_strategy + .acknowledge_state_update(&handshake_state_update) + .await; stream_state.initialize_stream_settings(stream_settings); + let mut in_flight_state_update = None; + if let Some(stream_closure_info) = self - .handle_responses(remaining_responses, &mut stream_state) + .handle_responses( + remaining_responses, + &mut stream_state, + &mut in_flight_state_update, + ) .await? { if let Some(retry_after) = stream_closure_info.retry_after { @@ -861,6 +893,7 @@ impl Api { // Consider the time we've processed the handshake or the spurious upload as the last // time we received data at the start. This is refreshed below whenever we upload data. let mut last_data_received_at = Instant::now(); + let mut in_flight_state_update = None; // At this point we have established the stream, so we should start the general // request/response handling. @@ -889,6 +922,30 @@ impl Api { log::trace!("sleep mode state changed, re-evaluating data idle timeout"); continue; } + _ = self.session_updates.changed(), if in_flight_state_update.is_none() => { + let _ = self.session_updates.borrow_and_update(); + let Some(session_update) = self.session_strategy.pending_state_update().await else { + continue; + }; + stream_state.send_request(session_update.request().clone()).await?; + in_flight_state_update = Some(InFlightStateUpdate { + session_update: Some(session_update), + }); + self.reconnect_state.record_connectivity_event(); + continue; + } + _ = self.opaque_entity_updates.changed(), if in_flight_state_update.is_none() => { + let _ = self.opaque_entity_updates.borrow_and_update(); + let Some(request) = self.state_update_request(None, true) else { + continue; + }; + stream_state.send_request(request).await?; + in_flight_state_update = Some(InFlightStateUpdate { + session_update: None, + }); + self.reconnect_state.record_connectivity_event(); + continue; + } Some(data_upload) = self.data_upload_rx.recv() => { log::trace!("received data upload"); last_data_received_at = Instant::now(); @@ -919,7 +976,9 @@ impl Api { let stream_closure_info = match stream_state.handle_upstream_event(upstream_event).await? { UpstreamEvent::UpstreamMessages(responses) => { - self.handle_responses(responses, &mut stream_state).await? + self + .handle_responses(responses, &mut stream_state, &mut in_flight_state_update) + .await? }, UpstreamEvent::StreamClosed(reason) => Some(StreamClosureInfo { reason, @@ -974,6 +1033,7 @@ impl Api { &self, responses: Vec, stream_state: &mut StreamState, + in_flight_state_update: &mut Option, ) -> anyhow::Result> { for response in responses { match response.response_type { @@ -1088,6 +1148,16 @@ impl Api { stream_state.send_request(request).await?; } }, + Some(Response_type::StateUpdate(_)) => { + if let Some(in_flight_state_update) = in_flight_state_update.take() + && let Some(session_update) = in_flight_state_update.session_update + { + self + .session_strategy + .acknowledge_state_update(&session_update) + .await; + } + }, None => { debug_assert!(false, "not handled"); }, @@ -1102,20 +1172,24 @@ impl Api { &self, metadata: &HashMap, previous_disconnect_reason: Option, - ) -> HandshakeRequest { + ) -> (HandshakeRequest, bd_session::PendingStateUpdate) { let opaque_client_state = tokio::fs::read(&self.opaque_client_state_path()).await.ok(); + let session_update = self.session_strategy.handshake_state_update().await; let mut handshake = HandshakeRequest { static_device_metadata: metadata.clone(), previous_disconnect_reason: previous_disconnect_reason.unwrap_or_default(), sleep_mode: *self.sleep_mode_active.borrow(), opaque_client_state, + state_update: self + .state_update_request(Some(session_update.request()), true) + .into(), ..Default::default() }; self.config_updater.fill_handshake(&mut handshake); self.runtime_loader.fill_handshake(&mut handshake); - handshake + (handshake, session_update) } async fn process_opaque_client_state(&self, state: Option>) { diff --git a/bd-api/src/api_test.rs b/bd-api/src/api_test.rs index fa4cedda4..a75dbaf73 100644 --- a/bd-api/src/api_test.rs +++ b/bd-api/src/api_test.rs @@ -8,7 +8,7 @@ use super::{Api, PlatformNetworkManager, PlatformNetworkStream}; use crate::api::{DISCONNECTED_OFFLINE_GRACE_PERIOD, StreamEvent}; use crate::upload::Tracked; -use crate::{DataUpload, OPAQUE_USER_ID_KEY, SimpleNetworkQualityProvider}; +use crate::{DataUpload, SimpleNetworkQualityProvider}; use anyhow::anyhow; use assert_matches::assert_matches; use bd_client_common::{ @@ -35,6 +35,7 @@ use bd_proto::protos::client::api::{ HandshakeResponse, RateLimited, RuntimeUpdate, + StateUpdateResponse, StatsUploadRequest, }; use bd_proto::protos::logging::payload::LogType; @@ -179,7 +180,9 @@ struct Setup { api_key: String, network_quality_provider: Arc, sleep_mode_active: watch::Sender, + opaque_entity_updates: watch::Sender>, store: Arc, + session_strategy: Arc, config_updater: Arc, } @@ -207,6 +210,7 @@ impl Setup { let (data_tx, data_rx) = channel(1); let (trigger_upload_tx, _trigger_upload_rx) = channel(1); let (sleep_mode_active_tx, sleep_mode_active_rx) = watch::channel(false); + let (opaque_entity_updates_tx, opaque_entity_updates_rx) = watch::channel(None); let time_provider = Arc::new(bd_time::TestTimeProvider::new(OffsetDateTime::UNIX_EPOCH)); @@ -224,6 +228,10 @@ impl Setup { let network_quality_provider = Arc::new(network_quality_provider.unwrap_or_default()); let store = in_memory_store(); + let session_strategy = Arc::new(bd_session::Strategy::fixed( + sdk_directory.path(), + Arc::new(bd_session::fixed::UUIDCallbacks), + )); let mut api = Api::new( sdk_directory.path().to_path_buf(), api_key.clone(), @@ -239,6 +247,8 @@ impl Setup { &collector.scope("api"), sleep_mode_active_rx, store.clone(), + session_strategy.clone(), + opaque_entity_updates_rx, ); api.data_idle_timeout_test_hook = idle_timeout_tx; @@ -263,7 +273,9 @@ impl Setup { api_key, network_quality_provider, sleep_mode_active: sleep_mode_active_tx, + opaque_entity_updates: opaque_entity_updates_tx, store, + session_strategy, config_updater, } } @@ -298,6 +310,8 @@ impl Setup { &self.collector.scope("api"), self.sleep_mode_active.subscribe(), self.store.clone(), + self.session_strategy.clone(), + self.opaque_entity_updates.subscribe(), ); self.api_task = Some(tokio::task::spawn(api.start())); @@ -361,6 +375,21 @@ impl Setup { .await; } + async fn state_update_response(&self) { + self + .send_response(ApiResponse { + response_type: Some(Response_type::StateUpdate(StateUpdateResponse::default())), + ..Default::default() + }) + .await; + } + + fn set_opaque_entity_id(&self, opaque_entity_id: Option<&str>) { + self + .opaque_entity_updates + .send_replace(opaque_entity_id.map(str::to_string)); + } + async fn send_request(&self, data: DataUpload) { self.data_tx.send(data).await.unwrap(); } @@ -429,6 +458,34 @@ impl Setup { Some(request) } + #[must_use] + async fn next_stream_allowing_state_updates( + &mut self, + wait: Duration, + ) -> Option { + tokio::select! { + _ = self.start_stream_rx.recv() => {}, + () = wait.sleep() => { + return None; + } + }; + + let deadline = Instant::now() + wait.unsigned_abs(); + loop { + let remaining = deadline.saturating_duration_since(Instant::now()); + let data = timeout(remaining, self.send_data_rx.recv()) + .await + .ok() + .flatten()?; + let request = self.decode(&data).unwrap(); + match request.request_type { + Some(Request_type::Handshake(request)) => return Some(request), + Some(Request_type::StateUpdate(_)) => {}, + _ => panic!("expected handshake request, got {request:?}"), + } + } + } + fn decode(&mut self, data: &[u8]) -> Option { if let Ok(requests) = self.requests_decoder.decode_data(data) { assert!( @@ -1424,42 +1481,153 @@ async fn opaque_client_state() { } #[tokio::test(start_paused = true)] -async fn handshake_includes_opaque_user_id_from_store() { +async fn handshake_includes_opaque_entity_and_current_session() { let mut setup = Setup::new().await; - setup.store.set_string(&OPAQUE_USER_ID_KEY, "hashed-user-1"); + setup.set_opaque_entity_id(Some("hashed-entity-1")); let handshake = setup.next_stream(1.seconds()).await.unwrap(); - let opaque_user_id = handshake - .static_device_metadata - .get("opaque_user_id") - .unwrap() - .string_data(); - assert_eq!(opaque_user_id, "hashed-user-1"); + let state_update = handshake.state_update.as_ref().unwrap(); + + assert_eq!( + Some("hashed-entity-1"), + state_update + .opaque_entity_update + .as_ref() + .unwrap() + .opaque_entity_id + .as_deref() + ); + assert_eq!(1, state_update.started_sessions.len()); + assert_eq!( + setup.session_strategy.session_id().await.unwrap(), + state_update.started_sessions[0].session_id + ); } #[tokio::test(start_paused = true)] -async fn reconnect_handshake_picks_up_updated_opaque_user_id() { +async fn reconnect_handshake_picks_up_updated_opaque_entity_id() { let mut setup = Setup::new().await; let handshake = setup.next_stream(1.seconds()).await.unwrap(); assert!( - !handshake - .static_device_metadata - .contains_key("opaque_user_id") + handshake + .state_update + .as_ref() + .unwrap() + .opaque_entity_update + .as_ref() + .unwrap() + .opaque_entity_id + .is_none() ); setup .handshake_response(HANDSHAKE_FLAG_CONFIG_UP_TO_DATE, None, None) .await; - setup.store.set_string(&OPAQUE_USER_ID_KEY, "hashed-user-2"); + setup.set_opaque_entity_id(Some("hashed-entity-2")); setup.close_stream().await; + // The old stream can enqueue a final opaque-entity state update before the close is observed. + // The reconnect assertion is about the handshake built for the new stream, so skip any + // intervening state-update frame and inspect the next handshake request. + let reconnect_handshake = setup + .next_stream_allowing_state_updates(2.seconds()) + .await + .unwrap(); + assert_eq!( + Some("hashed-entity-2"), + reconnect_handshake + .state_update + .as_ref() + .unwrap() + .opaque_entity_update + .as_ref() + .unwrap() + .opaque_entity_id + .as_deref() + ); +} + +#[tokio::test(start_paused = true)] +async fn midstream_opaque_entity_updates_are_sent() { + let mut setup = Setup::new().await; + + setup.next_stream(1.seconds()).await.unwrap(); + setup + .handshake_response(HANDSHAKE_FLAG_CONFIG_UP_TO_DATE, None, None) + .await; + + setup.set_opaque_entity_id(Some("hashed-entity-3")); + let request = setup.next_request(1.seconds()).await.unwrap(); + let Some(Request_type::StateUpdate(state_update)) = request.request_type else { + panic!("expected state update request, got {request:?}"); + }; + + assert_eq!( + Some("hashed-entity-3"), + state_update + .opaque_entity_update + .as_ref() + .unwrap() + .opaque_entity_id + .as_deref() + ); + assert!(state_update.started_sessions.is_empty()); + + setup.state_update_response().await; + setup.set_opaque_entity_id(None); + let request = setup.next_request(1.seconds()).await.unwrap(); + let Some(Request_type::StateUpdate(state_update)) = request.request_type else { + panic!("expected state update request, got {request:?}"); + }; + + assert!( + state_update + .opaque_entity_update + .as_ref() + .unwrap() + .opaque_entity_id + .is_none() + ); +} + +#[tokio::test(start_paused = true)] +async fn session_state_update_is_resent_until_acked() { + let mut setup = Setup::new().await; + + let handshake = setup.next_stream(1.seconds()).await.unwrap(); + let initial_session_id = handshake.state_update.as_ref().unwrap().started_sessions[0] + .session_id + .clone(); + setup + .handshake_response(HANDSHAKE_FLAG_CONFIG_UP_TO_DATE, None, None) + .await; + + setup.session_strategy.start_new_session().await; + let next_session_id = setup.session_strategy.session_id().await.unwrap(); + + let request = setup.next_request(1.seconds()).await.unwrap(); + let Some(Request_type::StateUpdate(state_update)) = request.request_type else { + panic!("expected state update request, got {request:?}"); + }; + + assert_eq!(1, state_update.started_sessions.len()); + assert_eq!(next_session_id, state_update.started_sessions[0].session_id); + + setup.close_stream().await; let reconnect_handshake = setup.next_stream(2.seconds()).await.unwrap(); - let opaque_user_id = reconnect_handshake - .static_device_metadata - .get("opaque_user_id") + let reconnect_started_sessions = &reconnect_handshake + .state_update + .as_ref() .unwrap() - .string_data(); - assert_eq!(opaque_user_id, "hashed-user-2"); + .started_sessions; + assert_eq!(1, reconnect_started_sessions.len()); + assert_eq!(next_session_id, reconnect_started_sessions[0].session_id); + assert_ne!(initial_session_id, reconnect_started_sessions[0].session_id); + + setup + .handshake_response(HANDSHAKE_FLAG_CONFIG_UP_TO_DATE, None, None) + .await; + setup.state_update_response().await; } diff --git a/bd-api/src/lib.rs b/bd-api/src/lib.rs index a4de212d7..830be752d 100644 --- a/bd-api/src/lib.rs +++ b/bd-api/src/lib.rs @@ -41,9 +41,6 @@ mod network_quality; mod reconnect; pub mod upload; -pub static OPAQUE_USER_ID_KEY: bd_key_value::Key = - bd_key_value::Key::new("opaque_user_id.state.1"); - pub use bd_metadata::{Metadata, Platform}; #[cfg(test)] diff --git a/bd-client-common/src/file_system.rs b/bd-client-common/src/file_system.rs index bac094e07..8a4c7ccf7 100644 --- a/bd-client-common/src/file_system.rs +++ b/bd-client-common/src/file_system.rs @@ -38,6 +38,36 @@ pub trait FileSystem: Send + Sync { async fn create_dir(&self, path: &Path) -> anyhow::Result<()>; } +/// Writes a file through a sibling temporary path so readers never observe a partial write. +pub async fn write_file_atomic(path: &Path, data: &[u8]) -> anyhow::Result<()> { + if let Some(parent) = path.parent() { + tokio::fs::create_dir_all(parent).await?; + } + + let tmp_path = path.with_extension("tmp"); + tokio::fs::write(&tmp_path, data).await?; + tokio::fs::rename(&tmp_path, path).await?; + Ok(()) +} + +/// Delete a file if it exists, treating a not found error as success. +pub async fn delete_file_if_exists_async(path: &Path) -> anyhow::Result<()> { + match tokio::fs::remove_file(path).await { + Ok(()) => Ok(()), + Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()), + Err(e) => Err(e.into()), + } +} + +/// Delete a directory tree while treating an absent directory as success. +pub async fn remove_dir_if_exists_async(path: &Path) -> anyhow::Result<()> { + match tokio::fs::remove_dir_all(path).await { + Ok(()) => Ok(()), + Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()), + Err(e) => Err(e.into()), + } +} + // // RealFileSystem // @@ -94,11 +124,7 @@ impl FileSystem for RealFileSystem { } async fn delete_file(&self, path: &Path) -> anyhow::Result<()> { - match tokio::fs::remove_file(self.directory.join(path)).await { - Ok(()) => Ok(()), - Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()), - Err(e) => Err(e.into()), - } + delete_file_if_exists_async(&self.directory.join(path)).await } async fn rename_file(&self, from: &Path, to: &Path) -> anyhow::Result<()> { @@ -106,11 +132,7 @@ impl FileSystem for RealFileSystem { } async fn remove_dir(&self, path: &Path) -> anyhow::Result<()> { - match tokio::fs::remove_dir_all(self.directory.join(path)).await { - Ok(()) => Ok(()), - Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()), - Err(e) => Err(e.into()), - } + remove_dir_if_exists_async(&self.directory.join(path)).await } async fn create_dir(&self, path: &Path) -> anyhow::Result<()> { diff --git a/bd-client-common/src/payload_conversion.rs b/bd-client-common/src/payload_conversion.rs index 819a24a25..33e7e2697 100644 --- a/bd-client-common/src/payload_conversion.rs +++ b/bd-client-common/src/payload_conversion.rs @@ -25,6 +25,7 @@ use bd_proto::protos::client::api::{ PingRequest, SankeyIntentRequest, SankeyPathUploadRequest, + StateUpdateRequest, StatsUploadRequest, UploadArtifactIntentRequest, UploadArtifactRequest, @@ -68,6 +69,7 @@ into_api_request!(HandshakeRequest, Request_type::Handshake); into_api_request!(LogUploadIntentRequest, Request_type::LogUploadIntent); into_api_request!(SankeyIntentRequest, Request_type::SankeyIntent); into_api_request!(SankeyPathUploadRequest, Request_type::SankeyPathUpload); +into_api_request!(StateUpdateRequest, Request_type::StateUpdate); into_api_request!(UploadArtifactRequest, Request_type::ArtifactUpload); into_api_request!(UploadArtifactIntentRequest, Request_type::ArtifactIntent); into_api_request!(DebugDataRequest, Request_type::DebugData); diff --git a/bd-crash-handler/src/lib.rs b/bd-crash-handler/src/lib.rs index b62624f0f..fcfb21172 100644 --- a/bd-crash-handler/src/lib.rs +++ b/bd-crash-handler/src/lib.rs @@ -457,13 +457,15 @@ impl Monitor { } } - fn get_session_id(&self, origin: ReportOrigin) -> String { + async fn get_session_id(&self, origin: ReportOrigin) -> anyhow::Result { match origin { - ReportOrigin::Current => self.session.session_id(), - ReportOrigin::Previous => self - .session - .previous_process_session_id() - .unwrap_or_default(), + ReportOrigin::Current => self.session.session_id().await, + ReportOrigin::Previous => Ok( + self + .session + .previous_process_session_id() + .unwrap_or_default(), + ), } } @@ -542,7 +544,10 @@ impl Monitor { let reporting_feature_flags = self.get_feature_flags(origin).await; let global_state_fields = self.get_global_state_fields(origin); - let session_id = self.get_session_id(origin); + let session_id = self + .get_session_id(origin) + .await + .unwrap_or_else(|_| "unknown".to_string()); let (timestamp, state_fields) = Self::read_log_fields(bin_report, &global_state_fields); self.invoke_crash_hook( diff --git a/bd-crash-handler/src/monitor_test.rs b/bd-crash-handler/src/monitor_test.rs index d2e9e3712..7afc3ac02 100644 --- a/bd-crash-handler/src/monitor_test.rs +++ b/bd-crash-handler/src/monitor_test.rs @@ -213,16 +213,13 @@ impl Setup { // Set up the session to return a fixed previous session ID, making it obvious that we are // using the previous session ID for uploads. - let mut session = bd_session::Strategy::Fixed(bd_session::fixed::Strategy::new( - store.clone(), + let mut session = bd_session::Strategy::fixed( + directory.path(), Arc::new(StaticSession("previous_session_id".into())), - )); - assert_eq!(session.session_id(), "previous_session_id"); + ); + assert_eq!(session.session_id().await.unwrap(), "previous_session_id"); - session = bd_session::Strategy::Fixed(bd_session::fixed::Strategy::new( - store.clone(), - Arc::new(UUIDCallbacks), - )); + session = bd_session::Strategy::fixed(directory.path(), Arc::new(UUIDCallbacks)); let (tx, rx) = tokio::sync::mpsc::channel(10); let emit_log = @@ -634,7 +631,7 @@ async fn file_watcher_detects_current_session_report() { ] .into(), crash_timestamp.into(), - setup.monitor.session.session_id().as_str(), + setup.monitor.session.session_id().await.unwrap().as_str(), Some(vec![ ("initial_flag".to_string(), "true".to_string()), ("previous_only_flag".to_string(), "enabled".to_string()), @@ -926,7 +923,7 @@ async fn current_session_crash_uses_current_feature_flags() { ] .into(), crash_timestamp.into(), - setup.monitor.session.session_id().as_str(), + setup.monitor.session.session_id().await.unwrap().as_str(), Some(vec![ ("initial_flag".to_string(), "updated".to_string()), ("current_only_flag".to_string(), "new".to_string()), diff --git a/bd-error-reporter/src/reporter.rs b/bd-error-reporter/src/reporter.rs index 840a03890..4e711bd0c 100644 --- a/bd-error-reporter/src/reporter.rs +++ b/bd-error-reporter/src/reporter.rs @@ -35,7 +35,7 @@ pub trait Reporter: Send + Sync { // pub trait SessionProvider { - fn session_id(&self) -> String; + fn session_id(&self) -> anyhow::Result; } // @@ -71,7 +71,10 @@ impl Reporter for MetadataErrorReporter { ) { let mut headers = headers.clone(); - let session_id = self.session_strategy.session_id(); + let session_id = self + .session_strategy + .session_id() + .unwrap_or_else(|_| "unknown".to_string()); headers.insert("x-session-id".into(), session_id.into()); for (key, value) in self.metadata.collect() { diff --git a/bd-error-reporter/src/reporter_test.rs b/bd-error-reporter/src/reporter_test.rs index e2f4f5b67..d669027ba 100644 --- a/bd-error-reporter/src/reporter_test.rs +++ b/bd-error-reporter/src/reporter_test.rs @@ -80,8 +80,8 @@ impl MockSessionProvider { } impl SessionProvider for MockSessionProvider { - fn session_id(&self) -> String { - self.session_id.clone() + fn session_id(&self) -> anyhow::Result { + Ok(self.session_id.clone()) } } @@ -113,7 +113,10 @@ fn attach_error_handler() { assert_eq!( HashMap::from([ - ("x-session-id".to_string(), session_strategy.session_id()), + ( + "x-session-id".to_string(), + session_strategy.session_id().unwrap(), + ), ("x-sdk-version".to_string(), "1.2.3".to_string()), ("x-platform".to_string(), "apple".to_string()), ("x-os".to_string(), "ios".to_string()), diff --git a/bd-logger/src/async_log_buffer.rs b/bd-logger/src/async_log_buffer.rs index 0a83a3f73..c19390476 100644 --- a/bd-logger/src/async_log_buffer.rs +++ b/bd-logger/src/async_log_buffer.rs @@ -50,7 +50,7 @@ use bd_proto::protos::logging::payload::LogType; use bd_runtime::runtime::ConfigLoader; use bd_session_replay::CaptureScreenshotHandler; use bd_shutdown::{ComponentShutdown, ComponentShutdownTrigger, ComponentShutdownTriggerHandle}; -use bd_state::{SYSTEM_SESSION_ID_KEY, Scope, string_value}; +use bd_state::{ENTITY_ID_KEY, SYSTEM_SESSION_ID_KEY, Scope, string_value}; use bd_stats_common::workflow::{WorkflowDebugStateKey, WorkflowDebugTransitionType}; use bd_time::{OffsetDateTimeExt, TimeDurationExt, TimeProvider}; use bd_workflows::workflow::WorkflowDebugStateMap; @@ -91,6 +91,9 @@ pub enum StateUpdateMessage { AddLogField(String, DataValue), RemoveLogField(String), SetFeatureFlagExposure(String, Option), + SetEntityId(Option), + RequestSessionId(bd_completion::Sender>), + StartNewSession(bd_completion::Sender<()>), FlushState(Option>), } @@ -103,6 +106,9 @@ impl MemorySized for StateUpdateMessage { Self::SetFeatureFlagExposure(flag, variant) => { flag.len() + variant.as_ref().map_or(0, String::len) }, + Self::SetEntityId(entity_id) => entity_id.as_ref().map_or(0, String::len), + Self::RequestSessionId(response_tx) => size_of_val(response_tx), + Self::StartNewSession(response_tx) => size_of_val(response_tx), Self::FlushState(sender) => size_of_val(sender), } } @@ -290,6 +296,23 @@ impl Sender { } Ok(()) } + + pub fn request_session_id(&self) -> anyhow::Result { + let (response_tx, response_rx) = bd_completion::Sender::new(); + self.try_send_state_update(StateUpdateMessage::RequestSessionId(response_tx))?; + + response_rx + .blocking_recv() + .map_err(|e| anyhow!("failed to receive session ID from async logger: {e}"))? + } + + pub fn request_start_new_session(&self) -> anyhow::Result<()> { + let (response_tx, response_rx) = bd_completion::Sender::new(); + self.try_send_state_update(StateUpdateMessage::StartNewSession(response_tx))?; + response_rx + .blocking_recv() + .map_err(|e| anyhow!("failed to receive start-new-session ack from async logger: {e}")) + } } pub type AsyncLogBufferOrderedReceiver = OrderedReceiver; @@ -621,11 +644,12 @@ impl AsyncLogBuffer { let (session_id, timestamp, extra_fields) = match log.attributes_overrides { Some(LogAttributesOverrides::PreviousRunSessionID(occurred_at)) => { // Use the previous session ID if available and the provided timestamp. + let session_id = match self.session_strategy.previous_process_session_id() { + Some(session_id) => session_id, + None => self.session_strategy.session_id().await?, + }; ( - self - .session_strategy - .previous_process_session_id() - .unwrap_or_else(|| self.session_strategy.session_id()), + session_id, occurred_at, Some(LogFields::from([( "_logged_at".into(), @@ -636,7 +660,7 @@ impl AsyncLogBuffer { Some(LogAttributesOverrides::OccurredAt(overridden_timestamp)) => { // Occurred at override provided. Emit log with overrides applied. ( - self.session_strategy.session_id(), + self.session_strategy.session_id().await?, overridden_timestamp, Some(LogFields::from([( "_logged_at".into(), @@ -646,7 +670,11 @@ impl AsyncLogBuffer { }, None => { // No overrides provided. Emit log without any overrides. - (self.session_strategy.session_id(), metadata.timestamp, None) + ( + self.session_strategy.session_id().await?, + metadata.timestamp, + None, + ) }, }; @@ -965,7 +993,16 @@ impl AsyncLogBuffer { self.metadata_collector.remove_field(&field_name); }, StateUpdateMessage::SetFeatureFlagExposure(flag, variant) => { - let session_id = self.session_strategy.session_id(); + let session_id = match self.session_strategy.session_id().await { + Ok(session_id) => session_id, + Err(e) => { + log::debug!( + "failed to record feature flag exposure because session ID resolution \ + failed: {e}" + ); + continue; + }, + }; if let LoggingState::Initialized(initialized_logging_context) = &mut self.logging_state { @@ -1007,6 +1044,28 @@ impl AsyncLogBuffer { } } }, + StateUpdateMessage::SetEntityId(entity_id) => { + let result = match entity_id { + Some(entity_id) => { + state_store + .insert(Scope::System, ENTITY_ID_KEY.to_string(), string_value(entity_id)) + .await + .map(|_| ()) + }, + None => state_store.remove(Scope::System, ENTITY_ID_KEY).await.map(|_| ()), + }; + + if let Err(e) = result { + log::debug!("failed to persist entity ID state: {e}"); + } + }, + StateUpdateMessage::RequestSessionId(response_tx) => { + response_tx.send(self.session_strategy.session_id().await); + }, + StateUpdateMessage::StartNewSession(response_tx) => { + self.session_strategy.start_new_session().await; + response_tx.send(()); + }, StateUpdateMessage::FlushState(completion_tx) => { let flush_stats_trigger = self.logging_state.flush_stats_trigger().clone(); let flush_stats = async move { @@ -1039,13 +1098,9 @@ impl AsyncLogBuffer { } }; - // TODO(mattklein123): We need the store interfaces to be async so that this - // flush can be async also. For now we do spawn blocking. let session_strategy = self.session_strategy.clone(); let flush_session = async { - let _ = tokio::task::spawn_blocking(move || { - session_strategy.flush(); - }).await; + session_strategy.flush().await; }; let persist_workflows = async { diff --git a/bd-logger/src/async_log_buffer_test.rs b/bd-logger/src/async_log_buffer_test.rs index f88a7dbd3..40e19c358 100644 --- a/bd-logger/src/async_log_buffer_test.rs +++ b/bd-logger/src/async_log_buffer_test.rs @@ -31,8 +31,8 @@ use bd_proto::protos::config::v1::config::BufferConfigList; use bd_proto::protos::filter::filter::FiltersConfiguration; use bd_proto::protos::logging::payload::LogType; use bd_runtime::runtime::{ConfigLoader, FeatureFlag}; +use bd_session::Strategy; use bd_session::fixed::UUIDCallbacks; -use bd_session::{Strategy, fixed}; use bd_shutdown::ComponentShutdownTrigger; use bd_state::test::TestStore; use bd_state::{SYSTEM_SESSION_ID_KEY, Scope, StateReader}; @@ -78,11 +78,7 @@ impl Setup { let collector = Collector::default(); let stats = Stats::new(collector.clone()); let (data_upload_tx, data_upload_rx) = mpsc::channel(1); - - let session_strategy = Arc::new(Strategy::Fixed(fixed::Strategy::new( - in_memory_store(), - Arc::new(UUIDCallbacks), - ))); + let session_strategy = Arc::new(Strategy::fixed(tmp_dir.path(), Arc::new(UUIDCallbacks))); Self { buffer_manager: bd_buffer::Manager::new( @@ -734,7 +730,7 @@ async fn updates_system_session_id_for_new_sessions() { let handle = tokio::task::spawn(buffer.run_with_shutdown(state_store, (), shutdown_trigger.make_shutdown())); - let first_session_id = setup.session_strategy.session_id(); + let first_session_id = setup.session_strategy.session_id().await.unwrap(); assert_ok!(AsyncLogBuffer::::enqueue_log( &sender, 0, @@ -747,8 +743,8 @@ async fn updates_system_session_id_for_new_sessions() { None, )); - setup.session_strategy.start_new_session(); - let second_session_id = setup.session_strategy.session_id(); + setup.session_strategy.start_new_session().await; + let second_session_id = setup.session_strategy.session_id().await.unwrap(); assert_ne!(first_session_id, second_session_id); assert_ok!(AsyncLogBuffer::::enqueue_log( @@ -797,7 +793,7 @@ async fn previous_run_log_does_not_override_system_session_id() { let handle = tokio::task::spawn(buffer.run_with_shutdown(state_store, (), shutdown_trigger.make_shutdown())); - let current_session_id = setup.session_strategy.session_id(); + let current_session_id = setup.session_strategy.session_id().await.unwrap(); assert_ok!(AsyncLogBuffer::::enqueue_log( &sender, 0, @@ -810,8 +806,8 @@ async fn previous_run_log_does_not_override_system_session_id() { None, )); - setup.session_strategy.start_new_session(); - let next_session_id = setup.session_strategy.session_id(); + setup.session_strategy.start_new_session().await; + let next_session_id = setup.session_strategy.session_id().await.unwrap(); assert_ne!(current_session_id, next_session_id); let log = LogLine { @@ -856,7 +852,7 @@ async fn pre_config_logs_trigger_session_id_update() { let state_store = (*test_store).clone(); let shutdown_trigger = ComponentShutdownTrigger::default(); - let first_session_id = setup.session_strategy.session_id(); + let first_session_id = setup.session_strategy.session_id().await.unwrap(); assert_ok!(AsyncLogBuffer::::enqueue_log( &sender, 0, @@ -869,8 +865,8 @@ async fn pre_config_logs_trigger_session_id_update() { None, )); - setup.session_strategy.start_new_session(); - let second_session_id = setup.session_strategy.session_id(); + setup.session_strategy.start_new_session().await; + let second_session_id = setup.session_strategy.session_id().await.unwrap(); assert_ne!(first_session_id, second_session_id); assert_ok!(AsyncLogBuffer::::enqueue_log( diff --git a/bd-logger/src/builder.rs b/bd-logger/src/builder.rs index bb4c1b9c1..a6f69d83a 100644 --- a/bd-logger/src/builder.rs +++ b/bd-logger/src/builder.rs @@ -35,8 +35,10 @@ use bd_runtime::runtime::network_quality::NetworkCallOnlineIndicatorTimeout; use bd_runtime::runtime::stats::{DirectStatFlushIntervalFlag, UploadStatFlushIntervalFlag}; use bd_runtime::runtime::{self, ConfigLoader, Watch, sleep_mode}; use bd_shutdown::{ComponentShutdownTrigger, ComponentShutdownTriggerHandle}; +use bd_state::{ENTITY_ID_KEY, Scope as StateScope, StateReader, Value_type}; use bd_time::{SystemTimeProvider, Ticker, TimeProvider}; use futures_util::{Future, try_join}; +use parking_lot::Mutex; use std::pin::Pin; use std::sync::Arc; use std::sync::atomic::AtomicBool; @@ -261,6 +263,8 @@ impl LoggerBuilder { let data_upload_tx_clone = data_upload_tx.clone(); let collector_clone = collector; + let (opaque_entity_updates_tx, opaque_entity_updates_rx) = watch::channel(None); + let pending_entity_id = Arc::new(Mutex::new(None)); let logger = Logger::new( maybe_shutdown_trigger, @@ -272,6 +276,8 @@ impl LoggerBuilder { self.params.device, self.params.static_metadata.sdk_version(), self.params.store.clone(), + opaque_entity_updates_tx.clone(), + pending_entity_id.clone(), sleep_mode_active_tx, is_tracing_active, ); @@ -328,6 +334,27 @@ impl LoggerBuilder { result.retention_registry, ); + // Preserve pre-start entity ID updates from the public logger handle. If nothing updated the + // watch channel yet, seed it from the persisted bd-state value before the API starts. + let pending_entity_id = pending_entity_id.lock().take(); + if pending_entity_id.is_none() { + let initial_opaque_entity_id = { + let reader = state_store.read().await; + reader + .get(StateScope::System, ENTITY_ID_KEY) + .and_then(|value| { + let Value_type::StringValue(entity_id) = value.value_type.as_ref()? else { + return None; + }; + + (!entity_id.is_empty()).then(|| entity_id.clone()) + }) + }; + if let Some(initial_opaque_entity_id) = initial_opaque_entity_id { + opaque_entity_updates_tx.send_replace(Some(initial_opaque_entity_id)); + } + } + if result.fallback_occurred { handle_unexpected( Err::<(), anyhow::Error>(anyhow::anyhow!( @@ -444,6 +471,8 @@ impl LoggerBuilder { &scope.scope("api"), sleep_mode_active_rx, self.params.store.clone(), + self.params.session_strategy.clone(), + opaque_entity_updates_rx, ); let mut config_writer = bd_crash_handler::ConfigWriter::new( diff --git a/bd-logger/src/logger.rs b/bd-logger/src/logger.rs index 2b82c9e93..a765ad9ec 100644 --- a/bd-logger/src/logger.rs +++ b/bd-logger/src/logger.rs @@ -13,7 +13,7 @@ use crate::app_version::{AppVersion, Repository}; use crate::async_log_buffer::{self, AsyncLogBuffer, LogAttributesOverrides}; use crate::log_replay::LoggerReplay; use crate::{MetadataProvider, app_version}; -use bd_api::{Metadata, OPAQUE_USER_ID_KEY}; +use bd_api::Metadata; use bd_bounded_buffer::{self}; use bd_client_stats_store::{Counter, Scope}; use bd_log::warn_every; @@ -176,6 +176,12 @@ impl CaptureSession { } } +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum PendingEntityIdUpdate { + Set(String), + Clear, +} + /// A handle to the logger that can be used to log messages. This is the primary interface for /// submitting logs into the system. pub struct LoggerHandle { @@ -186,7 +192,8 @@ pub struct LoggerHandle { sdk_version: String, app_version_repo: app_version::Repository, - store: Arc, + opaque_entity_updates: watch::Sender>, + pending_entity_id: Arc>>, stats: Stats, @@ -268,8 +275,25 @@ impl LoggerHandle { }); } - pub fn register_opaque_user_id(&self, opaque_user_id: &str) { - self.store.set_string(&OPAQUE_USER_ID_KEY, opaque_user_id); + pub fn register_opaque_entity_id(&self, opaque_entity_id: Option<&str>) { + let opaque_entity_id = opaque_entity_id.map(str::to_string); + *self.pending_entity_id.lock() = Some( + opaque_entity_id + .clone() + .map_or(PendingEntityIdUpdate::Clear, PendingEntityIdUpdate::Set), + ); + + if let Err(e) = + self + .tx + .try_send_state_update(async_log_buffer::StateUpdateMessage::SetEntityId( + opaque_entity_id.clone(), + )) + { + log::debug!("failed to persist entity ID state: {e:?}"); + } + + self.opaque_entity_updates.send_replace(opaque_entity_id); } #[must_use] @@ -475,22 +499,20 @@ impl LoggerHandle { self.stats.state_flushing_counters.record(&result); } - #[must_use] - pub fn session_id(&self) -> String { - self.session_strategy.session_id() + pub fn session_id(&self) -> anyhow::Result { + self.tx.request_session_id() } - pub fn start_new_session(&self) { - LOGGER_GUARD.with(|cell| { - if cell.try_borrow().is_ok() { - self.session_strategy.start_new_session(); - } else { - log::warn!( - "failed to start a new session, the operation is not allowed from within a field \ - provider" - ); - } - }); + pub fn start_new_session(&self) -> anyhow::Result<()> { + let is_allowed = LOGGER_GUARD.with(|cell| cell.try_borrow().is_ok()); + + if is_allowed { + self.tx.request_start_new_session() + } else { + Err(anyhow::anyhow!( + "operation not allowed from within a field provider" + )) + } } #[must_use] @@ -552,6 +574,8 @@ pub struct Logger { sdk_version: String, store: Arc, + opaque_entity_updates: watch::Sender>, + pending_entity_id: Arc>>, pub(crate) stats: Stats, @@ -562,7 +586,7 @@ pub struct Logger { } impl Logger { - pub fn new( + pub(crate) fn new( shutdown_state: Option, runtime_loader: Arc, stats_scope: Scope, @@ -572,6 +596,8 @@ impl Logger { device: Arc, sdk_version: &str, store: Arc, + opaque_entity_updates: watch::Sender>, + pending_entity_id: Arc>>, sleep_mode_active: watch::Sender, is_tracing_active: Arc, ) -> Self { @@ -591,6 +617,8 @@ impl Logger { stats, stats_scope, store, + opaque_entity_updates, + pending_entity_id, sleep_mode_active, is_tracing_active, } @@ -645,7 +673,8 @@ impl Logger { device: self.device.clone(), sdk_version: self.sdk_version.clone(), app_version_repo: Repository::new(self.store.clone()), - store: self.store.clone(), + opaque_entity_updates: self.opaque_entity_updates.clone(), + pending_entity_id: self.pending_entity_id.clone(), stats: self.stats.clone(), sleep_mode_active: self.sleep_mode_active.clone(), is_tracing_active: self.is_tracing_active.clone(), diff --git a/bd-logger/src/logger_test.rs b/bd-logger/src/logger_test.rs index f817eaa94..3794f61fd 100644 --- a/bd-logger/src/logger_test.rs +++ b/bd-logger/src/logger_test.rs @@ -9,16 +9,16 @@ use super::{Stats, with_thread_local_logger_guard}; use crate::app_version::Repository; use crate::logger::{Block, CaptureSession}; use crate::{LoggerHandle, async_log_buffer}; -use bd_api::OPAQUE_USER_ID_KEY; use bd_client_stats_store::Collector; use bd_log_primitives::log_level; use bd_proto::protos::logging::payload::LogType; use bd_session::Strategy; -use bd_session::fixed::{self, UUIDCallbacks}; +use bd_session::fixed::UUIDCallbacks; use bd_test_helpers::session::in_memory_store; use futures_util::poll; use std::sync::Arc; use std::sync::atomic::AtomicBool; +use tempfile::TempDir; use tokio::pin; use tokio::sync::watch; use tokio_test::assert_pending; @@ -29,18 +29,20 @@ async fn thread_local_logger_guard() { let (state_tx, _state_rx) = bd_bounded_buffer::channel(100); let sender = async_log_buffer::Sender::from_parts(log_tx, state_tx); + let sdk_directory = TempDir::new().unwrap(); let store = in_memory_store(); let handle = LoggerHandle { tx: sender, stats: Stats::new(&Collector::default().scope("")), - session_strategy: Arc::new(Strategy::Fixed(fixed::Strategy::new( - store.clone(), + session_strategy: Arc::new(Strategy::fixed( + sdk_directory.path(), Arc::new(UUIDCallbacks), - ))), + )), device: Arc::new(bd_device::Device::new(store.clone())), sdk_version: "1.0.0".into(), app_version_repo: Repository::new(store.clone()), - store, + opaque_entity_updates: watch::channel(None).0, + pending_entity_id: Arc::new(parking_lot::Mutex::new(None)), sleep_mode_active: watch::channel(false).0, is_tracing_active: Arc::new(AtomicBool::new(false)), }; @@ -64,30 +66,60 @@ async fn thread_local_logger_guard() { } #[tokio::test] -async fn register_opaque_user_id_persists_in_store() { - let (log_tx, _log_rx) = bd_bounded_buffer::channel(100); - let (state_tx, _state_rx) = bd_bounded_buffer::channel(100); +async fn register_opaque_entity_id_updates_store() { + let (log_tx, _log_rx) = bd_bounded_buffer::channel(1024 * 1024); + let (state_tx, mut state_rx) = bd_bounded_buffer::channel(1024 * 1024); let sender = async_log_buffer::Sender::from_parts(log_tx, state_tx); + let sdk_directory = TempDir::new().unwrap(); let store = in_memory_store(); + let (opaque_entity_updates_tx, opaque_entity_updates_rx) = watch::channel(None); let handle = LoggerHandle { tx: sender, stats: Stats::new(&Collector::default().scope("")), - session_strategy: Arc::new(Strategy::Fixed(fixed::Strategy::new( - store.clone(), + session_strategy: Arc::new(Strategy::fixed( + sdk_directory.path(), Arc::new(UUIDCallbacks), - ))), + )), device: Arc::new(bd_device::Device::new(store.clone())), sdk_version: "1.0.0".into(), app_version_repo: Repository::new(store.clone()), - store: store.clone(), + opaque_entity_updates: opaque_entity_updates_tx, + pending_entity_id: Arc::new(parking_lot::Mutex::new(None)), sleep_mode_active: watch::channel(false).0, is_tracing_active: Arc::new(AtomicBool::new(false)), }; - handle.register_opaque_user_id("hashed-user-id"); + handle.register_opaque_entity_id(Some("hashed-entity-id")); + assert!(matches!( + tokio::time::timeout(std::time::Duration::from_secs(1), state_rx.recv()) + .await + .unwrap() + .unwrap() + .message, + async_log_buffer::StateUpdateMessage::SetEntityId(Some(entity_id)) if entity_id == "hashed-entity-id" + )); + assert!(matches!( + handle.pending_entity_id.lock().clone(), + Some(super::PendingEntityIdUpdate::Set(entity_id)) if entity_id == "hashed-entity-id" + )); + assert_eq!( + Some("hashed-entity-id".to_string()), + opaque_entity_updates_rx.borrow().clone() + ); + + handle.register_opaque_entity_id(None); + assert!(matches!( + tokio::time::timeout(std::time::Duration::from_secs(1), state_rx.recv()) + .await + .unwrap() + .unwrap() + .message, + async_log_buffer::StateUpdateMessage::SetEntityId(None) + )); assert_eq!( - store.get_string(&OPAQUE_USER_ID_KEY), - Some("hashed-user-id".to_string()) + Some(super::PendingEntityIdUpdate::Clear), + handle.pending_entity_id.lock().clone() ); + assert_eq!(None, opaque_entity_updates_rx.borrow().clone()); } diff --git a/bd-logger/src/test/crash_handler_integration.rs b/bd-logger/src/test/crash_handler_integration.rs index f7339ebe1..eabfb1fb5 100644 --- a/bd-logger/src/test/crash_handler_integration.rs +++ b/bd-logger/src/test/crash_handler_integration.rs @@ -105,7 +105,7 @@ fn crash_report_upload() { ) .unwrap(); - setup.logger.new_logger_handle().session_id() + setup.logger.new_logger_handle().session_id().unwrap() }; let mut setup = Setup::new_with_options(SetupOptions { @@ -120,7 +120,7 @@ fn crash_report_upload() { assert_ne!( initial_session_id, - setup.logger.new_logger_handle().session_id() + setup.logger.new_logger_handle().session_id().unwrap() ); setup.configure_stream_all_logs(); diff --git a/bd-logger/src/test/embedded_logger_integration.rs b/bd-logger/src/test/embedded_logger_integration.rs index 28e4cd70f..f3e14000e 100644 --- a/bd-logger/src/test/embedded_logger_integration.rs +++ b/bd-logger/src/test/embedded_logger_integration.rs @@ -16,8 +16,8 @@ use bd_proto::protos::config::v1::config::BufferConfigList; use bd_proto::protos::config::v1::config::buffer_config::Type; use bd_proto::protos::logging::payload::LogType; use bd_runtime::runtime::FeatureFlag; +use bd_session::Strategy; use bd_session::fixed::UUIDCallbacks; -use bd_session::{Strategy, fixed}; use bd_shutdown::ComponentShutdownTrigger; use bd_test_helpers::config_helper::{ configuration_update, @@ -70,10 +70,10 @@ impl Setup { let (logger, _, future, _) = crate::LoggerBuilder::new(InitParams { sdk_directory: sdk_directory.path().to_owned(), network: Box::new(handle), - session_strategy: Arc::new(Strategy::Fixed(fixed::Strategy::new( - store.clone(), + session_strategy: Arc::new(Strategy::fixed( + sdk_directory.path(), Arc::new(UUIDCallbacks), - ))), + )), metadata_provider: Arc::new(TestMetadataProvider), store, resource_utilization_target: Box::new(EmptyTarget), diff --git a/bd-logger/src/test/logger_integration.rs b/bd-logger/src/test/logger_integration.rs index aa52db03e..62840d139 100644 --- a/bd-logger/src/test/logger_integration.rs +++ b/bd-logger/src/test/logger_integration.rs @@ -29,7 +29,6 @@ use bd_proto::protos::bdtail::bdtail_config::{BdTailConfigurations, BdTailStream use bd_proto::protos::client::api::configuration_update::StateOfTheWorld; use bd_proto::protos::client::api::debug_data_request::WorkflowTransitionDebugData; use bd_proto::protos::client::api::{DebugDataRequest, debug_data_request}; -use bd_proto::protos::client::key_value::FixedSessionStrategyState as State; use bd_proto::protos::config::v1::config::BufferConfigList; use bd_proto::protos::config::v1::config::buffer_config::Type; use bd_proto::protos::filter::filter::Filter; @@ -37,8 +36,8 @@ use bd_proto::protos::logging::payload::LogType; use bd_proto::protos::logging::payload::log::CompressedContents; use bd_runtime::runtime::FeatureFlag; use bd_runtime::runtime::log_upload::MinLogCompressionSize; +use bd_session::Strategy; use bd_session::fixed::UUIDCallbacks; -use bd_session::{Strategy, fixed}; use bd_session_replay::SESSION_REPLAY_SCREENSHOT_LOG_MESSAGE; use bd_stats_common::labels; use bd_test_helpers::config_helper::{ @@ -130,7 +129,7 @@ fn sleep_mode() { fn attributes_accessors() { let setup = Setup::new(); - assert_eq!(36, setup.logger_handle.session_id().len()); + assert_eq!(36, setup.logger_handle.session_id().unwrap().len()); assert_eq!(36, setup.logger_handle.device_id().len()); } @@ -402,12 +401,34 @@ fn explicit_session_capture_disabled_streaming() { #[test] fn log_upload_attributes_override() { + struct StaticSessionId(String); + + impl bd_session::fixed::Callbacks for StaticSessionId { + fn generate_session_id(&self) -> anyhow::Result { + Ok(self.0.clone()) + } + } + let time_first = datetime!(2024-06-01 12:00:00 UTC); - let mut setup = Setup::new_with_metadata(Arc::new(LogMetadata { - timestamp: Mutex::new(time_first), - ootb_fields: LogFields::from([("_some_version".into(), "400".into())]), + let sdk_directory = Arc::new(tempfile::TempDir::with_prefix("sdk").unwrap()); + let previous_session = bd_session::Strategy::fixed( + sdk_directory.path(), + Arc::new(StaticSessionId("foo_overridden".to_string())), + ); + assert_eq!( + tokio_test::block_on(previous_session.session_id()).unwrap(), + "foo_overridden" + ); + + let mut setup = Setup::new_with_options(SetupOptions { + sdk_directory, + metadata_provider: Arc::new(LogMetadata { + timestamp: Mutex::new(time_first), + ootb_fields: LogFields::from([("_some_version".into(), "400".into())]), + ..Default::default() + }), ..Default::default() - })); + }); setup.send_configuration_update( make_configuration_update_with_workflow_flushing_buffer_on_anything( @@ -421,14 +442,6 @@ fn log_upload_attributes_override() { let error_reporter = Arc::new(RecordingErrorReporter::default()); UnexpectedErrorHandler::set_reporter(error_reporter); - setup.store.set( - &fixed::STATE_KEY, - &State { - session_id: "foo_overridden".to_string(), - ..Default::default() - }, - ); - // This log should end up being emitted with an overridden session ID and timestamp, // and no fields associated with the current session setup.log( @@ -524,7 +537,12 @@ fn api_bandwidth_counters() { // If these numbers end up being too variable we do something more generic. let bandwidth_tx = upload.get_counter("api:bandwidth_tx", labels! {}).unwrap(); let bandwidth_rx = upload.get_counter("api:bandwidth_rx", labels! {}).unwrap(); - assert_eq!(upload.get_counter("api:bandwidth_tx_uncompressed", labels! {}), Some(119)); + assert!( + matches!( + upload.get_counter("api:bandwidth_tx_uncompressed", labels! {}), + Some(177 | 178) + ) + ); assert!(bandwidth_tx > 100, "bandwidth_tx = {bandwidth_tx}"); assert!(bandwidth_rx < 400, "bandwidth_rx = {bandwidth_rx}"); assert_eq!(upload.get_counter("api:bandwidth_rx_decompressed", labels! {}), Some(279)); @@ -2757,10 +2775,10 @@ fn runtime_caching() { let logger = crate::LoggerBuilder::new(InitParams { api_key: "foo-api-key".to_string(), network, - session_strategy: Arc::new(Strategy::Fixed(fixed::Strategy::new( - store.clone(), + session_strategy: Arc::new(Strategy::fixed( + sdk_directory.path(), Arc::new(UUIDCallbacks), - ))), + )), static_metadata: Arc::new(EmptyMetadata), store, resource_utilization_target: Box::new(EmptyTarget), diff --git a/bd-logger/src/test/setup.rs b/bd-logger/src/test/setup.rs index 139bcd6fa..44e3d43ae 100644 --- a/bd-logger/src/test/setup.rs +++ b/bd-logger/src/test/setup.rs @@ -25,7 +25,7 @@ use bd_proto::protos::config::v1::config::{BufferConfigList, buffer_config}; use bd_proto::protos::logging::payload::LogType; use bd_runtime::runtime::FeatureFlag as _; use bd_session::Strategy; -use bd_session::fixed::{self, UUIDCallbacks}; +use bd_session::fixed::UUIDCallbacks; use bd_shutdown::{ComponentShutdown, ComponentShutdownTrigger}; use bd_test_helpers::config_helper::{ configuration_update, @@ -117,7 +117,6 @@ pub struct Setup { pub sdk_directory: Arc, pub server: Box, pub current_api_stream: Option, - pub store: Arc, pub capture_screen_count: Arc, pub capture_screenshot_count: Arc, @@ -182,16 +181,16 @@ impl Setup { let (logger, _, flush_trigger) = crate::LoggerBuilder::new(InitParams { sdk_directory: options.sdk_directory.path().into(), api_key: "foo-api-key".to_string(), - session_strategy: Arc::new(Strategy::Fixed(fixed::Strategy::new( - store.clone(), + session_strategy: Arc::new(Strategy::fixed( + options.sdk_directory.path(), Arc::new(UUIDCallbacks), - ))), + )), metadata_provider: options.metadata_provider, resource_utilization_target: Box::new(EmptyTarget), session_replay_target, events_listener_target: Box::new(bd_test_helpers::events::NoOpListenerTarget), device, - store: store.clone(), + store, network: Box::new(Self::run_network(server.port, shutdown.make_shutdown())), static_metadata: Arc::new(EmptyMetadata), start_in_sleep_mode: options.start_in_sleep_mode, @@ -214,7 +213,6 @@ impl Setup { sdk_directory: options.sdk_directory, server, current_api_stream: Some(current_api_stream), - store, capture_screen_count, capture_screenshot_count, _shutdown: shutdown, @@ -464,7 +462,6 @@ impl Drop for Setup { /// Creates minimal `InitParams` for testing without a server connection. /// Useful for testing infrastructure-level concerns like directory locking. pub fn create_minimal_init_params(sdk_directory: &std::path::Path) -> InitParams { - let session_store = in_memory_store(); let device_store = Arc::new(Store::new(Box::new( bd_test_helpers::session::InMemoryStorage::default(), ))); @@ -472,10 +469,7 @@ pub fn create_minimal_init_params(sdk_directory: &std::path::Path) -> InitParams InitParams { sdk_directory: sdk_directory.into(), api_key: "test-api-key".to_string(), - session_strategy: Arc::new(Strategy::Fixed(fixed::Strategy::new( - session_store, - Arc::new(UUIDCallbacks), - ))), + session_strategy: Arc::new(Strategy::fixed(sdk_directory, Arc::new(UUIDCallbacks))), metadata_provider: Arc::new(LogMetadata::default()), resource_utilization_target: Box::new(EmptyTarget), session_replay_target: Box::new(bd_test_helpers::session_replay::NoOpTarget), diff --git a/bd-proto/src/protos/client/api.rs b/bd-proto/src/protos/client/api.rs index 60bcb12f5..b7ea3ca52 100644 --- a/bd-proto/src/protos/client/api.rs +++ b/bd-proto/src/protos/client/api.rs @@ -172,6 +172,414 @@ impl ::protobuf::reflect::ProtobufValue for ClientKillFile { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } +// @@protoc_insertion_point(message:bitdrift_public.protobuf.client.v1.StateUpdateRequest) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct StateUpdateRequest { + // message fields + // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.opaque_entity_update) + pub opaque_entity_update: ::protobuf::MessageField, + // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.started_sessions) + pub started_sessions: ::std::vec::Vec, + // special fields + // @@protoc_insertion_point(special_field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a StateUpdateRequest { + fn default() -> &'a StateUpdateRequest { + ::default_instance() + } +} + +impl StateUpdateRequest { + pub fn new() -> StateUpdateRequest { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, state_update_request::OpaqueEntityUpdate>( + "opaque_entity_update", + |m: &StateUpdateRequest| { &m.opaque_entity_update }, + |m: &mut StateUpdateRequest| { &mut m.opaque_entity_update }, + )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "started_sessions", + |m: &StateUpdateRequest| { &m.started_sessions }, + |m: &mut StateUpdateRequest| { &mut m.started_sessions }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "StateUpdateRequest", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for StateUpdateRequest { + const NAME: &'static str = "StateUpdateRequest"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.opaque_entity_update)?; + }, + 18 => { + self.started_sessions.push(is.read_message()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.opaque_entity_update.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + for value in &self.started_sessions { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.opaque_entity_update.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(1, v, os)?; + } + for v in &self.started_sessions { + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; + }; + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> StateUpdateRequest { + StateUpdateRequest::new() + } + + fn clear(&mut self) { + self.opaque_entity_update.clear(); + self.started_sessions.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static StateUpdateRequest { + static instance: StateUpdateRequest = StateUpdateRequest { + opaque_entity_update: ::protobuf::MessageField::none(), + started_sessions: ::std::vec::Vec::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for StateUpdateRequest { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("StateUpdateRequest").unwrap()).clone() + } +} + +impl ::std::fmt::Display for StateUpdateRequest { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for StateUpdateRequest { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +/// Nested message and enums of message `StateUpdateRequest` +pub mod state_update_request { + // @@protoc_insertion_point(message:bitdrift_public.protobuf.client.v1.StateUpdateRequest.StartedSession) + #[derive(PartialEq,Clone,Default,Debug)] + pub struct StartedSession { + // message fields + // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.StartedSession.session_id) + pub session_id: ::std::string::String, + // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.StartedSession.start_time) + pub start_time: ::protobuf::MessageField<::protobuf::well_known_types::timestamp::Timestamp>, + // special fields + // @@protoc_insertion_point(special_field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.StartedSession.special_fields) + pub special_fields: ::protobuf::SpecialFields, + } + + impl<'a> ::std::default::Default for &'a StartedSession { + fn default() -> &'a StartedSession { + ::default_instance() + } + } + + impl StartedSession { + pub fn new() -> StartedSession { + ::std::default::Default::default() + } + + pub(in super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "session_id", + |m: &StartedSession| { &m.session_id }, + |m: &mut StartedSession| { &mut m.session_id }, + )); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, ::protobuf::well_known_types::timestamp::Timestamp>( + "start_time", + |m: &StartedSession| { &m.start_time }, + |m: &mut StartedSession| { &mut m.start_time }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "StateUpdateRequest.StartedSession", + fields, + oneofs, + ) + } + } + + impl ::protobuf::Message for StartedSession { + const NAME: &'static str = "StartedSession"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.session_id = is.read_string()?; + }, + 18 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.start_time)?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.session_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.session_id); + } + if let Some(v) = self.start_time.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.session_id.is_empty() { + os.write_string(1, &self.session_id)?; + } + if let Some(v) = self.start_time.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> StartedSession { + StartedSession::new() + } + + fn clear(&mut self) { + self.session_id.clear(); + self.start_time.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static StartedSession { + static instance: StartedSession = StartedSession { + session_id: ::std::string::String::new(), + start_time: ::protobuf::MessageField::none(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } + } + + impl ::protobuf::MessageFull for StartedSession { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| super::file_descriptor().message_by_package_relative_name("StateUpdateRequest.StartedSession").unwrap()).clone() + } + } + + impl ::std::fmt::Display for StartedSession { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } + } + + impl ::protobuf::reflect::ProtobufValue for StartedSession { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; + } + + // @@protoc_insertion_point(message:bitdrift_public.protobuf.client.v1.StateUpdateRequest.OpaqueEntityUpdate) + #[derive(PartialEq,Clone,Default,Debug)] + pub struct OpaqueEntityUpdate { + // message fields + // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.OpaqueEntityUpdate.opaque_entity_id) + pub opaque_entity_id: ::std::option::Option<::std::string::String>, + // special fields + // @@protoc_insertion_point(special_field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.OpaqueEntityUpdate.special_fields) + pub special_fields: ::protobuf::SpecialFields, + } + + impl<'a> ::std::default::Default for &'a OpaqueEntityUpdate { + fn default() -> &'a OpaqueEntityUpdate { + ::default_instance() + } + } + + impl OpaqueEntityUpdate { + pub fn new() -> OpaqueEntityUpdate { + ::std::default::Default::default() + } + + pub(in super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "opaque_entity_id", + |m: &OpaqueEntityUpdate| { &m.opaque_entity_id }, + |m: &mut OpaqueEntityUpdate| { &mut m.opaque_entity_id }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "StateUpdateRequest.OpaqueEntityUpdate", + fields, + oneofs, + ) + } + } + + impl ::protobuf::Message for OpaqueEntityUpdate { + const NAME: &'static str = "OpaqueEntityUpdate"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.opaque_entity_id = ::std::option::Option::Some(is.read_string()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.opaque_entity_id.as_ref() { + my_size += ::protobuf::rt::string_size(1, &v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.opaque_entity_id.as_ref() { + os.write_string(1, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> OpaqueEntityUpdate { + OpaqueEntityUpdate::new() + } + + fn clear(&mut self) { + self.opaque_entity_id = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static OpaqueEntityUpdate { + static instance: OpaqueEntityUpdate = OpaqueEntityUpdate { + opaque_entity_id: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } + } + + impl ::protobuf::MessageFull for OpaqueEntityUpdate { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| super::file_descriptor().message_by_package_relative_name("StateUpdateRequest.OpaqueEntityUpdate").unwrap()).clone() + } + } + + impl ::std::fmt::Display for OpaqueEntityUpdate { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } + } + + impl ::protobuf::reflect::ProtobufValue for OpaqueEntityUpdate { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; + } +} + // @@protoc_insertion_point(message:bitdrift_public.protobuf.client.v1.HandshakeRequest) #[derive(PartialEq,Clone,Default,Debug)] pub struct HandshakeRequest { @@ -188,6 +596,8 @@ pub struct HandshakeRequest { pub sleep_mode: bool, // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.HandshakeRequest.opaque_client_state) pub opaque_client_state: ::std::option::Option<::std::vec::Vec>, + // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.HandshakeRequest.state_update) + pub state_update: ::protobuf::MessageField, // special fields // @@protoc_insertion_point(special_field:bitdrift_public.protobuf.client.v1.HandshakeRequest.special_fields) pub special_fields: ::protobuf::SpecialFields, @@ -205,7 +615,7 @@ impl HandshakeRequest { } fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(6); + let mut fields = ::std::vec::Vec::with_capacity(7); let mut oneofs = ::std::vec::Vec::with_capacity(0); fields.push(::protobuf::reflect::rt::v2::make_map_simpler_accessor_new::<_, _>( "static_device_metadata", @@ -237,6 +647,11 @@ impl HandshakeRequest { |m: &HandshakeRequest| { &m.opaque_client_state }, |m: &mut HandshakeRequest| { &mut m.opaque_client_state }, )); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, StateUpdateRequest>( + "state_update", + |m: &HandshakeRequest| { &m.state_update }, + |m: &mut HandshakeRequest| { &mut m.state_update }, + )); ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( "HandshakeRequest", fields, @@ -285,6 +700,9 @@ impl ::protobuf::Message for HandshakeRequest { 66 => { self.opaque_client_state = ::std::option::Option::Some(is.read_bytes()?); }, + 74 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.state_update)?; + }, tag => { ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; }, @@ -319,6 +737,10 @@ impl ::protobuf::Message for HandshakeRequest { if let Some(v) = self.opaque_client_state.as_ref() { my_size += ::protobuf::rt::bytes_size(8, &v); } + if let Some(v) = self.state_update.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); self.special_fields.cached_size().set(my_size as u32); my_size @@ -350,6 +772,9 @@ impl ::protobuf::Message for HandshakeRequest { if let Some(v) = self.opaque_client_state.as_ref() { os.write_bytes(8, v)?; } + if let Some(v) = self.state_update.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(9, v, os)?; + } os.write_unknown_fields(self.special_fields.unknown_fields())?; ::std::result::Result::Ok(()) } @@ -373,6 +798,7 @@ impl ::protobuf::Message for HandshakeRequest { self.previous_disconnect_reason.clear(); self.sleep_mode = false; self.opaque_client_state = ::std::option::Option::None; + self.state_update.clear(); self.special_fields.clear(); } @@ -2722,8 +3148,57 @@ impl ApiRequest { } } + // .bitdrift_public.protobuf.client.v1.StateUpdateRequest state_update = 15; + + pub fn state_update(&self) -> &StateUpdateRequest { + match self.request_type { + ::std::option::Option::Some(api_request::Request_type::StateUpdate(ref v)) => v, + _ => ::default_instance(), + } + } + + pub fn clear_state_update(&mut self) { + self.request_type = ::std::option::Option::None; + } + + pub fn has_state_update(&self) -> bool { + match self.request_type { + ::std::option::Option::Some(api_request::Request_type::StateUpdate(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_state_update(&mut self, v: StateUpdateRequest) { + self.request_type = ::std::option::Option::Some(api_request::Request_type::StateUpdate(v)) + } + + // Mutable pointer to the field. + pub fn mut_state_update(&mut self) -> &mut StateUpdateRequest { + if let ::std::option::Option::Some(api_request::Request_type::StateUpdate(_)) = self.request_type { + } else { + self.request_type = ::std::option::Option::Some(api_request::Request_type::StateUpdate(StateUpdateRequest::new())); + } + match self.request_type { + ::std::option::Option::Some(api_request::Request_type::StateUpdate(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_state_update(&mut self) -> StateUpdateRequest { + if self.has_state_update() { + match self.request_type.take() { + ::std::option::Option::Some(api_request::Request_type::StateUpdate(v)) => v, + _ => panic!(), + } + } else { + StateUpdateRequest::new() + } + } + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(12); + let mut fields = ::std::vec::Vec::with_capacity(13); let mut oneofs = ::std::vec::Vec::with_capacity(1); fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, HandshakeRequest>( "handshake", @@ -2809,6 +3284,13 @@ impl ApiRequest { ApiRequest::mut_debug_data, ApiRequest::set_debug_data, )); + fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, StateUpdateRequest>( + "state_update", + ApiRequest::has_state_update, + ApiRequest::state_update, + ApiRequest::mut_state_update, + ApiRequest::set_state_update, + )); oneofs.push(api_request::Request_type::generated_oneof_descriptor_data()); ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( "ApiRequest", @@ -2864,6 +3346,9 @@ impl ::protobuf::Message for ApiRequest { 114 => { self.request_type = ::std::option::Option::Some(api_request::Request_type::DebugData(is.read_message()?)); }, + 122 => { + self.request_type = ::std::option::Option::Some(api_request::Request_type::StateUpdate(is.read_message()?)); + }, tag => { ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; }, @@ -2926,6 +3411,10 @@ impl ::protobuf::Message for ApiRequest { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; }, + &api_request::Request_type::StateUpdate(ref v) => { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }, }; } my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); @@ -2972,6 +3461,9 @@ impl ::protobuf::Message for ApiRequest { &api_request::Request_type::DebugData(ref v) => { ::protobuf::rt::write_message_field_with_cached_size(14, v, os)?; }, + &api_request::Request_type::StateUpdate(ref v) => { + ::protobuf::rt::write_message_field_with_cached_size(15, v, os)?; + }, }; } os.write_unknown_fields(self.special_fields.unknown_fields())?; @@ -3003,6 +3495,7 @@ impl ::protobuf::Message for ApiRequest { self.request_type = ::std::option::Option::None; self.request_type = ::std::option::Option::None; self.request_type = ::std::option::Option::None; + self.request_type = ::std::option::Option::None; self.special_fields.clear(); } @@ -3062,6 +3555,8 @@ pub mod api_request { ArtifactIntent(super::UploadArtifactIntentRequest), // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.client.v1.ApiRequest.debug_data) DebugData(super::DebugDataRequest), + // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.client.v1.ApiRequest.state_update) + StateUpdate(super::StateUpdateRequest), } impl ::protobuf::Oneof for Request_type { @@ -8476,6 +8971,109 @@ pub mod debug_data_request { } } +// @@protoc_insertion_point(message:bitdrift_public.protobuf.client.v1.StateUpdateResponse) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct StateUpdateResponse { + // special fields + // @@protoc_insertion_point(special_field:bitdrift_public.protobuf.client.v1.StateUpdateResponse.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a StateUpdateResponse { + fn default() -> &'a StateUpdateResponse { + ::default_instance() + } +} + +impl StateUpdateResponse { + pub fn new() -> StateUpdateResponse { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(0); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "StateUpdateResponse", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for StateUpdateResponse { + const NAME: &'static str = "StateUpdateResponse"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> StateUpdateResponse { + StateUpdateResponse::new() + } + + fn clear(&mut self) { + self.special_fields.clear(); + } + + fn default_instance() -> &'static StateUpdateResponse { + static instance: StateUpdateResponse = StateUpdateResponse { + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for StateUpdateResponse { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("StateUpdateResponse").unwrap()).clone() + } +} + +impl ::std::fmt::Display for StateUpdateResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for StateUpdateResponse { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + // @@protoc_insertion_point(message:bitdrift_public.protobuf.client.v1.ApiResponse) #[derive(PartialEq,Clone,Default,Debug)] pub struct ApiResponse { @@ -9134,8 +9732,57 @@ impl ApiResponse { } } + // .bitdrift_public.protobuf.client.v1.StateUpdateResponse state_update = 16; + + pub fn state_update(&self) -> &StateUpdateResponse { + match self.response_type { + ::std::option::Option::Some(api_response::Response_type::StateUpdate(ref v)) => v, + _ => ::default_instance(), + } + } + + pub fn clear_state_update(&mut self) { + self.response_type = ::std::option::Option::None; + } + + pub fn has_state_update(&self) -> bool { + match self.response_type { + ::std::option::Option::Some(api_response::Response_type::StateUpdate(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_state_update(&mut self, v: StateUpdateResponse) { + self.response_type = ::std::option::Option::Some(api_response::Response_type::StateUpdate(v)) + } + + // Mutable pointer to the field. + pub fn mut_state_update(&mut self) -> &mut StateUpdateResponse { + if let ::std::option::Option::Some(api_response::Response_type::StateUpdate(_)) = self.response_type { + } else { + self.response_type = ::std::option::Option::Some(api_response::Response_type::StateUpdate(StateUpdateResponse::new())); + } + match self.response_type { + ::std::option::Option::Some(api_response::Response_type::StateUpdate(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_state_update(&mut self) -> StateUpdateResponse { + if self.has_state_update() { + match self.response_type.take() { + ::std::option::Option::Some(api_response::Response_type::StateUpdate(v)) => v, + _ => panic!(), + } + } else { + StateUpdateResponse::new() + } + } + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(13); + let mut fields = ::std::vec::Vec::with_capacity(14); let mut oneofs = ::std::vec::Vec::with_capacity(1); fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, HandshakeResponse>( "handshake", @@ -9228,6 +9875,13 @@ impl ApiResponse { ApiResponse::mut_artifact_intent, ApiResponse::set_artifact_intent, )); + fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, StateUpdateResponse>( + "state_update", + ApiResponse::has_state_update, + ApiResponse::state_update, + ApiResponse::mut_state_update, + ApiResponse::set_state_update, + )); oneofs.push(api_response::Response_type::generated_oneof_descriptor_data()); ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( "ApiResponse", @@ -9286,6 +9940,9 @@ impl ::protobuf::Message for ApiResponse { 122 => { self.response_type = ::std::option::Option::Some(api_response::Response_type::ArtifactIntent(is.read_message()?)); }, + 130 => { + self.response_type = ::std::option::Option::Some(api_response::Response_type::StateUpdate(is.read_message()?)); + }, tag => { ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; }, @@ -9352,6 +10009,10 @@ impl ::protobuf::Message for ApiResponse { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; }, + &api_response::Response_type::StateUpdate(ref v) => { + let len = v.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }, }; } my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); @@ -9401,6 +10062,9 @@ impl ::protobuf::Message for ApiResponse { &api_response::Response_type::ArtifactIntent(ref v) => { ::protobuf::rt::write_message_field_with_cached_size(15, v, os)?; }, + &api_response::Response_type::StateUpdate(ref v) => { + ::protobuf::rt::write_message_field_with_cached_size(16, v, os)?; + }, }; } os.write_unknown_fields(self.special_fields.unknown_fields())?; @@ -9433,6 +10097,7 @@ impl ::protobuf::Message for ApiResponse { self.response_type = ::std::option::Option::None; self.response_type = ::std::option::Option::None; self.response_type = ::std::option::Option::None; + self.response_type = ::std::option::Option::None; self.special_fields.clear(); } @@ -9494,6 +10159,8 @@ pub mod api_response { ArtifactUpload(super::UploadArtifactResponse), // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.client.v1.ApiResponse.artifact_intent) ArtifactIntent(super::UploadArtifactIntentResponse), + // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.client.v1.ApiResponse.state_update) + StateUpdate(super::StateUpdateResponse), } impl ::protobuf::Oneof for Response_type { @@ -9525,19 +10192,29 @@ static file_descriptor_proto_data: &'static [u8] = b"\ protobuf/timestamp.proto\x1a\x17validate/validate.proto\"m\n\x0eClientKi\ llFile\x12\x20\n\x0capi_key_hash\x18\x01\x20\x01(\x0cR\napiKeyHash\x129\ \n\nkill_until\x18\x02\x20\x01(\x0b2\x1a.google.protobuf.TimestampR\tkil\ - lUntil\"\xcc\x04\n\x10HandshakeRequest\x12\x84\x01\n\x16static_device_me\ - tadata\x18\x01\x20\x03(\x0b2N.bitdrift_public.protobuf.client.v1.Handsha\ - keRequest.StaticDeviceMetadataEntryR\x14staticDeviceMetadata\x12>\n\x1bc\ - onfiguration_version_nonce\x18\x03\x20\x01(\tR\x19configurationVersionNo\ - nce\x122\n\x15runtime_version_nonce\x18\x04\x20\x01(\tR\x13runtimeVersio\ - nNonce\x12<\n\x1aprevious_disconnect_reason\x18\x06\x20\x01(\tR\x18previ\ - ousDisconnectReason\x12\x1d\n\nsleep_mode\x18\x07\x20\x01(\x08R\tsleepMo\ - de\x123\n\x13opaque_client_state\x18\x08\x20\x01(\x0cH\0R\x11opaqueClien\ - tState\x88\x01\x01\x1ar\n\x19StaticDeviceMetadataEntry\x12\x10\n\x03key\ - \x18\x01\x20\x01(\tR\x03key\x12?\n\x05value\x18\x02\x20\x01(\x0b2).bitdr\ - ift_public.protobuf.logging.v1.DataR\x05value:\x028\x01B\x16\n\x14_opaqu\ - e_client_stateJ\x04\x08\x02\x10\x03J\x04\x08\x05\x10\x06R\x13fields_for_\ - all_logs\"\xd5\x04\n\x16LogUploadIntentRequest\x12\x1b\n\tlog_count\x18\ + lUntil\"\xc9\x03\n\x12StateUpdateRequest\x12{\n\x14opaque_entity_update\ + \x18\x01\x20\x01(\x0b2I.bitdrift_public.protobuf.client.v1.StateUpdateRe\ + quest.OpaqueEntityUpdateR\x12opaqueEntityUpdate\x12p\n\x10started_sessio\ + ns\x18\x02\x20\x03(\x0b2E.bitdrift_public.protobuf.client.v1.StateUpdate\ + Request.StartedSessionR\x0fstartedSessions\x1aj\n\x0eStartedSession\x12\ + \x1d\n\nsession_id\x18\x01\x20\x01(\tR\tsessionId\x129\n\nstart_time\x18\ + \x02\x20\x01(\x0b2\x1a.google.protobuf.TimestampR\tstartTime\x1aX\n\x12O\ + paqueEntityUpdate\x12-\n\x10opaque_entity_id\x18\x01\x20\x01(\tH\0R\x0eo\ + paqueEntityId\x88\x01\x01B\x13\n\x11_opaque_entity_id\"\x92\x05\n\x10Han\ + dshakeRequest\x12\x84\x01\n\x16static_device_metadata\x18\x01\x20\x03(\ + \x0b2N.bitdrift_public.protobuf.client.v1.HandshakeRequest.StaticDeviceM\ + etadataEntryR\x14staticDeviceMetadata\x12>\n\x1bconfiguration_version_no\ + nce\x18\x03\x20\x01(\tR\x19configurationVersionNonce\x122\n\x15runtime_v\ + ersion_nonce\x18\x04\x20\x01(\tR\x13runtimeVersionNonce\x12<\n\x1aprevio\ + us_disconnect_reason\x18\x06\x20\x01(\tR\x18previousDisconnectReason\x12\ + \x1d\n\nsleep_mode\x18\x07\x20\x01(\x08R\tsleepMode\x123\n\x13opaque_cli\ + ent_state\x18\x08\x20\x01(\x0cH\0R\x11opaqueClientState\x88\x01\x01\x12Y\ + \n\x0cstate_update\x18\t\x20\x01(\x0b26.bitdrift_public.protobuf.client.\ + v1.StateUpdateRequestR\x0bstateUpdate\x1ar\n\x19StaticDeviceMetadataEntr\ + y\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12?\n\x05value\x18\x02\ + \x20\x01(\x0b2).bitdrift_public.protobuf.logging.v1.DataR\x05value:\x028\ + \x01B\x16\n\x14_opaque_client_stateJ\x04\x08\x02\x10\x03J\x04\x08\x05\ + \x10\x06\"\xd5\x04\n\x16LogUploadIntentRequest\x12\x1b\n\tlog_count\x18\ \x01\x20\x01(\rR\x08logCount\x12\x1d\n\nbyte_count\x18\x02\x20\x01(\rR\t\ byteCount\x12\x1b\n\tbuffer_id\x18\x03\x20\x01(\tR\x08bufferId\x12\x1f\n\ \x0bintent_uuid\x18\x04\x20\x01(\tR\nintentUuid\x12\x1d\n\nsession_id\ @@ -9567,7 +10244,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01(\x0b2?.bitdrift_public.protobuf.client.v1.ConfigurationUpdateAck.Na\ ckR\x04nack\x1aP\n\x04Nack\x12#\n\rversion_nonce\x18\x01\x20\x01(\tR\x0c\ versionNonce\x12#\n\rerror_details\x18\x02\x20\x01(\tR\x0cerrorDetails\"\ - \xc2\t\n\nApiRequest\x12T\n\thandshake\x18\x01\x20\x01(\x0b24.bitdrift_p\ + \x9f\n\n\nApiRequest\x12T\n\thandshake\x18\x01\x20\x01(\x0b24.bitdrift_p\ ublic.protobuf.client.v1.HandshakeRequestH\0R\thandshake\x12h\n\x11log_u\ pload_intent\x18\x07\x20\x01(\x0b2:.bitdrift_public.protobuf.client.v1.L\ ogUploadIntentRequestH\0R\x0flogUploadIntent\x12U\n\nlog_upload\x18\x02\ @@ -9587,173 +10264,177 @@ static file_descriptor_proto_data: &'static [u8] = b"\ uestH\0R\x0eartifactUpload\x12j\n\x0fartifact_intent\x18\r\x20\x01(\x0b2\ ?.bitdrift_public.protobuf.client.v1.UploadArtifactIntentRequestH\0R\x0e\ artifactIntent\x12U\n\ndebug_data\x18\x0e\x20\x01(\x0b24.bitdrift_public\ - .protobuf.client.v1.DebugDataRequestH\0R\tdebugDataB\x13\n\x0crequest_ty\ - pe\x12\x03\xf8B\x01J\x04\x08\x08\x10\tJ\x04\x08\t\x10\n\"\x9a\x02\n\x17S\ - ankeyPathUploadRequest\x12(\n\x0bupload_uuid\x18\x04\x20\x01(\tR\nupload\ - UuidB\x07\xfaB\x04r\x02\x10\x01\x12\x17\n\x02id\x18\x01\x20\x01(\tR\x02i\ - dB\x07\xfaB\x04r\x02\x10\x01\x12\x20\n\x07path_id\x18\x02\x20\x01(\tR\ - \x06pathIdB\x07\xfaB\x04r\x02\x10\x01\x12`\n\x05nodes\x18\x03\x20\x03(\ - \x0b2@.bitdrift_public.protobuf.client.v1.SankeyPathUploadRequest.NodeR\ - \x05nodesB\x08\xfaB\x05\x92\x01\x02\x08\x01\x1a8\n\x04Node\x120\n\x0fext\ - racted_value\x18\x01\x20\x01(\tR\x0eextractedValueB\x07\xfaB\x04r\x02\ - \x10\x01\"\x96\x01\n\x13SankeyIntentRequest\x12(\n\x0bintent_uuid\x18\ - \x01\x20\x01(\tR\nintentUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x20\n\x07pat\ - h_id\x18\x02\x20\x01(\tR\x06pathIdB\x07\xfaB\x04r\x02\x10\x01\x123\n\x11\ - sankey_diagram_id\x18\x03\x20\x01(\tR\x0fsankeyDiagramIdB\x07\xfaB\x04r\ - \x02\x10\x01\"\xd9\x03\n\x1bUploadArtifactIntentRequest\x12(\n\x0bintent\ - _uuid\x18\x01\x20\x01(\tR\nintentUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x20\ - \n\x07type_id\x18\x02\x20\x01(\tR\x06typeIdB\x07\xfaB\x04r\x02\x10\x01\ - \x12i\n\x08metadata\x18\x06\x20\x03(\x0b2M.bitdrift_public.protobuf.clie\ - nt.v1.UploadArtifactIntentRequest.MetadataEntryR\x08metadata\x12(\n\x0ba\ - rtifact_id\x18\x04\x20\x01(\tR\nartifactIdB\x07\xfaB\x04r\x02\x10\x01\ - \x128\n\x04time\x18\x05\x20\x01(\x0b2\x1a.google.protobuf.TimestampR\x04\ - timeB\x08\xfaB\x05\x8a\x01\x02\x10\x01\x12\"\n\nsession_id\x18\x07\x20\ - \x01(\tH\0R\tsessionId\x88\x01\x01\x1af\n\rMetadataEntry\x12\x10\n\x03ke\ - y\x18\x01\x20\x01(\tR\x03key\x12?\n\x05value\x18\x02\x20\x01(\x0b2).bitd\ - rift_public.protobuf.logging.v1.DataR\x05value:\x028\x01B\r\n\x0b_sessio\ - n_idJ\x04\x08\x03\x10\x04\"\xd4\x02\n\x1cUploadArtifactIntentResponse\ - \x12(\n\x0bintent_uuid\x18\x01\x20\x01(\tR\nintentUuidB\x07\xfaB\x04r\ - \x02\x10\x01\x12\x83\x01\n\x12upload_immediately\x18\x03\x20\x01(\x0b2R.\ - bitdrift_public.protobuf.client.v1.UploadArtifactIntentResponse.UploadIm\ - mediatelyH\0R\x11uploadImmediately\x12[\n\x04drop\x18\x04\x20\x01(\x0b2E\ - .bitdrift_public.protobuf.client.v1.UploadArtifactIntentResponse.DropH\0\ - R\x04drop\x1a\x13\n\x11UploadImmediately\x1a\x06\n\x04DropB\n\n\x08decis\ - ion\"\xba\x04\n\x15UploadArtifactRequest\x12(\n\x0bupload_uuid\x18\x01\ - \x20\x01(\tR\nuploadUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x20\n\x07type_id\ - \x18\x02\x20\x01(\tR\x06typeIdB\x07\xfaB\x04r\x02\x10\x01\x12\x1a\n\x08c\ - ontents\x18\x03\x20\x01(\x0cR\x08contents\x12(\n\x0bartifact_id\x18\x04\ - \x20\x01(\tR\nartifactIdB\x07\xfaB\x04r\x02\x10\x01\x12s\n\x0estate_meta\ - data\x18\x05\x20\x03(\x0b2L.bitdrift_public.protobuf.client.v1.UploadArt\ - ifactRequest.StateMetadataEntryR\rstateMetadata\x128\n\x04time\x18\x06\ + .protobuf.client.v1.DebugDataRequestH\0R\tdebugData\x12[\n\x0cstate_upda\ + te\x18\x0f\x20\x01(\x0b26.bitdrift_public.protobuf.client.v1.StateUpdate\ + RequestH\0R\x0bstateUpdateB\x13\n\x0crequest_type\x12\x03\xf8B\x01J\x04\ + \x08\x08\x10\tJ\x04\x08\t\x10\n\"\x9a\x02\n\x17SankeyPathUploadRequest\ + \x12(\n\x0bupload_uuid\x18\x04\x20\x01(\tR\nuploadUuidB\x07\xfaB\x04r\ + \x02\x10\x01\x12\x17\n\x02id\x18\x01\x20\x01(\tR\x02idB\x07\xfaB\x04r\ + \x02\x10\x01\x12\x20\n\x07path_id\x18\x02\x20\x01(\tR\x06pathIdB\x07\xfa\ + B\x04r\x02\x10\x01\x12`\n\x05nodes\x18\x03\x20\x03(\x0b2@.bitdrift_publi\ + c.protobuf.client.v1.SankeyPathUploadRequest.NodeR\x05nodesB\x08\xfaB\ + \x05\x92\x01\x02\x08\x01\x1a8\n\x04Node\x120\n\x0fextracted_value\x18\ + \x01\x20\x01(\tR\x0eextractedValueB\x07\xfaB\x04r\x02\x10\x01\"\x96\x01\ + \n\x13SankeyIntentRequest\x12(\n\x0bintent_uuid\x18\x01\x20\x01(\tR\nint\ + entUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x20\n\x07path_id\x18\x02\x20\x01(\ + \tR\x06pathIdB\x07\xfaB\x04r\x02\x10\x01\x123\n\x11sankey_diagram_id\x18\ + \x03\x20\x01(\tR\x0fsankeyDiagramIdB\x07\xfaB\x04r\x02\x10\x01\"\xd9\x03\ + \n\x1bUploadArtifactIntentRequest\x12(\n\x0bintent_uuid\x18\x01\x20\x01(\ + \tR\nintentUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x20\n\x07type_id\x18\x02\ + \x20\x01(\tR\x06typeIdB\x07\xfaB\x04r\x02\x10\x01\x12i\n\x08metadata\x18\ + \x06\x20\x03(\x0b2M.bitdrift_public.protobuf.client.v1.UploadArtifactInt\ + entRequest.MetadataEntryR\x08metadata\x12(\n\x0bartifact_id\x18\x04\x20\ + \x01(\tR\nartifactIdB\x07\xfaB\x04r\x02\x10\x01\x128\n\x04time\x18\x05\ \x20\x01(\x0b2\x1a.google.protobuf.TimestampR\x04timeB\x08\xfaB\x05\x8a\ - \x01\x02\x10\x01\x12\x1d\n\nsession_id\x18\x07\x20\x01(\tR\tsessionId\ - \x12T\n\rfeature_flags\x18\x08\x20\x03(\x0b2/.bitdrift_public.protobuf.c\ - lient.v1.FeatureFlagR\x0cfeatureFlags\x1ak\n\x12StateMetadataEntry\x12\ - \x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12?\n\x05value\x18\x02\x20\x01\ - (\x0b2).bitdrift_public.protobuf.logging.v1.DataR\x05value:\x028\x01\"X\ - \n\x16UploadArtifactResponse\x12(\n\x0bupload_uuid\x18\x01\x20\x01(\tR\n\ - uploadUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x14\n\x05error\x18\x02\x20\x01\ - (\tR\x05error\"\xf7\x02\n\x11HandshakeResponse\x12m\n\x0fstream_settings\ - \x18\x01\x20\x01(\x0b2D.bitdrift_public.protobuf.client.v1.HandshakeResp\ - onse.StreamSettingsR\x0estreamSettings\x12>\n\x1bconfiguration_update_st\ - atus\x18\x02\x20\x01(\rR\x19configurationUpdateStatus\x12A\n\x1bopaque_c\ - lient_state_to_echo\x18\x03\x20\x01(\x0cH\0R\x17opaqueClientStateToEcho\ - \x88\x01\x01\x1aP\n\x0eStreamSettings\x12>\n\rping_interval\x18\x01\x20\ - \x01(\x0b2\x19.google.protobuf.DurationR\x0cpingIntervalB\x1e\n\x1c_opaq\ - ue_client_state_to_echo\"I\n\x0bRateLimited\x12:\n\x0bretry_after\x18\ - \x01\x20\x01(\x0b2\x19.google.protobuf.DurationR\nretryAfter\"\xca\x01\n\ - \x11LogUploadResponse\x12(\n\x0bupload_uuid\x18\x01\x20\x01(\tR\nuploadU\ - uidB\x07\xfaB\x04r\x02\x10\x01\x12\x14\n\x05error\x18\x02\x20\x01(\tR\ - \x05error\x12!\n\x0clogs_dropped\x18\x03\x20\x01(\rR\x0blogsDropped\x12R\ - \n\x0crate_limited\x18\x04\x20\x01(\x0b2/.bitdrift_public.protobuf.clien\ - t.v1.RateLimitedR\x0brateLimited\"\x9e\n\n\x12StatsUploadRequest\x12(\n\ - \x0bupload_uuid\x18\x01\x20\x01(\tR\nuploadUuidB\x07\xfaB\x04r\x02\x10\ - \x01\x12e\n\x08snapshot\x18\x02\x20\x03(\x0b2?.bitdrift_public.protobuf.\ - client.v1.StatsUploadRequest.SnapshotR\x08snapshotB\x08\xfaB\x05\x92\x01\ - \x02\x08\x01\x123\n\x07sent_at\x18\x03\x20\x01(\x0b2\x1a.google.protobuf\ - .TimestampR\x06sentAt\x12h\n\rupload_reason\x18\x04\x20\x01(\x0e2C.bitdr\ - ift_public.protobuf.client.v1.StatsUploadRequest.UploadReasonR\x0cupload\ - Reason\x1a\xe9\x06\n\x08Snapshot\x12K\n\x07metrics\x18\x01\x20\x01(\x0b2\ - /.bitdrift_public.protobuf.client.v1.MetricsListH\0R\x07metrics\x12l\n\n\ - aggregated\x18\x02\x20\x01(\x0b2J.bitdrift_public.protobuf.client.v1.Sta\ - tsUploadRequest.Snapshot.AggregatedH\x01R\naggregated\x12\x86\x01\n\x13m\ - etric_id_overflows\x18\x03\x20\x03(\x0b2V.bitdrift_public.protobuf.clien\ - t.v1.StatsUploadRequest.Snapshot.MetricIdOverflowsEntryR\x11metricIdOver\ - flows\x12\x86\x01\n\x13workflow_debug_data\x18\x04\x20\x03(\x0b2V.bitdri\ - ft_public.protobuf.client.v1.StatsUploadRequest.Snapshot.WorkflowDebugDa\ - taEntryR\x11workflowDebugData\x1a\x90\x01\n\nAggregated\x12G\n\x0cperiod\ - _start\x18\x04\x20\x01(\x0b2\x1a.google.protobuf.TimestampR\x0bperiodSta\ - rtB\x08\xfaB\x05\x8a\x01\x02\x10\x01\x129\n\nperiod_end\x18\x05\x20\x01(\ - \x0b2\x1a.google.protobuf.TimestampR\tperiodEnd\x1aD\n\x16MetricIdOverfl\ - owsEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x14\n\x05value\ - \x18\x02\x20\x01(\x04R\x05value:\x028\x01\x1a\x8c\x01\n\x16WorkflowDebug\ - DataEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\\\n\x05value\ - \x18\x02\x20\x01(\x0b2F.bitdrift_public.protobuf.client.v1.DebugDataRequ\ - est.WorkflowDebugDataR\x05value:\x028\x01B\x14\n\rsnapshot_type\x12\x03\ - \xf8B\x01B\x12\n\x0boccurred_at\x12\x03\xf8B\x01\"l\n\x0cUploadReason\ - \x12\x1d\n\x19UPLOAD_REASON_UNSPECIFIED\x10\0\x12\x1a\n\x16UPLOAD_REASON\ - _PERIODIC\x10\x01\x12!\n\x1dUPLOAD_REASON_EVENT_TRIGGERED\x10\x02\"~\n\ - \x13StatsUploadResponse\x12(\n\x0bupload_uuid\x18\x01\x20\x01(\tR\nuploa\ - dUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x14\n\x05error\x18\x02\x20\x01(\tR\ - \x05error\x12'\n\x0fmetrics_dropped\x18\x03\x20\x01(\rR\x0emetricsDroppe\ - d\"\x0e\n\x0cPongResponse\"\xa1\x06\n\x13ConfigurationUpdate\x12#\n\rver\ - sion_nonce\x18\x01\x20\x01(\tR\x0cversionNonce\x12v\n\x12state_of_the_wo\ - rld\x18\x02\x20\x01(\x0b2G.bitdrift_public.protobuf.client.v1.Configurat\ - ionUpdate.StateOfTheWorldH\0R\x0fstateOfTheWorld\x1a\xdd\x04\n\x0fStateO\ - fTheWorld\x12b\n\x12buffer_config_list\x18\x03\x20\x01(\x0b24.bitdrift_p\ - ublic.protobuf.config.v1.BufferConfigListR\x10bufferConfigList\x12u\n\ - \x17workflows_configuration\x18\x04\x20\x01(\x0b2<.bitdrift_public.proto\ - buf.workflow.v1.WorkflowsConfigurationR\x16workflowsConfiguration\x12k\n\ - \x14bdtail_configuration\x18\x06\x20\x01(\x0b28.bitdrift_public.protobuf\ - .bdtail.v1.BdTailConfigurationsR\x13bdtailConfiguration\x12m\n\x15filter\ - s_configuration\x18\x08\x20\x01(\x0b28.bitdrift_public.protobuf.filter.v\ - 1.FiltersConfigurationR\x14filtersConfiguration\x12e\n\x0fdebug_workflow\ - s\x18\t\x20\x01(\x0b2<.bitdrift_public.protobuf.workflow.v1.WorkflowsCon\ - figurationR\x0edebugWorkflowsJ\x04\x08\x02\x10\x03J\x04\x08\x07\x10\x08R\ - \x08mll_listR\x16insights_configurationB\r\n\x0bupdate_type\"{\n\rRuntim\ - eUpdate\x12#\n\rversion_nonce\x18\x01\x20\x01(\tR\x0cversionNonce\x12E\n\ - \x07runtime\x18\x02\x20\x01(\x0b2+.bitdrift_public.protobuf.client.v1.Ru\ - ntimeR\x07runtime\"\xa7\x01\n\rErrorShutdown\x12\x1f\n\x0bgrpc_status\ - \x18\x01\x20\x01(\x05R\ngrpcStatus\x12!\n\x0cgrpc_message\x18\x02\x20\ - \x01(\tR\x0bgrpcMessage\x12R\n\x0crate_limited\x18\x03\x20\x01(\x0b2/.bi\ - tdrift_public.protobuf.client.v1.RateLimitedR\x0brateLimited\"4\n\x0cFlu\ - shBuffers\x12$\n\x0ebuffer_id_list\x18\x01\x20\x03(\tR\x0cbufferIdList\"\ - Z\n\x18SankeyPathUploadResponse\x12(\n\x0bupload_uuid\x18\x01\x20\x01(\t\ - R\nuploadUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x14\n\x05error\x18\x02\x20\ - \x01(\tR\x05error\"\xcb\x02\n\x14SankeyIntentResponse\x12(\n\x0bintent_u\ - uid\x18\x01\x20\x01(\tR\nintentUuidB\x07\xfaB\x04r\x02\x10\x01\x12{\n\ - \x12upload_immediately\x18\x03\x20\x01(\x0b2J.bitdrift_public.protobuf.c\ - lient.v1.SankeyIntentResponse.UploadImmediatelyH\0R\x11uploadImmediately\ - \x12S\n\x04drop\x18\x04\x20\x01(\x0b2=.bitdrift_public.protobuf.client.v\ - 1.SankeyIntentResponse.DropH\0R\x04drop\x1a\x13\n\x11UploadImmediately\ - \x1a\x06\n\x04DropB\n\n\x08decisionJ\x04\x08\x02\x10\x03R\x08decision\"\ - \xb5\x08\n\x10DebugDataRequest\x12{\n\x13workflow_debug_data\x18\x01\x20\ - \x03(\x0b2K.bitdrift_public.protobuf.client.v1.DebugDataRequest.Workflow\ - DebugDataEntryR\x11workflowDebugData\x1a\x87\x02\n\x1bWorkflowTransition\ - DebugData\x12+\n\x10transition_index\x18\x01\x20\x01(\rH\0R\x0ftransitio\ - nIndex\x12/\n\x12timeout_transition\x18\x02\x20\x01(\x08H\0R\x11timeoutT\ - ransition\x12)\n\x10transition_count\x18\x03\x20\x01(\x04R\x0ftransition\ - Count\x12L\n\x14last_transition_time\x18\x04\x20\x01(\x0b2\x1a.google.pr\ - otobuf.TimestampR\x12lastTransitionTimeB\x11\n\x0ftransition_type\x1a\ - \x8c\x01\n\x16WorkflowStateDebugData\x12r\n\x0btransitions\x18\x01\x20\ - \x03(\x0b2P.bitdrift_public.protobuf.client.v1.DebugDataRequest.Workflow\ - TransitionDebugDataR\x0btransitions\x1a\xfb\x02\n\x11WorkflowDebugData\ - \x12j\n\x06states\x18\x01\x20\x03(\x0b2R.bitdrift_public.protobuf.client\ - .v1.DebugDataRequest.WorkflowDebugData.StatesEntryR\x06states\x12q\n\x0b\ - start_reset\x18\x02\x20\x01(\x0b2P.bitdrift_public.protobuf.client.v1.De\ - bugDataRequest.WorkflowTransitionDebugDataR\nstartReset\x1a\x86\x01\n\ - \x0bStatesEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12a\n\x05va\ - lue\x18\x02\x20\x01(\x0b2K.bitdrift_public.protobuf.client.v1.DebugDataR\ - equest.WorkflowStateDebugDataR\x05value:\x028\x01\x1a\x8c\x01\n\x16Workf\ - lowDebugDataEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\\\n\ - \x05value\x18\x02\x20\x01(\x0b2F.bitdrift_public.protobuf.client.v1.Debu\ - gDataRequest.WorkflowDebugDataR\x05value:\x028\x01\"\xa8\n\n\x0bApiRespo\ - nse\x12U\n\thandshake\x18\x01\x20\x01(\x0b25.bitdrift_public.protobuf.cl\ - ient.v1.HandshakeResponseH\0R\thandshake\x12V\n\nlog_upload\x18\x02\x20\ - \x01(\x0b25.bitdrift_public.protobuf.client.v1.LogUploadResponseH\0R\tlo\ - gUpload\x12i\n\x11log_upload_intent\x18\x08\x20\x01(\x0b2;.bitdrift_publ\ - ic.protobuf.client.v1.LogUploadIntentResponseH\0R\x0flogUploadIntent\x12\ - \\\n\x0cstats_upload\x18\x07\x20\x01(\x0b27.bitdrift_public.protobuf.cli\ - ent.v1.StatsUploadResponseH\0R\x0bstatsUpload\x12F\n\x04pong\x18\x03\x20\ - \x01(\x0b20.bitdrift_public.protobuf.client.v1.PongResponseH\0R\x04pong\ - \x12l\n\x14configuration_update\x18\x04\x20\x01(\x0b27.bitdrift_public.p\ - rotobuf.client.v1.ConfigurationUpdateH\0R\x13configurationUpdate\x12Z\n\ - \x0eruntime_update\x18\x05\x20\x01(\x0b21.bitdrift_public.protobuf.clien\ - t.v1.RuntimeUpdateH\0R\rruntimeUpdate\x12Z\n\x0eerror_shutdown\x18\x06\ - \x20\x01(\x0b21.bitdrift_public.protobuf.client.v1.ErrorShutdownH\0R\rer\ - rorShutdown\x12W\n\rflush_buffers\x18\t\x20\x01(\x0b20.bitdrift_public.p\ - rotobuf.client.v1.FlushBuffersH\0R\x0cflushBuffers\x12r\n\x15sankey_diag\ - ram_upload\x18\x0c\x20\x01(\x0b2<.bitdrift_public.protobuf.client.v1.San\ - keyPathUploadResponseH\0R\x13sankeyDiagramUpload\x12p\n\x16sankey_intent\ - _response\x18\r\x20\x01(\x0b28.bitdrift_public.protobuf.client.v1.Sankey\ - IntentResponseH\0R\x14sankeyIntentResponse\x12e\n\x0fartifact_upload\x18\ - \x0e\x20\x01(\x0b2:.bitdrift_public.protobuf.client.v1.UploadArtifactRes\ - ponseH\0R\x0eartifactUpload\x12k\n\x0fartifact_intent\x18\x0f\x20\x01(\ - \x0b2@.bitdrift_public.protobuf.client.v1.UploadArtifactIntentResponseH\ - \0R\x0eartifactIntentB\x14\n\rresponse_type\x12\x03\xf8B\x01J\x04\x08\n\ - \x10\x0bJ\x04\x08\x0b\x10\x0c2x\n\nApiService\x12j\n\x03Mux\x12..bitdrif\ - t_public.protobuf.client.v1.ApiRequest\x1a/.bitdrift_public.protobuf.cli\ - ent.v1.ApiResponse(\x010\x01b\x06proto3\ + \x01\x02\x10\x01\x12\"\n\nsession_id\x18\x07\x20\x01(\tH\0R\tsessionId\ + \x88\x01\x01\x1af\n\rMetadataEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ + \x03key\x12?\n\x05value\x18\x02\x20\x01(\x0b2).bitdrift_public.protobuf.\ + logging.v1.DataR\x05value:\x028\x01B\r\n\x0b_session_idJ\x04\x08\x03\x10\ + \x04\"\xd4\x02\n\x1cUploadArtifactIntentResponse\x12(\n\x0bintent_uuid\ + \x18\x01\x20\x01(\tR\nintentUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x83\x01\ + \n\x12upload_immediately\x18\x03\x20\x01(\x0b2R.bitdrift_public.protobuf\ + .client.v1.UploadArtifactIntentResponse.UploadImmediatelyH\0R\x11uploadI\ + mmediately\x12[\n\x04drop\x18\x04\x20\x01(\x0b2E.bitdrift_public.protobu\ + f.client.v1.UploadArtifactIntentResponse.DropH\0R\x04drop\x1a\x13\n\x11U\ + ploadImmediately\x1a\x06\n\x04DropB\n\n\x08decision\"\xba\x04\n\x15Uploa\ + dArtifactRequest\x12(\n\x0bupload_uuid\x18\x01\x20\x01(\tR\nuploadUuidB\ + \x07\xfaB\x04r\x02\x10\x01\x12\x20\n\x07type_id\x18\x02\x20\x01(\tR\x06t\ + ypeIdB\x07\xfaB\x04r\x02\x10\x01\x12\x1a\n\x08contents\x18\x03\x20\x01(\ + \x0cR\x08contents\x12(\n\x0bartifact_id\x18\x04\x20\x01(\tR\nartifactIdB\ + \x07\xfaB\x04r\x02\x10\x01\x12s\n\x0estate_metadata\x18\x05\x20\x03(\x0b\ + 2L.bitdrift_public.protobuf.client.v1.UploadArtifactRequest.StateMetadat\ + aEntryR\rstateMetadata\x128\n\x04time\x18\x06\x20\x01(\x0b2\x1a.google.p\ + rotobuf.TimestampR\x04timeB\x08\xfaB\x05\x8a\x01\x02\x10\x01\x12\x1d\n\n\ + session_id\x18\x07\x20\x01(\tR\tsessionId\x12T\n\rfeature_flags\x18\x08\ + \x20\x03(\x0b2/.bitdrift_public.protobuf.client.v1.FeatureFlagR\x0cfeatu\ + reFlags\x1ak\n\x12StateMetadataEntry\x12\x10\n\x03key\x18\x01\x20\x01(\t\ + R\x03key\x12?\n\x05value\x18\x02\x20\x01(\x0b2).bitdrift_public.protobuf\ + .logging.v1.DataR\x05value:\x028\x01\"X\n\x16UploadArtifactResponse\x12(\ + \n\x0bupload_uuid\x18\x01\x20\x01(\tR\nuploadUuidB\x07\xfaB\x04r\x02\x10\ + \x01\x12\x14\n\x05error\x18\x02\x20\x01(\tR\x05error\"\xf7\x02\n\x11Hand\ + shakeResponse\x12m\n\x0fstream_settings\x18\x01\x20\x01(\x0b2D.bitdrift_\ + public.protobuf.client.v1.HandshakeResponse.StreamSettingsR\x0estreamSet\ + tings\x12>\n\x1bconfiguration_update_status\x18\x02\x20\x01(\rR\x19confi\ + gurationUpdateStatus\x12A\n\x1bopaque_client_state_to_echo\x18\x03\x20\ + \x01(\x0cH\0R\x17opaqueClientStateToEcho\x88\x01\x01\x1aP\n\x0eStreamSet\ + tings\x12>\n\rping_interval\x18\x01\x20\x01(\x0b2\x19.google.protobuf.Du\ + rationR\x0cpingIntervalB\x1e\n\x1c_opaque_client_state_to_echo\"I\n\x0bR\ + ateLimited\x12:\n\x0bretry_after\x18\x01\x20\x01(\x0b2\x19.google.protob\ + uf.DurationR\nretryAfter\"\xca\x01\n\x11LogUploadResponse\x12(\n\x0buplo\ + ad_uuid\x18\x01\x20\x01(\tR\nuploadUuidB\x07\xfaB\x04r\x02\x10\x01\x12\ + \x14\n\x05error\x18\x02\x20\x01(\tR\x05error\x12!\n\x0clogs_dropped\x18\ + \x03\x20\x01(\rR\x0blogsDropped\x12R\n\x0crate_limited\x18\x04\x20\x01(\ + \x0b2/.bitdrift_public.protobuf.client.v1.RateLimitedR\x0brateLimited\"\ + \x9e\n\n\x12StatsUploadRequest\x12(\n\x0bupload_uuid\x18\x01\x20\x01(\tR\ + \nuploadUuidB\x07\xfaB\x04r\x02\x10\x01\x12e\n\x08snapshot\x18\x02\x20\ + \x03(\x0b2?.bitdrift_public.protobuf.client.v1.StatsUploadRequest.Snapsh\ + otR\x08snapshotB\x08\xfaB\x05\x92\x01\x02\x08\x01\x123\n\x07sent_at\x18\ + \x03\x20\x01(\x0b2\x1a.google.protobuf.TimestampR\x06sentAt\x12h\n\ruplo\ + ad_reason\x18\x04\x20\x01(\x0e2C.bitdrift_public.protobuf.client.v1.Stat\ + sUploadRequest.UploadReasonR\x0cuploadReason\x1a\xe9\x06\n\x08Snapshot\ + \x12K\n\x07metrics\x18\x01\x20\x01(\x0b2/.bitdrift_public.protobuf.clien\ + t.v1.MetricsListH\0R\x07metrics\x12l\n\naggregated\x18\x02\x20\x01(\x0b2\ + J.bitdrift_public.protobuf.client.v1.StatsUploadRequest.Snapshot.Aggrega\ + tedH\x01R\naggregated\x12\x86\x01\n\x13metric_id_overflows\x18\x03\x20\ + \x03(\x0b2V.bitdrift_public.protobuf.client.v1.StatsUploadRequest.Snapsh\ + ot.MetricIdOverflowsEntryR\x11metricIdOverflows\x12\x86\x01\n\x13workflo\ + w_debug_data\x18\x04\x20\x03(\x0b2V.bitdrift_public.protobuf.client.v1.S\ + tatsUploadRequest.Snapshot.WorkflowDebugDataEntryR\x11workflowDebugData\ + \x1a\x90\x01\n\nAggregated\x12G\n\x0cperiod_start\x18\x04\x20\x01(\x0b2\ + \x1a.google.protobuf.TimestampR\x0bperiodStartB\x08\xfaB\x05\x8a\x01\x02\ + \x10\x01\x129\n\nperiod_end\x18\x05\x20\x01(\x0b2\x1a.google.protobuf.Ti\ + mestampR\tperiodEnd\x1aD\n\x16MetricIdOverflowsEntry\x12\x10\n\x03key\ + \x18\x01\x20\x01(\tR\x03key\x12\x14\n\x05value\x18\x02\x20\x01(\x04R\x05\ + value:\x028\x01\x1a\x8c\x01\n\x16WorkflowDebugDataEntry\x12\x10\n\x03key\ + \x18\x01\x20\x01(\tR\x03key\x12\\\n\x05value\x18\x02\x20\x01(\x0b2F.bitd\ + rift_public.protobuf.client.v1.DebugDataRequest.WorkflowDebugDataR\x05va\ + lue:\x028\x01B\x14\n\rsnapshot_type\x12\x03\xf8B\x01B\x12\n\x0boccurred_\ + at\x12\x03\xf8B\x01\"l\n\x0cUploadReason\x12\x1d\n\x19UPLOAD_REASON_UNSP\ + ECIFIED\x10\0\x12\x1a\n\x16UPLOAD_REASON_PERIODIC\x10\x01\x12!\n\x1dUPLO\ + AD_REASON_EVENT_TRIGGERED\x10\x02\"~\n\x13StatsUploadResponse\x12(\n\x0b\ + upload_uuid\x18\x01\x20\x01(\tR\nuploadUuidB\x07\xfaB\x04r\x02\x10\x01\ + \x12\x14\n\x05error\x18\x02\x20\x01(\tR\x05error\x12'\n\x0fmetrics_dropp\ + ed\x18\x03\x20\x01(\rR\x0emetricsDropped\"\x0e\n\x0cPongResponse\"\xa1\ + \x06\n\x13ConfigurationUpdate\x12#\n\rversion_nonce\x18\x01\x20\x01(\tR\ + \x0cversionNonce\x12v\n\x12state_of_the_world\x18\x02\x20\x01(\x0b2G.bit\ + drift_public.protobuf.client.v1.ConfigurationUpdate.StateOfTheWorldH\0R\ + \x0fstateOfTheWorld\x1a\xdd\x04\n\x0fStateOfTheWorld\x12b\n\x12buffer_co\ + nfig_list\x18\x03\x20\x01(\x0b24.bitdrift_public.protobuf.config.v1.Buff\ + erConfigListR\x10bufferConfigList\x12u\n\x17workflows_configuration\x18\ + \x04\x20\x01(\x0b2<.bitdrift_public.protobuf.workflow.v1.WorkflowsConfig\ + urationR\x16workflowsConfiguration\x12k\n\x14bdtail_configuration\x18\ + \x06\x20\x01(\x0b28.bitdrift_public.protobuf.bdtail.v1.BdTailConfigurati\ + onsR\x13bdtailConfiguration\x12m\n\x15filters_configuration\x18\x08\x20\ + \x01(\x0b28.bitdrift_public.protobuf.filter.v1.FiltersConfigurationR\x14\ + filtersConfiguration\x12e\n\x0fdebug_workflows\x18\t\x20\x01(\x0b2<.bitd\ + rift_public.protobuf.workflow.v1.WorkflowsConfigurationR\x0edebugWorkflo\ + wsJ\x04\x08\x02\x10\x03J\x04\x08\x07\x10\x08R\x08mll_listR\x16insights_c\ + onfigurationB\r\n\x0bupdate_type\"{\n\rRuntimeUpdate\x12#\n\rversion_non\ + ce\x18\x01\x20\x01(\tR\x0cversionNonce\x12E\n\x07runtime\x18\x02\x20\x01\ + (\x0b2+.bitdrift_public.protobuf.client.v1.RuntimeR\x07runtime\"\xa7\x01\ + \n\rErrorShutdown\x12\x1f\n\x0bgrpc_status\x18\x01\x20\x01(\x05R\ngrpcSt\ + atus\x12!\n\x0cgrpc_message\x18\x02\x20\x01(\tR\x0bgrpcMessage\x12R\n\ + \x0crate_limited\x18\x03\x20\x01(\x0b2/.bitdrift_public.protobuf.client.\ + v1.RateLimitedR\x0brateLimited\"4\n\x0cFlushBuffers\x12$\n\x0ebuffer_id_\ + list\x18\x01\x20\x03(\tR\x0cbufferIdList\"Z\n\x18SankeyPathUploadRespons\ + e\x12(\n\x0bupload_uuid\x18\x01\x20\x01(\tR\nuploadUuidB\x07\xfaB\x04r\ + \x02\x10\x01\x12\x14\n\x05error\x18\x02\x20\x01(\tR\x05error\"\xcb\x02\n\ + \x14SankeyIntentResponse\x12(\n\x0bintent_uuid\x18\x01\x20\x01(\tR\ninte\ + ntUuidB\x07\xfaB\x04r\x02\x10\x01\x12{\n\x12upload_immediately\x18\x03\ + \x20\x01(\x0b2J.bitdrift_public.protobuf.client.v1.SankeyIntentResponse.\ + UploadImmediatelyH\0R\x11uploadImmediately\x12S\n\x04drop\x18\x04\x20\ + \x01(\x0b2=.bitdrift_public.protobuf.client.v1.SankeyIntentResponse.Drop\ + H\0R\x04drop\x1a\x13\n\x11UploadImmediately\x1a\x06\n\x04DropB\n\n\x08de\ + cisionJ\x04\x08\x02\x10\x03R\x08decision\"\xb5\x08\n\x10DebugDataRequest\ + \x12{\n\x13workflow_debug_data\x18\x01\x20\x03(\x0b2K.bitdrift_public.pr\ + otobuf.client.v1.DebugDataRequest.WorkflowDebugDataEntryR\x11workflowDeb\ + ugData\x1a\x87\x02\n\x1bWorkflowTransitionDebugData\x12+\n\x10transition\ + _index\x18\x01\x20\x01(\rH\0R\x0ftransitionIndex\x12/\n\x12timeout_trans\ + ition\x18\x02\x20\x01(\x08H\0R\x11timeoutTransition\x12)\n\x10transition\ + _count\x18\x03\x20\x01(\x04R\x0ftransitionCount\x12L\n\x14last_transitio\ + n_time\x18\x04\x20\x01(\x0b2\x1a.google.protobuf.TimestampR\x12lastTrans\ + itionTimeB\x11\n\x0ftransition_type\x1a\x8c\x01\n\x16WorkflowStateDebugD\ + ata\x12r\n\x0btransitions\x18\x01\x20\x03(\x0b2P.bitdrift_public.protobu\ + f.client.v1.DebugDataRequest.WorkflowTransitionDebugDataR\x0btransitions\ + \x1a\xfb\x02\n\x11WorkflowDebugData\x12j\n\x06states\x18\x01\x20\x03(\ + \x0b2R.bitdrift_public.protobuf.client.v1.DebugDataRequest.WorkflowDebug\ + Data.StatesEntryR\x06states\x12q\n\x0bstart_reset\x18\x02\x20\x01(\x0b2P\ + .bitdrift_public.protobuf.client.v1.DebugDataRequest.WorkflowTransitionD\ + ebugDataR\nstartReset\x1a\x86\x01\n\x0bStatesEntry\x12\x10\n\x03key\x18\ + \x01\x20\x01(\tR\x03key\x12a\n\x05value\x18\x02\x20\x01(\x0b2K.bitdrift_\ + public.protobuf.client.v1.DebugDataRequest.WorkflowStateDebugDataR\x05va\ + lue:\x028\x01\x1a\x8c\x01\n\x16WorkflowDebugDataEntry\x12\x10\n\x03key\ + \x18\x01\x20\x01(\tR\x03key\x12\\\n\x05value\x18\x02\x20\x01(\x0b2F.bitd\ + rift_public.protobuf.client.v1.DebugDataRequest.WorkflowDebugDataR\x05va\ + lue:\x028\x01\"\x15\n\x13StateUpdateResponse\"\x86\x0b\n\x0bApiResponse\ + \x12U\n\thandshake\x18\x01\x20\x01(\x0b25.bitdrift_public.protobuf.clien\ + t.v1.HandshakeResponseH\0R\thandshake\x12V\n\nlog_upload\x18\x02\x20\x01\ + (\x0b25.bitdrift_public.protobuf.client.v1.LogUploadResponseH\0R\tlogUpl\ + oad\x12i\n\x11log_upload_intent\x18\x08\x20\x01(\x0b2;.bitdrift_public.p\ + rotobuf.client.v1.LogUploadIntentResponseH\0R\x0flogUploadIntent\x12\\\n\ + \x0cstats_upload\x18\x07\x20\x01(\x0b27.bitdrift_public.protobuf.client.\ + v1.StatsUploadResponseH\0R\x0bstatsUpload\x12F\n\x04pong\x18\x03\x20\x01\ + (\x0b20.bitdrift_public.protobuf.client.v1.PongResponseH\0R\x04pong\x12l\ + \n\x14configuration_update\x18\x04\x20\x01(\x0b27.bitdrift_public.protob\ + uf.client.v1.ConfigurationUpdateH\0R\x13configurationUpdate\x12Z\n\x0eru\ + ntime_update\x18\x05\x20\x01(\x0b21.bitdrift_public.protobuf.client.v1.R\ + untimeUpdateH\0R\rruntimeUpdate\x12Z\n\x0eerror_shutdown\x18\x06\x20\x01\ + (\x0b21.bitdrift_public.protobuf.client.v1.ErrorShutdownH\0R\rerrorShutd\ + own\x12W\n\rflush_buffers\x18\t\x20\x01(\x0b20.bitdrift_public.protobuf.\ + client.v1.FlushBuffersH\0R\x0cflushBuffers\x12r\n\x15sankey_diagram_uplo\ + ad\x18\x0c\x20\x01(\x0b2<.bitdrift_public.protobuf.client.v1.SankeyPathU\ + ploadResponseH\0R\x13sankeyDiagramUpload\x12p\n\x16sankey_intent_respons\ + e\x18\r\x20\x01(\x0b28.bitdrift_public.protobuf.client.v1.SankeyIntentRe\ + sponseH\0R\x14sankeyIntentResponse\x12e\n\x0fartifact_upload\x18\x0e\x20\ + \x01(\x0b2:.bitdrift_public.protobuf.client.v1.UploadArtifactResponseH\0\ + R\x0eartifactUpload\x12k\n\x0fartifact_intent\x18\x0f\x20\x01(\x0b2@.bit\ + drift_public.protobuf.client.v1.UploadArtifactIntentResponseH\0R\x0earti\ + factIntent\x12\\\n\x0cstate_update\x18\x10\x20\x01(\x0b27.bitdrift_publi\ + c.protobuf.client.v1.StateUpdateResponseH\0R\x0bstateUpdateB\x14\n\rresp\ + onse_type\x12\x03\xf8B\x01J\x04\x08\n\x10\x0bJ\x04\x08\x0b\x10\x0c2x\n\n\ + ApiService\x12j\n\x03Mux\x12..bitdrift_public.protobuf.client.v1.ApiRequ\ + est\x1a/.bitdrift_public.protobuf.client.v1.ApiResponse(\x010\x01b\x06pr\ + oto3\ "; /// `FileDescriptorProto` object which was a source for this generated file @@ -9782,8 +10463,9 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { deps.push(::protobuf::well_known_types::duration::file_descriptor().clone()); deps.push(::protobuf::well_known_types::timestamp::file_descriptor().clone()); deps.push(super::validate::file_descriptor().clone()); - let mut messages = ::std::vec::Vec::with_capacity(45); + let mut messages = ::std::vec::Vec::with_capacity(49); messages.push(ClientKillFile::generated_message_descriptor_data()); + messages.push(StateUpdateRequest::generated_message_descriptor_data()); messages.push(HandshakeRequest::generated_message_descriptor_data()); messages.push(LogUploadIntentRequest::generated_message_descriptor_data()); messages.push(LogUploadIntentResponse::generated_message_descriptor_data()); @@ -9810,7 +10492,10 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { messages.push(SankeyPathUploadResponse::generated_message_descriptor_data()); messages.push(SankeyIntentResponse::generated_message_descriptor_data()); messages.push(DebugDataRequest::generated_message_descriptor_data()); + messages.push(StateUpdateResponse::generated_message_descriptor_data()); messages.push(ApiResponse::generated_message_descriptor_data()); + messages.push(state_update_request::StartedSession::generated_message_descriptor_data()); + messages.push(state_update_request::OpaqueEntityUpdate::generated_message_descriptor_data()); messages.push(log_upload_intent_request::WorkflowActionUpload::generated_message_descriptor_data()); messages.push(log_upload_intent_request::ExplicitSessionCapture::generated_message_descriptor_data()); messages.push(log_upload_intent_response::UploadImmediately::generated_message_descriptor_data()); diff --git a/bd-proto/src/protos/client/with_source/api.rs b/bd-proto/src/protos/client/with_source/api.rs index 2963efe35..fc0a3a99a 100644 --- a/bd-proto/src/protos/client/with_source/api.rs +++ b/bd-proto/src/protos/client/with_source/api.rs @@ -179,6 +179,422 @@ impl ::protobuf::reflect::ProtobufValue for ClientKillFile { type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; } +/// This is sent both in the initial handshake as well as mid-stream if any of the attributes have +/// changed. The handshake will fill in all values as part of an initial update. +// @@protoc_insertion_point(message:bitdrift_public.protobuf.client.v1.StateUpdateRequest) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct StateUpdateRequest { + // message fields + /// The opaque entity update. + // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.opaque_entity_update) + pub opaque_entity_update: ::protobuf::MessageField, + /// The list of started sessions. + // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.started_sessions) + pub started_sessions: ::std::vec::Vec, + // special fields + // @@protoc_insertion_point(special_field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a StateUpdateRequest { + fn default() -> &'a StateUpdateRequest { + ::default_instance() + } +} + +impl StateUpdateRequest { + pub fn new() -> StateUpdateRequest { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, state_update_request::OpaqueEntityUpdate>( + "opaque_entity_update", + |m: &StateUpdateRequest| { &m.opaque_entity_update }, + |m: &mut StateUpdateRequest| { &mut m.opaque_entity_update }, + )); + fields.push(::protobuf::reflect::rt::v2::make_vec_simpler_accessor::<_, _>( + "started_sessions", + |m: &StateUpdateRequest| { &m.started_sessions }, + |m: &mut StateUpdateRequest| { &mut m.started_sessions }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "StateUpdateRequest", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for StateUpdateRequest { + const NAME: &'static str = "StateUpdateRequest"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.opaque_entity_update)?; + }, + 18 => { + self.started_sessions.push(is.read_message()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.opaque_entity_update.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + for value in &self.started_sessions { + let len = value.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.opaque_entity_update.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(1, v, os)?; + } + for v in &self.started_sessions { + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; + }; + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> StateUpdateRequest { + StateUpdateRequest::new() + } + + fn clear(&mut self) { + self.opaque_entity_update.clear(); + self.started_sessions.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static StateUpdateRequest { + static instance: StateUpdateRequest = StateUpdateRequest { + opaque_entity_update: ::protobuf::MessageField::none(), + started_sessions: ::std::vec::Vec::new(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for StateUpdateRequest { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("StateUpdateRequest").unwrap()).clone() + } +} + +impl ::std::fmt::Display for StateUpdateRequest { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for StateUpdateRequest { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + +/// Nested message and enums of message `StateUpdateRequest` +pub mod state_update_request { + // @@protoc_insertion_point(message:bitdrift_public.protobuf.client.v1.StateUpdateRequest.StartedSession) + #[derive(PartialEq,Clone,Default,Debug)] + pub struct StartedSession { + // message fields + /// The session ID of the started session. + // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.StartedSession.session_id) + pub session_id: ::std::string::String, + /// The start time of the session. + // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.StartedSession.start_time) + pub start_time: ::protobuf::MessageField<::protobuf::well_known_types::timestamp::Timestamp>, + // special fields + // @@protoc_insertion_point(special_field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.StartedSession.special_fields) + pub special_fields: ::protobuf::SpecialFields, + } + + impl<'a> ::std::default::Default for &'a StartedSession { + fn default() -> &'a StartedSession { + ::default_instance() + } + } + + impl StartedSession { + pub fn new() -> StartedSession { + ::std::default::Default::default() + } + + pub(in super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(2); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_simpler_field_accessor::<_, _>( + "session_id", + |m: &StartedSession| { &m.session_id }, + |m: &mut StartedSession| { &mut m.session_id }, + )); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, ::protobuf::well_known_types::timestamp::Timestamp>( + "start_time", + |m: &StartedSession| { &m.start_time }, + |m: &mut StartedSession| { &mut m.start_time }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "StateUpdateRequest.StartedSession", + fields, + oneofs, + ) + } + } + + impl ::protobuf::Message for StartedSession { + const NAME: &'static str = "StartedSession"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.session_id = is.read_string()?; + }, + 18 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.start_time)?; + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if !self.session_id.is_empty() { + my_size += ::protobuf::rt::string_size(1, &self.session_id); + } + if let Some(v) = self.start_time.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if !self.session_id.is_empty() { + os.write_string(1, &self.session_id)?; + } + if let Some(v) = self.start_time.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(2, v, os)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> StartedSession { + StartedSession::new() + } + + fn clear(&mut self) { + self.session_id.clear(); + self.start_time.clear(); + self.special_fields.clear(); + } + + fn default_instance() -> &'static StartedSession { + static instance: StartedSession = StartedSession { + session_id: ::std::string::String::new(), + start_time: ::protobuf::MessageField::none(), + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } + } + + impl ::protobuf::MessageFull for StartedSession { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| super::file_descriptor().message_by_package_relative_name("StateUpdateRequest.StartedSession").unwrap()).clone() + } + } + + impl ::std::fmt::Display for StartedSession { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } + } + + impl ::protobuf::reflect::ProtobufValue for StartedSession { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; + } + + // @@protoc_insertion_point(message:bitdrift_public.protobuf.client.v1.StateUpdateRequest.OpaqueEntityUpdate) + #[derive(PartialEq,Clone,Default,Debug)] + pub struct OpaqueEntityUpdate { + // message fields + /// If one has been supplied, the opaque entity ID. If an update is sent that nulls this out + /// it means that the unique entity is no longer bound (for example after a logout). + // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.OpaqueEntityUpdate.opaque_entity_id) + pub opaque_entity_id: ::std::option::Option<::std::string::String>, + // special fields + // @@protoc_insertion_point(special_field:bitdrift_public.protobuf.client.v1.StateUpdateRequest.OpaqueEntityUpdate.special_fields) + pub special_fields: ::protobuf::SpecialFields, + } + + impl<'a> ::std::default::Default for &'a OpaqueEntityUpdate { + fn default() -> &'a OpaqueEntityUpdate { + ::default_instance() + } + } + + impl OpaqueEntityUpdate { + pub fn new() -> OpaqueEntityUpdate { + ::std::default::Default::default() + } + + pub(in super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(1); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + fields.push(::protobuf::reflect::rt::v2::make_option_accessor::<_, _>( + "opaque_entity_id", + |m: &OpaqueEntityUpdate| { &m.opaque_entity_id }, + |m: &mut OpaqueEntityUpdate| { &mut m.opaque_entity_id }, + )); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "StateUpdateRequest.OpaqueEntityUpdate", + fields, + oneofs, + ) + } + } + + impl ::protobuf::Message for OpaqueEntityUpdate { + const NAME: &'static str = "OpaqueEntityUpdate"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + 10 => { + self.opaque_entity_id = ::std::option::Option::Some(is.read_string()?); + }, + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + if let Some(v) = self.opaque_entity_id.as_ref() { + my_size += ::protobuf::rt::string_size(1, &v); + } + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + if let Some(v) = self.opaque_entity_id.as_ref() { + os.write_string(1, v)?; + } + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> OpaqueEntityUpdate { + OpaqueEntityUpdate::new() + } + + fn clear(&mut self) { + self.opaque_entity_id = ::std::option::Option::None; + self.special_fields.clear(); + } + + fn default_instance() -> &'static OpaqueEntityUpdate { + static instance: OpaqueEntityUpdate = OpaqueEntityUpdate { + opaque_entity_id: ::std::option::Option::None, + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } + } + + impl ::protobuf::MessageFull for OpaqueEntityUpdate { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| super::file_descriptor().message_by_package_relative_name("StateUpdateRequest.OpaqueEntityUpdate").unwrap()).clone() + } + } + + impl ::std::fmt::Display for OpaqueEntityUpdate { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } + } + + impl ::protobuf::reflect::ProtobufValue for OpaqueEntityUpdate { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; + } +} + /// The initial request sent over the stream. // @@protoc_insertion_point(message:bitdrift_public.protobuf.client.v1.HandshakeRequest) #[derive(PartialEq,Clone,Default,Debug)] @@ -186,10 +602,7 @@ pub struct HandshakeRequest { // message fields /// A set of opaque metadata that identifies the connecting device. These will /// remain static for the duration of this stream. - /// TODO(snowp): Support updating these throughout the session. - /// TODO(snowp): Improve the story for this when parameters change during a - /// logging period, e.g. if we capture multiple process restarts that may span - /// versions. + /// TODO(snowp): Support updating these throughout the session / move to StateUpdateRequest. // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.HandshakeRequest.static_device_metadata) pub static_device_metadata: ::std::collections::HashMap<::std::string::String, super::payload::Data>, /// If the client has an active configuration, previously obtained via a ConfigurationUpdate @@ -216,6 +629,12 @@ pub struct HandshakeRequest { /// value (which may be empty to clear existing state). // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.HandshakeRequest.opaque_client_state) pub opaque_client_state: ::std::option::Option<::std::vec::Vec>, + /// When the handshake request is sent an initial state update will be included with both + /// the opaque entity ID (if provided) as well as at least the current session. There may be + /// multiple sessions included if some session transitions have happened while offline and have + /// not yet been sent to the server. + // @@protoc_insertion_point(field:bitdrift_public.protobuf.client.v1.HandshakeRequest.state_update) + pub state_update: ::protobuf::MessageField, // special fields // @@protoc_insertion_point(special_field:bitdrift_public.protobuf.client.v1.HandshakeRequest.special_fields) pub special_fields: ::protobuf::SpecialFields, @@ -233,7 +652,7 @@ impl HandshakeRequest { } fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(6); + let mut fields = ::std::vec::Vec::with_capacity(7); let mut oneofs = ::std::vec::Vec::with_capacity(0); fields.push(::protobuf::reflect::rt::v2::make_map_simpler_accessor_new::<_, _>( "static_device_metadata", @@ -265,6 +684,11 @@ impl HandshakeRequest { |m: &HandshakeRequest| { &m.opaque_client_state }, |m: &mut HandshakeRequest| { &mut m.opaque_client_state }, )); + fields.push(::protobuf::reflect::rt::v2::make_message_field_accessor::<_, StateUpdateRequest>( + "state_update", + |m: &HandshakeRequest| { &m.state_update }, + |m: &mut HandshakeRequest| { &mut m.state_update }, + )); ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( "HandshakeRequest", fields, @@ -313,6 +737,9 @@ impl ::protobuf::Message for HandshakeRequest { 66 => { self.opaque_client_state = ::std::option::Option::Some(is.read_bytes()?); }, + 74 => { + ::protobuf::rt::read_singular_message_into_field(is, &mut self.state_update)?; + }, tag => { ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; }, @@ -347,6 +774,10 @@ impl ::protobuf::Message for HandshakeRequest { if let Some(v) = self.opaque_client_state.as_ref() { my_size += ::protobuf::rt::bytes_size(8, &v); } + if let Some(v) = self.state_update.as_ref() { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + } my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); self.special_fields.cached_size().set(my_size as u32); my_size @@ -378,6 +809,9 @@ impl ::protobuf::Message for HandshakeRequest { if let Some(v) = self.opaque_client_state.as_ref() { os.write_bytes(8, v)?; } + if let Some(v) = self.state_update.as_ref() { + ::protobuf::rt::write_message_field_with_cached_size(9, v, os)?; + } os.write_unknown_fields(self.special_fields.unknown_fields())?; ::std::result::Result::Ok(()) } @@ -401,6 +835,7 @@ impl ::protobuf::Message for HandshakeRequest { self.previous_disconnect_reason.clear(); self.sleep_mode = false; self.opaque_client_state = ::std::option::Option::None; + self.state_update.clear(); self.special_fields.clear(); } @@ -2795,8 +3230,57 @@ impl ApiRequest { } } + // .bitdrift_public.protobuf.client.v1.StateUpdateRequest state_update = 15; + + pub fn state_update(&self) -> &StateUpdateRequest { + match self.request_type { + ::std::option::Option::Some(api_request::Request_type::StateUpdate(ref v)) => v, + _ => ::default_instance(), + } + } + + pub fn clear_state_update(&mut self) { + self.request_type = ::std::option::Option::None; + } + + pub fn has_state_update(&self) -> bool { + match self.request_type { + ::std::option::Option::Some(api_request::Request_type::StateUpdate(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_state_update(&mut self, v: StateUpdateRequest) { + self.request_type = ::std::option::Option::Some(api_request::Request_type::StateUpdate(v)) + } + + // Mutable pointer to the field. + pub fn mut_state_update(&mut self) -> &mut StateUpdateRequest { + if let ::std::option::Option::Some(api_request::Request_type::StateUpdate(_)) = self.request_type { + } else { + self.request_type = ::std::option::Option::Some(api_request::Request_type::StateUpdate(StateUpdateRequest::new())); + } + match self.request_type { + ::std::option::Option::Some(api_request::Request_type::StateUpdate(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_state_update(&mut self) -> StateUpdateRequest { + if self.has_state_update() { + match self.request_type.take() { + ::std::option::Option::Some(api_request::Request_type::StateUpdate(v)) => v, + _ => panic!(), + } + } else { + StateUpdateRequest::new() + } + } + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(12); + let mut fields = ::std::vec::Vec::with_capacity(13); let mut oneofs = ::std::vec::Vec::with_capacity(1); fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, HandshakeRequest>( "handshake", @@ -2882,6 +3366,13 @@ impl ApiRequest { ApiRequest::mut_debug_data, ApiRequest::set_debug_data, )); + fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, StateUpdateRequest>( + "state_update", + ApiRequest::has_state_update, + ApiRequest::state_update, + ApiRequest::mut_state_update, + ApiRequest::set_state_update, + )); oneofs.push(api_request::Request_type::generated_oneof_descriptor_data()); ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( "ApiRequest", @@ -2937,6 +3428,9 @@ impl ::protobuf::Message for ApiRequest { 114 => { self.request_type = ::std::option::Option::Some(api_request::Request_type::DebugData(is.read_message()?)); }, + 122 => { + self.request_type = ::std::option::Option::Some(api_request::Request_type::StateUpdate(is.read_message()?)); + }, tag => { ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; }, @@ -2999,6 +3493,10 @@ impl ::protobuf::Message for ApiRequest { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; }, + &api_request::Request_type::StateUpdate(ref v) => { + let len = v.compute_size(); + my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }, }; } my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); @@ -3045,6 +3543,9 @@ impl ::protobuf::Message for ApiRequest { &api_request::Request_type::DebugData(ref v) => { ::protobuf::rt::write_message_field_with_cached_size(14, v, os)?; }, + &api_request::Request_type::StateUpdate(ref v) => { + ::protobuf::rt::write_message_field_with_cached_size(15, v, os)?; + }, }; } os.write_unknown_fields(self.special_fields.unknown_fields())?; @@ -3076,6 +3577,7 @@ impl ::protobuf::Message for ApiRequest { self.request_type = ::std::option::Option::None; self.request_type = ::std::option::Option::None; self.request_type = ::std::option::Option::None; + self.request_type = ::std::option::Option::None; self.special_fields.clear(); } @@ -3135,6 +3637,8 @@ pub mod api_request { ArtifactIntent(super::UploadArtifactIntentRequest), // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.client.v1.ApiRequest.debug_data) DebugData(super::DebugDataRequest), + // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.client.v1.ApiRequest.state_update) + StateUpdate(super::StateUpdateRequest), } impl ::protobuf::Oneof for Request_type { @@ -8675,6 +9179,109 @@ pub mod debug_data_request { } } +// @@protoc_insertion_point(message:bitdrift_public.protobuf.client.v1.StateUpdateResponse) +#[derive(PartialEq,Clone,Default,Debug)] +pub struct StateUpdateResponse { + // special fields + // @@protoc_insertion_point(special_field:bitdrift_public.protobuf.client.v1.StateUpdateResponse.special_fields) + pub special_fields: ::protobuf::SpecialFields, +} + +impl<'a> ::std::default::Default for &'a StateUpdateResponse { + fn default() -> &'a StateUpdateResponse { + ::default_instance() + } +} + +impl StateUpdateResponse { + pub fn new() -> StateUpdateResponse { + ::std::default::Default::default() + } + + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { + let mut fields = ::std::vec::Vec::with_capacity(0); + let mut oneofs = ::std::vec::Vec::with_capacity(0); + ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( + "StateUpdateResponse", + fields, + oneofs, + ) + } +} + +impl ::protobuf::Message for StateUpdateResponse { + const NAME: &'static str = "StateUpdateResponse"; + + fn is_initialized(&self) -> bool { + true + } + + fn merge_from(&mut self, is: &mut ::protobuf::CodedInputStream<'_>) -> ::protobuf::Result<()> { + while let Some(tag) = is.read_raw_tag_or_eof()? { + match tag { + tag => { + ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; + }, + }; + } + ::std::result::Result::Ok(()) + } + + // Compute sizes of nested messages + #[allow(unused_variables)] + fn compute_size(&self) -> u64 { + let mut my_size = 0; + my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); + self.special_fields.cached_size().set(my_size as u32); + my_size + } + + fn write_to_with_cached_sizes(&self, os: &mut ::protobuf::CodedOutputStream<'_>) -> ::protobuf::Result<()> { + os.write_unknown_fields(self.special_fields.unknown_fields())?; + ::std::result::Result::Ok(()) + } + + fn special_fields(&self) -> &::protobuf::SpecialFields { + &self.special_fields + } + + fn mut_special_fields(&mut self) -> &mut ::protobuf::SpecialFields { + &mut self.special_fields + } + + fn new() -> StateUpdateResponse { + StateUpdateResponse::new() + } + + fn clear(&mut self) { + self.special_fields.clear(); + } + + fn default_instance() -> &'static StateUpdateResponse { + static instance: StateUpdateResponse = StateUpdateResponse { + special_fields: ::protobuf::SpecialFields::new(), + }; + &instance + } +} + +impl ::protobuf::MessageFull for StateUpdateResponse { + fn descriptor() -> ::protobuf::reflect::MessageDescriptor { + static descriptor: ::protobuf::rt::Lazy<::protobuf::reflect::MessageDescriptor> = ::protobuf::rt::Lazy::new(); + descriptor.get(|| file_descriptor().message_by_package_relative_name("StateUpdateResponse").unwrap()).clone() + } +} + +impl ::std::fmt::Display for StateUpdateResponse { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + ::protobuf::text_format::fmt(self, f) + } +} + +impl ::protobuf::reflect::ProtobufValue for StateUpdateResponse { + type RuntimeType = ::protobuf::reflect::rt::RuntimeTypeMessage; +} + /// A multiplexed response sent over the bitdrift API. // @@protoc_insertion_point(message:bitdrift_public.protobuf.client.v1.ApiResponse) #[derive(PartialEq,Clone,Default,Debug)] @@ -9334,8 +9941,57 @@ impl ApiResponse { } } + // .bitdrift_public.protobuf.client.v1.StateUpdateResponse state_update = 16; + + pub fn state_update(&self) -> &StateUpdateResponse { + match self.response_type { + ::std::option::Option::Some(api_response::Response_type::StateUpdate(ref v)) => v, + _ => ::default_instance(), + } + } + + pub fn clear_state_update(&mut self) { + self.response_type = ::std::option::Option::None; + } + + pub fn has_state_update(&self) -> bool { + match self.response_type { + ::std::option::Option::Some(api_response::Response_type::StateUpdate(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_state_update(&mut self, v: StateUpdateResponse) { + self.response_type = ::std::option::Option::Some(api_response::Response_type::StateUpdate(v)) + } + + // Mutable pointer to the field. + pub fn mut_state_update(&mut self) -> &mut StateUpdateResponse { + if let ::std::option::Option::Some(api_response::Response_type::StateUpdate(_)) = self.response_type { + } else { + self.response_type = ::std::option::Option::Some(api_response::Response_type::StateUpdate(StateUpdateResponse::new())); + } + match self.response_type { + ::std::option::Option::Some(api_response::Response_type::StateUpdate(ref mut v)) => v, + _ => panic!(), + } + } + + // Take field + pub fn take_state_update(&mut self) -> StateUpdateResponse { + if self.has_state_update() { + match self.response_type.take() { + ::std::option::Option::Some(api_response::Response_type::StateUpdate(v)) => v, + _ => panic!(), + } + } else { + StateUpdateResponse::new() + } + } + fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(13); + let mut fields = ::std::vec::Vec::with_capacity(14); let mut oneofs = ::std::vec::Vec::with_capacity(1); fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, HandshakeResponse>( "handshake", @@ -9428,6 +10084,13 @@ impl ApiResponse { ApiResponse::mut_artifact_intent, ApiResponse::set_artifact_intent, )); + fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, StateUpdateResponse>( + "state_update", + ApiResponse::has_state_update, + ApiResponse::state_update, + ApiResponse::mut_state_update, + ApiResponse::set_state_update, + )); oneofs.push(api_response::Response_type::generated_oneof_descriptor_data()); ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( "ApiResponse", @@ -9486,6 +10149,9 @@ impl ::protobuf::Message for ApiResponse { 122 => { self.response_type = ::std::option::Option::Some(api_response::Response_type::ArtifactIntent(is.read_message()?)); }, + 130 => { + self.response_type = ::std::option::Option::Some(api_response::Response_type::StateUpdate(is.read_message()?)); + }, tag => { ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; }, @@ -9552,6 +10218,10 @@ impl ::protobuf::Message for ApiResponse { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; }, + &api_response::Response_type::StateUpdate(ref v) => { + let len = v.compute_size(); + my_size += 2 + ::protobuf::rt::compute_raw_varint64_size(len) + len; + }, }; } my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); @@ -9601,6 +10271,9 @@ impl ::protobuf::Message for ApiResponse { &api_response::Response_type::ArtifactIntent(ref v) => { ::protobuf::rt::write_message_field_with_cached_size(15, v, os)?; }, + &api_response::Response_type::StateUpdate(ref v) => { + ::protobuf::rt::write_message_field_with_cached_size(16, v, os)?; + }, }; } os.write_unknown_fields(self.special_fields.unknown_fields())?; @@ -9633,6 +10306,7 @@ impl ::protobuf::Message for ApiResponse { self.response_type = ::std::option::Option::None; self.response_type = ::std::option::Option::None; self.response_type = ::std::option::Option::None; + self.response_type = ::std::option::Option::None; self.special_fields.clear(); } @@ -9694,6 +10368,8 @@ pub mod api_response { ArtifactUpload(super::UploadArtifactResponse), // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.client.v1.ApiResponse.artifact_intent) ArtifactIntent(super::UploadArtifactIntentResponse), + // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.client.v1.ApiResponse.state_update) + StateUpdate(super::StateUpdateResponse), } impl ::protobuf::Oneof for Response_type { @@ -9725,19 +10401,29 @@ static file_descriptor_proto_data: &'static [u8] = b"\ protobuf/timestamp.proto\x1a\x17validate/validate.proto\"m\n\x0eClientKi\ llFile\x12\x20\n\x0capi_key_hash\x18\x01\x20\x01(\x0cR\napiKeyHash\x129\ \n\nkill_until\x18\x02\x20\x01(\x0b2\x1a.google.protobuf.TimestampR\tkil\ - lUntil\"\xcc\x04\n\x10HandshakeRequest\x12\x84\x01\n\x16static_device_me\ - tadata\x18\x01\x20\x03(\x0b2N.bitdrift_public.protobuf.client.v1.Handsha\ - keRequest.StaticDeviceMetadataEntryR\x14staticDeviceMetadata\x12>\n\x1bc\ - onfiguration_version_nonce\x18\x03\x20\x01(\tR\x19configurationVersionNo\ - nce\x122\n\x15runtime_version_nonce\x18\x04\x20\x01(\tR\x13runtimeVersio\ - nNonce\x12<\n\x1aprevious_disconnect_reason\x18\x06\x20\x01(\tR\x18previ\ - ousDisconnectReason\x12\x1d\n\nsleep_mode\x18\x07\x20\x01(\x08R\tsleepMo\ - de\x123\n\x13opaque_client_state\x18\x08\x20\x01(\x0cH\0R\x11opaqueClien\ - tState\x88\x01\x01\x1ar\n\x19StaticDeviceMetadataEntry\x12\x10\n\x03key\ - \x18\x01\x20\x01(\tR\x03key\x12?\n\x05value\x18\x02\x20\x01(\x0b2).bitdr\ - ift_public.protobuf.logging.v1.DataR\x05value:\x028\x01B\x16\n\x14_opaqu\ - e_client_stateJ\x04\x08\x02\x10\x03J\x04\x08\x05\x10\x06R\x13fields_for_\ - all_logs\"\xd5\x04\n\x16LogUploadIntentRequest\x12\x1b\n\tlog_count\x18\ + lUntil\"\xc9\x03\n\x12StateUpdateRequest\x12{\n\x14opaque_entity_update\ + \x18\x01\x20\x01(\x0b2I.bitdrift_public.protobuf.client.v1.StateUpdateRe\ + quest.OpaqueEntityUpdateR\x12opaqueEntityUpdate\x12p\n\x10started_sessio\ + ns\x18\x02\x20\x03(\x0b2E.bitdrift_public.protobuf.client.v1.StateUpdate\ + Request.StartedSessionR\x0fstartedSessions\x1aj\n\x0eStartedSession\x12\ + \x1d\n\nsession_id\x18\x01\x20\x01(\tR\tsessionId\x129\n\nstart_time\x18\ + \x02\x20\x01(\x0b2\x1a.google.protobuf.TimestampR\tstartTime\x1aX\n\x12O\ + paqueEntityUpdate\x12-\n\x10opaque_entity_id\x18\x01\x20\x01(\tH\0R\x0eo\ + paqueEntityId\x88\x01\x01B\x13\n\x11_opaque_entity_id\"\x92\x05\n\x10Han\ + dshakeRequest\x12\x84\x01\n\x16static_device_metadata\x18\x01\x20\x03(\ + \x0b2N.bitdrift_public.protobuf.client.v1.HandshakeRequest.StaticDeviceM\ + etadataEntryR\x14staticDeviceMetadata\x12>\n\x1bconfiguration_version_no\ + nce\x18\x03\x20\x01(\tR\x19configurationVersionNonce\x122\n\x15runtime_v\ + ersion_nonce\x18\x04\x20\x01(\tR\x13runtimeVersionNonce\x12<\n\x1aprevio\ + us_disconnect_reason\x18\x06\x20\x01(\tR\x18previousDisconnectReason\x12\ + \x1d\n\nsleep_mode\x18\x07\x20\x01(\x08R\tsleepMode\x123\n\x13opaque_cli\ + ent_state\x18\x08\x20\x01(\x0cH\0R\x11opaqueClientState\x88\x01\x01\x12Y\ + \n\x0cstate_update\x18\t\x20\x01(\x0b26.bitdrift_public.protobuf.client.\ + v1.StateUpdateRequestR\x0bstateUpdate\x1ar\n\x19StaticDeviceMetadataEntr\ + y\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12?\n\x05value\x18\x02\ + \x20\x01(\x0b2).bitdrift_public.protobuf.logging.v1.DataR\x05value:\x028\ + \x01B\x16\n\x14_opaque_client_stateJ\x04\x08\x02\x10\x03J\x04\x08\x05\ + \x10\x06\"\xd5\x04\n\x16LogUploadIntentRequest\x12\x1b\n\tlog_count\x18\ \x01\x20\x01(\rR\x08logCount\x12\x1d\n\nbyte_count\x18\x02\x20\x01(\rR\t\ byteCount\x12\x1b\n\tbuffer_id\x18\x03\x20\x01(\tR\x08bufferId\x12\x1f\n\ \x0bintent_uuid\x18\x04\x20\x01(\tR\nintentUuid\x12\x1d\n\nsession_id\ @@ -9767,7 +10453,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x01(\x0b2?.bitdrift_public.protobuf.client.v1.ConfigurationUpdateAck.Na\ ckR\x04nack\x1aP\n\x04Nack\x12#\n\rversion_nonce\x18\x01\x20\x01(\tR\x0c\ versionNonce\x12#\n\rerror_details\x18\x02\x20\x01(\tR\x0cerrorDetails\"\ - \xc2\t\n\nApiRequest\x12T\n\thandshake\x18\x01\x20\x01(\x0b24.bitdrift_p\ + \x9f\n\n\nApiRequest\x12T\n\thandshake\x18\x01\x20\x01(\x0b24.bitdrift_p\ ublic.protobuf.client.v1.HandshakeRequestH\0R\thandshake\x12h\n\x11log_u\ pload_intent\x18\x07\x20\x01(\x0b2:.bitdrift_public.protobuf.client.v1.L\ ogUploadIntentRequestH\0R\x0flogUploadIntent\x12U\n\nlog_upload\x18\x02\ @@ -9787,860 +10473,902 @@ static file_descriptor_proto_data: &'static [u8] = b"\ uestH\0R\x0eartifactUpload\x12j\n\x0fartifact_intent\x18\r\x20\x01(\x0b2\ ?.bitdrift_public.protobuf.client.v1.UploadArtifactIntentRequestH\0R\x0e\ artifactIntent\x12U\n\ndebug_data\x18\x0e\x20\x01(\x0b24.bitdrift_public\ - .protobuf.client.v1.DebugDataRequestH\0R\tdebugDataB\x13\n\x0crequest_ty\ - pe\x12\x03\xf8B\x01J\x04\x08\x08\x10\tJ\x04\x08\t\x10\n\"\x9a\x02\n\x17S\ - ankeyPathUploadRequest\x12(\n\x0bupload_uuid\x18\x04\x20\x01(\tR\nupload\ - UuidB\x07\xfaB\x04r\x02\x10\x01\x12\x17\n\x02id\x18\x01\x20\x01(\tR\x02i\ - dB\x07\xfaB\x04r\x02\x10\x01\x12\x20\n\x07path_id\x18\x02\x20\x01(\tR\ - \x06pathIdB\x07\xfaB\x04r\x02\x10\x01\x12`\n\x05nodes\x18\x03\x20\x03(\ - \x0b2@.bitdrift_public.protobuf.client.v1.SankeyPathUploadRequest.NodeR\ - \x05nodesB\x08\xfaB\x05\x92\x01\x02\x08\x01\x1a8\n\x04Node\x120\n\x0fext\ - racted_value\x18\x01\x20\x01(\tR\x0eextractedValueB\x07\xfaB\x04r\x02\ - \x10\x01\"\x96\x01\n\x13SankeyIntentRequest\x12(\n\x0bintent_uuid\x18\ - \x01\x20\x01(\tR\nintentUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x20\n\x07pat\ - h_id\x18\x02\x20\x01(\tR\x06pathIdB\x07\xfaB\x04r\x02\x10\x01\x123\n\x11\ - sankey_diagram_id\x18\x03\x20\x01(\tR\x0fsankeyDiagramIdB\x07\xfaB\x04r\ - \x02\x10\x01\"\xd9\x03\n\x1bUploadArtifactIntentRequest\x12(\n\x0bintent\ - _uuid\x18\x01\x20\x01(\tR\nintentUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x20\ - \n\x07type_id\x18\x02\x20\x01(\tR\x06typeIdB\x07\xfaB\x04r\x02\x10\x01\ - \x12i\n\x08metadata\x18\x06\x20\x03(\x0b2M.bitdrift_public.protobuf.clie\ - nt.v1.UploadArtifactIntentRequest.MetadataEntryR\x08metadata\x12(\n\x0ba\ - rtifact_id\x18\x04\x20\x01(\tR\nartifactIdB\x07\xfaB\x04r\x02\x10\x01\ - \x128\n\x04time\x18\x05\x20\x01(\x0b2\x1a.google.protobuf.TimestampR\x04\ - timeB\x08\xfaB\x05\x8a\x01\x02\x10\x01\x12\"\n\nsession_id\x18\x07\x20\ - \x01(\tH\0R\tsessionId\x88\x01\x01\x1af\n\rMetadataEntry\x12\x10\n\x03ke\ - y\x18\x01\x20\x01(\tR\x03key\x12?\n\x05value\x18\x02\x20\x01(\x0b2).bitd\ - rift_public.protobuf.logging.v1.DataR\x05value:\x028\x01B\r\n\x0b_sessio\ - n_idJ\x04\x08\x03\x10\x04\"\xd4\x02\n\x1cUploadArtifactIntentResponse\ - \x12(\n\x0bintent_uuid\x18\x01\x20\x01(\tR\nintentUuidB\x07\xfaB\x04r\ - \x02\x10\x01\x12\x83\x01\n\x12upload_immediately\x18\x03\x20\x01(\x0b2R.\ - bitdrift_public.protobuf.client.v1.UploadArtifactIntentResponse.UploadIm\ - mediatelyH\0R\x11uploadImmediately\x12[\n\x04drop\x18\x04\x20\x01(\x0b2E\ - .bitdrift_public.protobuf.client.v1.UploadArtifactIntentResponse.DropH\0\ - R\x04drop\x1a\x13\n\x11UploadImmediately\x1a\x06\n\x04DropB\n\n\x08decis\ - ion\"\xba\x04\n\x15UploadArtifactRequest\x12(\n\x0bupload_uuid\x18\x01\ - \x20\x01(\tR\nuploadUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x20\n\x07type_id\ - \x18\x02\x20\x01(\tR\x06typeIdB\x07\xfaB\x04r\x02\x10\x01\x12\x1a\n\x08c\ - ontents\x18\x03\x20\x01(\x0cR\x08contents\x12(\n\x0bartifact_id\x18\x04\ - \x20\x01(\tR\nartifactIdB\x07\xfaB\x04r\x02\x10\x01\x12s\n\x0estate_meta\ - data\x18\x05\x20\x03(\x0b2L.bitdrift_public.protobuf.client.v1.UploadArt\ - ifactRequest.StateMetadataEntryR\rstateMetadata\x128\n\x04time\x18\x06\ + .protobuf.client.v1.DebugDataRequestH\0R\tdebugData\x12[\n\x0cstate_upda\ + te\x18\x0f\x20\x01(\x0b26.bitdrift_public.protobuf.client.v1.StateUpdate\ + RequestH\0R\x0bstateUpdateB\x13\n\x0crequest_type\x12\x03\xf8B\x01J\x04\ + \x08\x08\x10\tJ\x04\x08\t\x10\n\"\x9a\x02\n\x17SankeyPathUploadRequest\ + \x12(\n\x0bupload_uuid\x18\x04\x20\x01(\tR\nuploadUuidB\x07\xfaB\x04r\ + \x02\x10\x01\x12\x17\n\x02id\x18\x01\x20\x01(\tR\x02idB\x07\xfaB\x04r\ + \x02\x10\x01\x12\x20\n\x07path_id\x18\x02\x20\x01(\tR\x06pathIdB\x07\xfa\ + B\x04r\x02\x10\x01\x12`\n\x05nodes\x18\x03\x20\x03(\x0b2@.bitdrift_publi\ + c.protobuf.client.v1.SankeyPathUploadRequest.NodeR\x05nodesB\x08\xfaB\ + \x05\x92\x01\x02\x08\x01\x1a8\n\x04Node\x120\n\x0fextracted_value\x18\ + \x01\x20\x01(\tR\x0eextractedValueB\x07\xfaB\x04r\x02\x10\x01\"\x96\x01\ + \n\x13SankeyIntentRequest\x12(\n\x0bintent_uuid\x18\x01\x20\x01(\tR\nint\ + entUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x20\n\x07path_id\x18\x02\x20\x01(\ + \tR\x06pathIdB\x07\xfaB\x04r\x02\x10\x01\x123\n\x11sankey_diagram_id\x18\ + \x03\x20\x01(\tR\x0fsankeyDiagramIdB\x07\xfaB\x04r\x02\x10\x01\"\xd9\x03\ + \n\x1bUploadArtifactIntentRequest\x12(\n\x0bintent_uuid\x18\x01\x20\x01(\ + \tR\nintentUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x20\n\x07type_id\x18\x02\ + \x20\x01(\tR\x06typeIdB\x07\xfaB\x04r\x02\x10\x01\x12i\n\x08metadata\x18\ + \x06\x20\x03(\x0b2M.bitdrift_public.protobuf.client.v1.UploadArtifactInt\ + entRequest.MetadataEntryR\x08metadata\x12(\n\x0bartifact_id\x18\x04\x20\ + \x01(\tR\nartifactIdB\x07\xfaB\x04r\x02\x10\x01\x128\n\x04time\x18\x05\ \x20\x01(\x0b2\x1a.google.protobuf.TimestampR\x04timeB\x08\xfaB\x05\x8a\ - \x01\x02\x10\x01\x12\x1d\n\nsession_id\x18\x07\x20\x01(\tR\tsessionId\ - \x12T\n\rfeature_flags\x18\x08\x20\x03(\x0b2/.bitdrift_public.protobuf.c\ - lient.v1.FeatureFlagR\x0cfeatureFlags\x1ak\n\x12StateMetadataEntry\x12\ - \x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12?\n\x05value\x18\x02\x20\x01\ - (\x0b2).bitdrift_public.protobuf.logging.v1.DataR\x05value:\x028\x01\"X\ - \n\x16UploadArtifactResponse\x12(\n\x0bupload_uuid\x18\x01\x20\x01(\tR\n\ - uploadUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x14\n\x05error\x18\x02\x20\x01\ - (\tR\x05error\"\xf7\x02\n\x11HandshakeResponse\x12m\n\x0fstream_settings\ - \x18\x01\x20\x01(\x0b2D.bitdrift_public.protobuf.client.v1.HandshakeResp\ - onse.StreamSettingsR\x0estreamSettings\x12>\n\x1bconfiguration_update_st\ - atus\x18\x02\x20\x01(\rR\x19configurationUpdateStatus\x12A\n\x1bopaque_c\ - lient_state_to_echo\x18\x03\x20\x01(\x0cH\0R\x17opaqueClientStateToEcho\ - \x88\x01\x01\x1aP\n\x0eStreamSettings\x12>\n\rping_interval\x18\x01\x20\ - \x01(\x0b2\x19.google.protobuf.DurationR\x0cpingIntervalB\x1e\n\x1c_opaq\ - ue_client_state_to_echo\"I\n\x0bRateLimited\x12:\n\x0bretry_after\x18\ - \x01\x20\x01(\x0b2\x19.google.protobuf.DurationR\nretryAfter\"\xca\x01\n\ - \x11LogUploadResponse\x12(\n\x0bupload_uuid\x18\x01\x20\x01(\tR\nuploadU\ - uidB\x07\xfaB\x04r\x02\x10\x01\x12\x14\n\x05error\x18\x02\x20\x01(\tR\ - \x05error\x12!\n\x0clogs_dropped\x18\x03\x20\x01(\rR\x0blogsDropped\x12R\ - \n\x0crate_limited\x18\x04\x20\x01(\x0b2/.bitdrift_public.protobuf.clien\ - t.v1.RateLimitedR\x0brateLimited\"\x9e\n\n\x12StatsUploadRequest\x12(\n\ - \x0bupload_uuid\x18\x01\x20\x01(\tR\nuploadUuidB\x07\xfaB\x04r\x02\x10\ - \x01\x12e\n\x08snapshot\x18\x02\x20\x03(\x0b2?.bitdrift_public.protobuf.\ - client.v1.StatsUploadRequest.SnapshotR\x08snapshotB\x08\xfaB\x05\x92\x01\ - \x02\x08\x01\x123\n\x07sent_at\x18\x03\x20\x01(\x0b2\x1a.google.protobuf\ - .TimestampR\x06sentAt\x12h\n\rupload_reason\x18\x04\x20\x01(\x0e2C.bitdr\ - ift_public.protobuf.client.v1.StatsUploadRequest.UploadReasonR\x0cupload\ - Reason\x1a\xe9\x06\n\x08Snapshot\x12K\n\x07metrics\x18\x01\x20\x01(\x0b2\ - /.bitdrift_public.protobuf.client.v1.MetricsListH\0R\x07metrics\x12l\n\n\ - aggregated\x18\x02\x20\x01(\x0b2J.bitdrift_public.protobuf.client.v1.Sta\ - tsUploadRequest.Snapshot.AggregatedH\x01R\naggregated\x12\x86\x01\n\x13m\ - etric_id_overflows\x18\x03\x20\x03(\x0b2V.bitdrift_public.protobuf.clien\ - t.v1.StatsUploadRequest.Snapshot.MetricIdOverflowsEntryR\x11metricIdOver\ - flows\x12\x86\x01\n\x13workflow_debug_data\x18\x04\x20\x03(\x0b2V.bitdri\ - ft_public.protobuf.client.v1.StatsUploadRequest.Snapshot.WorkflowDebugDa\ - taEntryR\x11workflowDebugData\x1a\x90\x01\n\nAggregated\x12G\n\x0cperiod\ - _start\x18\x04\x20\x01(\x0b2\x1a.google.protobuf.TimestampR\x0bperiodSta\ - rtB\x08\xfaB\x05\x8a\x01\x02\x10\x01\x129\n\nperiod_end\x18\x05\x20\x01(\ - \x0b2\x1a.google.protobuf.TimestampR\tperiodEnd\x1aD\n\x16MetricIdOverfl\ - owsEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\x14\n\x05value\ - \x18\x02\x20\x01(\x04R\x05value:\x028\x01\x1a\x8c\x01\n\x16WorkflowDebug\ - DataEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\\\n\x05value\ - \x18\x02\x20\x01(\x0b2F.bitdrift_public.protobuf.client.v1.DebugDataRequ\ - est.WorkflowDebugDataR\x05value:\x028\x01B\x14\n\rsnapshot_type\x12\x03\ - \xf8B\x01B\x12\n\x0boccurred_at\x12\x03\xf8B\x01\"l\n\x0cUploadReason\ - \x12\x1d\n\x19UPLOAD_REASON_UNSPECIFIED\x10\0\x12\x1a\n\x16UPLOAD_REASON\ - _PERIODIC\x10\x01\x12!\n\x1dUPLOAD_REASON_EVENT_TRIGGERED\x10\x02\"~\n\ - \x13StatsUploadResponse\x12(\n\x0bupload_uuid\x18\x01\x20\x01(\tR\nuploa\ - dUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x14\n\x05error\x18\x02\x20\x01(\tR\ - \x05error\x12'\n\x0fmetrics_dropped\x18\x03\x20\x01(\rR\x0emetricsDroppe\ - d\"\x0e\n\x0cPongResponse\"\xa1\x06\n\x13ConfigurationUpdate\x12#\n\rver\ - sion_nonce\x18\x01\x20\x01(\tR\x0cversionNonce\x12v\n\x12state_of_the_wo\ - rld\x18\x02\x20\x01(\x0b2G.bitdrift_public.protobuf.client.v1.Configurat\ - ionUpdate.StateOfTheWorldH\0R\x0fstateOfTheWorld\x1a\xdd\x04\n\x0fStateO\ - fTheWorld\x12b\n\x12buffer_config_list\x18\x03\x20\x01(\x0b24.bitdrift_p\ - ublic.protobuf.config.v1.BufferConfigListR\x10bufferConfigList\x12u\n\ - \x17workflows_configuration\x18\x04\x20\x01(\x0b2<.bitdrift_public.proto\ - buf.workflow.v1.WorkflowsConfigurationR\x16workflowsConfiguration\x12k\n\ - \x14bdtail_configuration\x18\x06\x20\x01(\x0b28.bitdrift_public.protobuf\ - .bdtail.v1.BdTailConfigurationsR\x13bdtailConfiguration\x12m\n\x15filter\ - s_configuration\x18\x08\x20\x01(\x0b28.bitdrift_public.protobuf.filter.v\ - 1.FiltersConfigurationR\x14filtersConfiguration\x12e\n\x0fdebug_workflow\ - s\x18\t\x20\x01(\x0b2<.bitdrift_public.protobuf.workflow.v1.WorkflowsCon\ - figurationR\x0edebugWorkflowsJ\x04\x08\x02\x10\x03J\x04\x08\x07\x10\x08R\ - \x08mll_listR\x16insights_configurationB\r\n\x0bupdate_type\"{\n\rRuntim\ - eUpdate\x12#\n\rversion_nonce\x18\x01\x20\x01(\tR\x0cversionNonce\x12E\n\ - \x07runtime\x18\x02\x20\x01(\x0b2+.bitdrift_public.protobuf.client.v1.Ru\ - ntimeR\x07runtime\"\xa7\x01\n\rErrorShutdown\x12\x1f\n\x0bgrpc_status\ - \x18\x01\x20\x01(\x05R\ngrpcStatus\x12!\n\x0cgrpc_message\x18\x02\x20\ - \x01(\tR\x0bgrpcMessage\x12R\n\x0crate_limited\x18\x03\x20\x01(\x0b2/.bi\ - tdrift_public.protobuf.client.v1.RateLimitedR\x0brateLimited\"4\n\x0cFlu\ - shBuffers\x12$\n\x0ebuffer_id_list\x18\x01\x20\x03(\tR\x0cbufferIdList\"\ - Z\n\x18SankeyPathUploadResponse\x12(\n\x0bupload_uuid\x18\x01\x20\x01(\t\ - R\nuploadUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x14\n\x05error\x18\x02\x20\ - \x01(\tR\x05error\"\xcb\x02\n\x14SankeyIntentResponse\x12(\n\x0bintent_u\ - uid\x18\x01\x20\x01(\tR\nintentUuidB\x07\xfaB\x04r\x02\x10\x01\x12{\n\ - \x12upload_immediately\x18\x03\x20\x01(\x0b2J.bitdrift_public.protobuf.c\ - lient.v1.SankeyIntentResponse.UploadImmediatelyH\0R\x11uploadImmediately\ - \x12S\n\x04drop\x18\x04\x20\x01(\x0b2=.bitdrift_public.protobuf.client.v\ - 1.SankeyIntentResponse.DropH\0R\x04drop\x1a\x13\n\x11UploadImmediately\ - \x1a\x06\n\x04DropB\n\n\x08decisionJ\x04\x08\x02\x10\x03R\x08decision\"\ - \xb5\x08\n\x10DebugDataRequest\x12{\n\x13workflow_debug_data\x18\x01\x20\ - \x03(\x0b2K.bitdrift_public.protobuf.client.v1.DebugDataRequest.Workflow\ - DebugDataEntryR\x11workflowDebugData\x1a\x87\x02\n\x1bWorkflowTransition\ - DebugData\x12+\n\x10transition_index\x18\x01\x20\x01(\rH\0R\x0ftransitio\ - nIndex\x12/\n\x12timeout_transition\x18\x02\x20\x01(\x08H\0R\x11timeoutT\ - ransition\x12)\n\x10transition_count\x18\x03\x20\x01(\x04R\x0ftransition\ - Count\x12L\n\x14last_transition_time\x18\x04\x20\x01(\x0b2\x1a.google.pr\ - otobuf.TimestampR\x12lastTransitionTimeB\x11\n\x0ftransition_type\x1a\ - \x8c\x01\n\x16WorkflowStateDebugData\x12r\n\x0btransitions\x18\x01\x20\ - \x03(\x0b2P.bitdrift_public.protobuf.client.v1.DebugDataRequest.Workflow\ - TransitionDebugDataR\x0btransitions\x1a\xfb\x02\n\x11WorkflowDebugData\ - \x12j\n\x06states\x18\x01\x20\x03(\x0b2R.bitdrift_public.protobuf.client\ - .v1.DebugDataRequest.WorkflowDebugData.StatesEntryR\x06states\x12q\n\x0b\ - start_reset\x18\x02\x20\x01(\x0b2P.bitdrift_public.protobuf.client.v1.De\ - bugDataRequest.WorkflowTransitionDebugDataR\nstartReset\x1a\x86\x01\n\ - \x0bStatesEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12a\n\x05va\ - lue\x18\x02\x20\x01(\x0b2K.bitdrift_public.protobuf.client.v1.DebugDataR\ - equest.WorkflowStateDebugDataR\x05value:\x028\x01\x1a\x8c\x01\n\x16Workf\ - lowDebugDataEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\x03key\x12\\\n\ - \x05value\x18\x02\x20\x01(\x0b2F.bitdrift_public.protobuf.client.v1.Debu\ - gDataRequest.WorkflowDebugDataR\x05value:\x028\x01\"\xa8\n\n\x0bApiRespo\ - nse\x12U\n\thandshake\x18\x01\x20\x01(\x0b25.bitdrift_public.protobuf.cl\ - ient.v1.HandshakeResponseH\0R\thandshake\x12V\n\nlog_upload\x18\x02\x20\ - \x01(\x0b25.bitdrift_public.protobuf.client.v1.LogUploadResponseH\0R\tlo\ - gUpload\x12i\n\x11log_upload_intent\x18\x08\x20\x01(\x0b2;.bitdrift_publ\ - ic.protobuf.client.v1.LogUploadIntentResponseH\0R\x0flogUploadIntent\x12\ - \\\n\x0cstats_upload\x18\x07\x20\x01(\x0b27.bitdrift_public.protobuf.cli\ - ent.v1.StatsUploadResponseH\0R\x0bstatsUpload\x12F\n\x04pong\x18\x03\x20\ - \x01(\x0b20.bitdrift_public.protobuf.client.v1.PongResponseH\0R\x04pong\ - \x12l\n\x14configuration_update\x18\x04\x20\x01(\x0b27.bitdrift_public.p\ - rotobuf.client.v1.ConfigurationUpdateH\0R\x13configurationUpdate\x12Z\n\ - \x0eruntime_update\x18\x05\x20\x01(\x0b21.bitdrift_public.protobuf.clien\ - t.v1.RuntimeUpdateH\0R\rruntimeUpdate\x12Z\n\x0eerror_shutdown\x18\x06\ - \x20\x01(\x0b21.bitdrift_public.protobuf.client.v1.ErrorShutdownH\0R\rer\ - rorShutdown\x12W\n\rflush_buffers\x18\t\x20\x01(\x0b20.bitdrift_public.p\ - rotobuf.client.v1.FlushBuffersH\0R\x0cflushBuffers\x12r\n\x15sankey_diag\ - ram_upload\x18\x0c\x20\x01(\x0b2<.bitdrift_public.protobuf.client.v1.San\ - keyPathUploadResponseH\0R\x13sankeyDiagramUpload\x12p\n\x16sankey_intent\ - _response\x18\r\x20\x01(\x0b28.bitdrift_public.protobuf.client.v1.Sankey\ - IntentResponseH\0R\x14sankeyIntentResponse\x12e\n\x0fartifact_upload\x18\ - \x0e\x20\x01(\x0b2:.bitdrift_public.protobuf.client.v1.UploadArtifactRes\ - ponseH\0R\x0eartifactUpload\x12k\n\x0fartifact_intent\x18\x0f\x20\x01(\ - \x0b2@.bitdrift_public.protobuf.client.v1.UploadArtifactIntentResponseH\ - \0R\x0eartifactIntentB\x14\n\rresponse_type\x12\x03\xf8B\x01J\x04\x08\n\ - \x10\x0bJ\x04\x08\x0b\x10\x0c2x\n\nApiService\x12j\n\x03Mux\x12..bitdrif\ - t_public.protobuf.client.v1.ApiRequest\x1a/.bitdrift_public.protobuf.cli\ - ent.v1.ApiResponse(\x010\x01J\xdf\xd4\x01\n\x07\x12\x05\x07\0\xf7\x04\ - \x01\n\xb8\x02\n\x01\x0c\x12\x03\x07\0\x122\xad\x02\x20api\x20-\x20bitdr\ - ift's\x20client/server\x20API\x20definitions\n\x20Copyright\x20Bitdrift,\ - \x20Inc.\x20All\x20rights\x20reserved.\n\n\x20Use\x20of\x20this\x20sourc\ - e\x20code\x20and\x20APIs\x20are\x20governed\x20by\x20a\x20source\x20avai\ - lable\x20license\x20that\x20can\x20be\x20found\x20in\n\x20the\x20LICENSE\ - \x20file\x20or\x20at:\n\x20https://polyformproject.org/wp-content/upload\ - s/2020/06/PolyForm-Shield-1.0.0.txt\n\n\x08\n\x01\x02\x12\x03\t\0+\n\t\n\ - \x02\x03\0\x12\x03\x0b\0@\n\t\n\x02\x03\x01\x12\x03\x0c\0?\n\t\n\x02\x03\ - \x02\x12\x03\r\09\n\t\n\x02\x03\x03\x12\x03\x0e\0:\n\t\n\x02\x03\x04\x12\ - \x03\x0f\09\n\t\n\x02\x03\x05\x12\x03\x10\09\n\t\n\x02\x03\x06\x12\x03\ - \x11\0;\n\t\n\x02\x03\x07\x12\x03\x12\0=\n\t\n\x02\x03\x08\x12\x03\x13\0\ - (\n\t\n\x02\x03\t\x12\x03\x14\0)\n\t\n\x02\x03\n\x12\x03\x15\0!\n\x94\ - \x01\n\x02\x04\0\x12\x04\x19\0\"\x01\x1a\x87\x01\x20File\x20written\x20t\ - o\x20disk\x20if\x20the\x20client\x20has\x20been\x20placed\x20in\x20the\ - \x20\"killed\"\x20state\x20and\x20told\x20not\x20to\n\x20contact\x20the\ - \x20server\x20for\x20some\x20period\x20of\x20time.\n\n\n\n\x03\x04\0\x01\ - \x12\x03\x19\x08\x16\n\xe4\x01\n\x04\x04\0\x02\0\x12\x03\x1d\x02\x19\x1a\ - \xd6\x01\x20This\x20is\x20the\x20hash\x20of\x20the\x20API\x20key.\x20If\ - \x20the\x20API\x20key\x20hash\x20changes,\x20we\x20will\x20always\x20ign\ - ore\x20the\n\x20kill_until\x20timestamp.\x20This\x20is\x20to\x20ease\x20\ - local\x20development/onboarding\x20when\x20folks\x20might\x20be\n\x20con\ - fused\x20about\x20what\x20API\x20key\x20to\x20use.\n\n\x0c\n\x05\x04\0\ - \x02\0\x05\x12\x03\x1d\x02\x07\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x1d\ - \x08\x14\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x1d\x17\x18\nr\n\x04\x04\0\ - \x02\x01\x12\x03!\x02+\x1ae\x20The\x20time\x20the\x20client\x20will\x20b\ - e\x20killed\x20until.\x20After\x20this\x20time\x20it\x20will\x20try\x20t\ - o\x20contact\x20the\x20server\n\x20again.\n\n\x0c\n\x05\x04\0\x02\x01\ - \x06\x12\x03!\x02\x1b\n\x0c\n\x05\x04\0\x02\x01\x01\x12\x03!\x1c&\n\x0c\ - \n\x05\x04\0\x02\x01\x03\x12\x03!)*\n7\n\x02\x04\x01\x12\x04%\0L\x01\x1a\ - +\x20The\x20initial\x20request\x20sent\x20over\x20the\x20stream.\n\n\n\n\ - \x03\x04\x01\x01\x12\x03%\x08\x18\n\xe7\x02\n\x04\x04\x01\x02\0\x12\x03,\ - \x02:\x1a\xd9\x02\x20A\x20set\x20of\x20opaque\x20metadata\x20that\x20ide\ - ntifies\x20the\x20connecting\x20device.\x20These\x20will\n\x20remain\x20\ - static\x20for\x20the\x20duration\x20of\x20this\x20stream.\n\x20TODO(snow\ - p):\x20Support\x20updating\x20these\x20throughout\x20the\x20session.\n\ - \x20TODO(snowp):\x20Improve\x20the\x20story\x20for\x20this\x20when\x20pa\ - rameters\x20change\x20during\x20a\n\x20logging\x20period,\x20e.g.\x20if\ - \x20we\x20capture\x20multiple\x20process\x20restarts\x20that\x20may\x20s\ - pan\n\x20versions.\n\n\x0c\n\x05\x04\x01\x02\0\x06\x12\x03,\x02\x1e\n\ - \x0c\n\x05\x04\x01\x02\0\x01\x12\x03,\x1f5\n\x0c\n\x05\x04\x01\x02\0\x03\ - \x12\x03,89\n\x84\x01\n\x03\x04\x01\n\x12\x030\x02!\x1ax\x20This\x20was\ - \x20never\x20used\x20by\x20the\x20client.\x20Reserve\x20it\x20for\x20now\ - \x20to\x20avoid\x20implementing\x20it.\x20We\x20can\x20bring\n\x20it\x20\ - back\x20later\x20if\x20needed.\n\n\x0b\n\x04\x04\x01\n\0\x12\x030\x0b\ - \x20\n\n\n\x03\x04\x01\t\x12\x031\x02\r\n\x0b\n\x04\x04\x01\t\0\x12\x031\ - \x0b\x0c\n\x0c\n\x05\x04\x01\t\0\x01\x12\x031\x0b\x0c\n\x0c\n\x05\x04\ - \x01\t\0\x02\x12\x031\x0b\x0c\n\xab\x02\n\x04\x04\x01\x02\x01\x12\x037\ - \x02)\x1a\x9d\x02\x20If\x20the\x20client\x20has\x20an\x20active\x20confi\ - guration,\x20previously\x20obtained\x20via\x20a\x20ConfigurationUpdate\n\ - \x20message,\x20it\x20should\x20indicate\x20it\x20in\x20the\x20handshake\ - .\x20This\x20will\x20allow\x20the\x20server\x20to\x20not\x20have\x20to\n\ - \x20send\x20out\x20a\x20redundant\x20configuration\x20update.\x20If\x20t\ - here\x20is\x20no\x20active\x20configuration\x20this\x20should\n\x20be\ - \x20empty.\n\n\x0c\n\x05\x04\x01\x02\x01\x05\x12\x037\x02\x08\n\x0c\n\ - \x05\x04\x01\x02\x01\x01\x12\x037\t$\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\ - \x037'(\n\x93\x02\n\x04\x04\x01\x02\x02\x12\x03=\x02#\x1a\x85\x02\x20If\ - \x20the\x20client\x20has\x20an\x20active\x20runtime,\x20previously\x20ob\ - tained\x20via\x20a\x20RuntimeUpdate\n\x20message,\x20it\x20should\x20ind\ - icate\x20it\x20in\x20the\x20handshake.\x20This\x20will\x20allow\x20the\ - \x20server\x20to\x20not\x20have\x20to\n\x20send\x20out\x20a\x20redundant\ - \x20runtime\x20update.\x20If\x20there\x20is\x20no\x20active\x20runtime\ - \x20this\x20should\n\x20be\x20empty.\n\n\x0c\n\x05\x04\x01\x02\x02\x05\ - \x12\x03=\x02\x08\n\x0c\n\x05\x04\x01\x02\x02\x01\x12\x03=\t\x1e\n\x0c\n\ - \x05\x04\x01\x02\x02\x03\x12\x03=!\"\n\n\n\x03\x04\x01\t\x12\x03?\x02\r\ - \n\x0b\n\x04\x04\x01\t\x01\x12\x03?\x0b\x0c\n\x0c\n\x05\x04\x01\t\x01\ - \x01\x12\x03?\x0b\x0c\n\x0c\n\x05\x04\x01\t\x01\x02\x12\x03?\x0b\x0c\n\ - \x97\x01\n\x04\x04\x01\x02\x03\x12\x03C\x02(\x1a\x89\x01\x20Reports\x20t\ - he\x20reason,\x20if\x20any,\x20that\x20the\x20client\x20was\x20previousl\ - y\x20disconnected\x20from\x20the\x20server.\x20This\n\x20is\x20useful\ - \x20for\x20debugging\x20reconnect\x20loops.\n\n\x0c\n\x05\x04\x01\x02\ - \x03\x05\x12\x03C\x02\x08\n\x0c\n\x05\x04\x01\x02\x03\x01\x12\x03C\t#\n\ - \x0c\n\x05\x04\x01\x02\x03\x03\x12\x03C&'\n[\n\x04\x04\x01\x02\x04\x12\ - \x03F\x02\x16\x1aN\x20At\x20the\x20time\x20of\x20the\x20handshake,\x20wh\ - ether\x20the\x20client\x20is\x20operating\x20in\x20sleep\x20mode.\n\n\ - \x0c\n\x05\x04\x01\x02\x04\x05\x12\x03F\x02\x06\n\x0c\n\x05\x04\x01\x02\ - \x04\x01\x12\x03F\x07\x11\n\x0c\n\x05\x04\x01\x02\x04\x03\x12\x03F\x14\ - \x15\n\xf6\x01\n\x04\x04\x01\x02\x05\x12\x03K\x02)\x1a\xe8\x01\x20Opaque\ - \x20client\x20state\x20previously\x20provided\x20by\x20the\x20server\x20\ - in\x20a\x20HandshakeResponse.\x20The\x20client\n\x20should\x20continue\ - \x20to\x20send\x20this\x20on\x20every\x20handshake\x20request\x20until\ - \x20the\x20server\x20provides\x20a\x20new\n\x20value\x20(which\x20may\ - \x20be\x20empty\x20to\x20clear\x20existing\x20state).\n\n\x0c\n\x05\x04\ - \x01\x02\x05\x04\x12\x03K\x02\n\n\x0c\n\x05\x04\x01\x02\x05\x05\x12\x03K\ - \x0b\x10\n\x0c\n\x05\x04\x01\x02\x05\x01\x12\x03K\x11$\n\x0c\n\x05\x04\ - \x01\x02\x05\x03\x12\x03K'(\n\xc6\x03\n\x02\x04\x02\x12\x04S\0x\x01\x1a\ - \xb9\x03\x20Notifies\x20the\x20server\x20about\x20the\x20intent\x20to\ - \x20upload\x20one\x20or\x20more\x20batches\x20of\x20logs.\x20The\x20clie\ - nt\x20is\x20expected\x20(but\n\x20not\x20required,\x20for\x20backwards\ - \x20compatibility)\x20to\x20notify\x20the\x20server\x20about\x20the\x20i\ - ntent\x20to\x20upload\n\x20before\x20uploading.\x20The\x20server\x20is\ - \x20thusly\x20able\x20to\x20influence\x20whether\x20the\x20client\n\x20a\ - ctually\x20uploads\x20(e.g.\x20the\x20backend\x20no\x20longer\x20wants\ - \x20more\x20of\x20these\x20kind\x20of\x20logs)\n\x20or\x20delay\x20the\ - \x20upload\x20(e.g.\x20we\x20are\x20hitting\x20rate\x20limits\x20and\x20\ - are\x20applying\x20back-pressure).\n\n\n\n\x03\x04\x02\x01\x12\x03S\x08\ - \x1e\n\x9c\x01\n\x04\x04\x02\x02\0\x12\x03V\x02\x17\x1a\x8e\x01\x20The\ - \x20number\x20of\x20logs\x20that\x20the\x20client\x20wants\x20to\x20uplo\ - ad.\x20Note\x20that\x20for\x20a\x20ListenerUpload\x20this\x20is\n\x20an\ - \x20approximation\x20of\x20all\x20logs\x20across\x20all\x20batches.\n\n\ - \x0c\n\x05\x04\x02\x02\0\x05\x12\x03V\x02\x08\n\x0c\n\x05\x04\x02\x02\0\ - \x01\x12\x03V\t\x12\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03V\x15\x16\n\x9f\ - \x01\n\x04\x04\x02\x02\x01\x12\x03Z\x02\x18\x1a\x91\x01\x20The\x20size\ - \x20of\x20the\x20intended\x20upload,\x20in\x20bytes.\x20Note\x20that\x20\ - for\x20a\x20ListenerUpload\x20this\x20is\n\x20an\x20approximation\x20of\ - \x20the\x20size\x20of\x20all\x20logs\x20across\x20all\x20batches.\n\n\ - \x0c\n\x05\x04\x02\x02\x01\x05\x12\x03Z\x02\x08\n\x0c\n\x05\x04\x02\x02\ - \x01\x01\x12\x03Z\t\x13\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03Z\x16\x17\ - \n7\n\x04\x04\x02\x02\x02\x12\x03]\x02\x17\x1a*\x20The\x20buffer\x20thes\ - e\x20logs\x20are\x20uploaded\x20from.\n\n\x0c\n\x05\x04\x02\x02\x02\x05\ - \x12\x03]\x02\x08\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\x03]\t\x12\n\x0c\n\ - \x05\x04\x02\x02\x02\x03\x12\x03]\x15\x16\n\xd6\x01\n\x04\x04\x02\x02\ - \x03\x12\x03b\x02\x19\x1a\xc8\x01\x20The\x20client\x20generated\x20UUID\ - \x20for\x20this\x20intent.\x20This\x20allows\x20the\x20server\x20to\x20e\ - nforce\x20idempotence\n\x20during\x20intent\x20negotiation\x20as\x20well\ - \x20as\x20allowing\x20for\x20parallel\x20intent\x20requests\x20to\x20be\ - \x20responded\n\x20to\x20out\x20of\x20order.\n\n\x0c\n\x05\x04\x02\x02\ - \x03\x05\x12\x03b\x02\x08\n\x0c\n\x05\x04\x02\x02\x03\x01\x12\x03b\t\x14\ - \n\x0c\n\x05\x04\x02\x02\x03\x03\x12\x03b\x17\x18\n\x8f\x01\n\x04\x04\ - \x02\x02\x04\x12\x03f\x02\x18\x1a\x81\x01\x20The\x20session\x20ID\x20of\ - \x20the\x20log\x20that\x20caused\x20the\x20intent\x20negotiation.\x20Thi\ - s\x20allows\x20correlating\x20the\x20intent\x20with\n\x20a\x20specific\ - \x20user\x20session.\n\n\x0c\n\x05\x04\x02\x02\x04\x05\x12\x03f\x02\x08\ - \n\x0c\n\x05\x04\x02\x02\x04\x01\x12\x03f\t\x13\n\x0c\n\x05\x04\x02\x02\ - \x04\x03\x12\x03f\x16\x17\n\x0c\n\x04\x04\x02\x03\0\x12\x04h\x02k\x03\n\ - \x0c\n\x05\x04\x02\x03\0\x01\x12\x03h\n\x1e\n=\n\x06\x04\x02\x03\0\x02\0\ - \x12\x03j\x04,\x1a.\x20The\x20listener(s)\x20which\x20triggered\x20this\ - \x20upload.\n\n\x0e\n\x07\x04\x02\x03\0\x02\0\x04\x12\x03j\x04\x0c\n\x0e\ - \n\x07\x04\x02\x03\0\x02\0\x05\x12\x03j\r\x13\n\x0e\n\x07\x04\x02\x03\0\ - \x02\0\x01\x12\x03j\x14'\n\x0e\n\x07\x04\x02\x03\0\x02\0\x03\x12\x03j*+\ - \n\x0c\n\x04\x04\x02\x03\x01\x12\x04m\x02p\x03\n\x0c\n\x05\x04\x02\x03\ - \x01\x01\x12\x03m\n\x20\nb\n\x06\x04\x02\x03\x01\x02\0\x12\x03o\x04;\x1a\ - S\x20An\x20opaque\x20identifier\x20that\x20is\x20used\x20to\x20identify\ - \x20the\x20reason\x20for\x20the\x20session\x20capture.\n\n\x0e\n\x07\x04\ - \x02\x03\x01\x02\0\x05\x12\x03o\x04\n\n\x0e\n\x07\x04\x02\x03\x01\x02\0\ - \x01\x12\x03o\x0b\r\n\x0e\n\x07\x04\x02\x03\x01\x02\0\x03\x12\x03o\x10\ - \x11\n\x0e\n\x07\x04\x02\x03\x01\x02\0\x08\x12\x03o\x12:\n\x11\n\n\x04\ - \x02\x03\x01\x02\0\x08\xaf\x08\x0e\x12\x03o\x139\n\x0c\n\x04\x04\x02\x08\ - \0\x12\x04r\x02w\x03\n\x0c\n\x05\x04\x02\x08\0\x01\x12\x03r\x08\x13\n\ - \x0b\n\x04\x04\x02\x02\x05\x12\x03s\x044\n\x0c\n\x05\x04\x02\x02\x05\x06\ - \x12\x03s\x04\x18\n\x0c\n\x05\x04\x02\x02\x05\x01\x12\x03s\x19/\n\x0c\n\ - \x05\x04\x02\x02\x05\x03\x12\x03s23\nF\n\x04\x04\x02\x02\x06\x12\x03v\ - \x048\x1a9\x20Session\x20capture\x20was\x20explicitly\x20triggered\x20by\ - \x20the\x20client.\n\n\x0c\n\x05\x04\x02\x02\x06\x06\x12\x03v\x04\x1a\n\ - \x0c\n\x05\x04\x02\x02\x06\x01\x12\x03v\x1b3\n\x0c\n\x05\x04\x02\x02\x06\ - \x03\x12\x03v67\n\x0b\n\x02\x04\x03\x12\x05z\0\x8b\x01\x01\n\n\n\x03\x04\ - \x03\x01\x12\x03z\x08\x1f\n7\n\x04\x04\x03\x02\0\x12\x03|\x02\x19\x1a*\ - \x20The\x20UUID\x20of\x20the\x20intent\x20being\x20negotiated.\n\n\x0c\n\ - \x05\x04\x03\x02\0\x05\x12\x03|\x02\x08\n\x0c\n\x05\x04\x03\x02\0\x01\ - \x12\x03|\t\x14\n\x0c\n\x05\x04\x03\x02\0\x03\x12\x03|\x17\x18\n\x0b\n\ - \x04\x04\x03\x03\0\x12\x03~\x02\x1e\n\x0c\n\x05\x04\x03\x03\0\x01\x12\ - \x03~\n\x1b\na\n\x04\x04\x03\x03\x01\x12\x06\x80\x01\x02\x82\x01\x03\"Q\ - \x20If\x20the\x20upload\x20intent\x20was\x20a\x20ListenerUpload\x20the\ - \x20entire\x20upload\x20should\x20be\x20canceled.\n\n\r\n\x05\x04\x03\ - \x03\x01\x01\x12\x04\x80\x01\n\x0e\n\x0e\n\x04\x04\x03\x08\0\x12\x06\x84\ - \x01\x02\x8a\x01\x03\n\r\n\x05\x04\x03\x08\0\x01\x12\x04\x84\x01\x08\x10\ - \n7\n\x04\x04\x03\x02\x01\x12\x04\x86\x01\x04-\x1a)\x20The\x20log\x20sho\ - uld\x20be\x20uploaded\x20immediately.\n\n\r\n\x05\x04\x03\x02\x01\x06\ - \x12\x04\x86\x01\x04\x15\n\r\n\x05\x04\x03\x02\x01\x01\x12\x04\x86\x01\ - \x16(\n\r\n\x05\x04\x03\x02\x01\x03\x12\x04\x86\x01+,\n6\n\x04\x04\x03\ - \x02\x02\x12\x04\x89\x01\x04\x12\x1a(\x20The\x20candidate\x20batch\x20sh\ - ould\x20be\x20dropped.\n\n\r\n\x05\x04\x03\x02\x02\x06\x12\x04\x89\x01\ - \x04\x08\n\r\n\x05\x04\x03\x02\x02\x01\x12\x04\x89\x01\t\r\n\r\n\x05\x04\ - \x03\x02\x02\x03\x12\x04\x89\x01\x10\x11\n,\n\x02\x04\x04\x12\x06\x8e\ - \x01\0\xa2\x01\x01\x1a\x1e\x20A\x20single\x20log\x20upload\x20payload.\n\ - \n\x0b\n\x03\x04\x04\x01\x12\x04\x8e\x01\x08\x18\n\x88\x01\n\x04\x04\x04\ - \x02\0\x12\x04\x91\x01\x02B\x1az\x20A\x20UUID\x20(v4)\x20associated\x20w\ - ith\x20this\x20upload.\x20This\x20should\x20be\x20generated\x20by\x20the\ - \n\x20client.\x20Retries\x20should\x20use\x20the\x20same\x20upload_id.\n\ - \n\r\n\x05\x04\x04\x02\0\x05\x12\x04\x91\x01\x02\x08\n\r\n\x05\x04\x04\ - \x02\0\x01\x12\x04\x91\x01\t\x14\n\r\n\x05\x04\x04\x02\0\x03\x12\x04\x91\ - \x01\x17\x18\n\r\n\x05\x04\x04\x02\0\x08\x12\x04\x91\x01\x19A\n\x10\n\ - \x08\x04\x04\x02\0\x08\xaf\x08\x0e\x12\x04\x91\x01\x1a@\n\xda\x01\n\x04\ - \x04\x04\x02\x01\x12\x04\x96\x01\x02,\x1a\xcb\x01\x20A\x20repeated\x20se\ - t\x20of\x20flatbuffer\x20encoding\x20of\x20a\x20number\x20of\x20log\x20l\ - ines.\x20Each\x20log\x20line\x20is\x20of\x20type\n\x20Log\x20defined\x20\ - in\x20buffer_log.fbs.\x20This\x20is\x20deprecated.\x20New\x20clients\x20\ - send\x20protobuf\x20encoded\x20logs\n\x20in\x20the\x20'logs'\x20field.\n\ - \n\r\n\x05\x04\x04\x02\x01\x04\x12\x04\x96\x01\x02\n\n\r\n\x05\x04\x04\ - \x02\x01\x05\x12\x04\x96\x01\x0b\x10\n\r\n\x05\x04\x04\x02\x01\x01\x12\ - \x04\x96\x01\x11'\n\r\n\x05\x04\x04\x02\x01\x03\x12\x04\x96\x01*+\nO\n\ - \x04\x04\x04\x02\x02\x12\x04\x99\x01\x02\x20\x1aA\x20Logs\x20encoded\x20\ - in\x20bitdrift_public.protobuf.logging.v1.Log\x20format.\n\n\r\n\x05\x04\ - \x04\x02\x02\x04\x12\x04\x99\x01\x02\n\n\r\n\x05\x04\x04\x02\x02\x05\x12\ - \x04\x99\x01\x0b\x10\n\r\n\x05\x04\x04\x02\x02\x01\x12\x04\x99\x01\x11\ - \x1b\n\r\n\x05\x04\x04\x02\x02\x03\x12\x04\x99\x01\x1e\x1f\nG\n\x04\x04\ - \x04\x02\x03\x12\x04\x9c\x01\x02B\x1a9\x20The\x20UUID\x20(v4)\x20of\x20t\ - he\x20buffer\x20that\x20is\x20producing\x20the\x20logs.\n\n\r\n\x05\x04\ - \x04\x02\x03\x05\x12\x04\x9c\x01\x02\x08\n\r\n\x05\x04\x04\x02\x03\x01\ - \x12\x04\x9c\x01\t\x14\n\r\n\x05\x04\x04\x02\x03\x03\x12\x04\x9c\x01\x17\ - \x18\n\r\n\x05\x04\x04\x02\x03\x08\x12\x04\x9c\x01\x19A\n\x10\n\x08\x04\ - \x04\x02\x03\x08\xaf\x08\x0e\x12\x04\x9c\x01\x1a@\n\xc8\x01\n\x04\x04\ - \x04\x02\x04\x12\x04\xa1\x01\x02\x13\x1a\xb9\x01\x20Whether\x20the\x20se\ - rver\x20should\x20not\x20respond\x20to\x20this\x20upload.\x20This\x20is\ - \x20used\x20for\x20high\n\x20throughput,\x20low\x20value\x20logs\x20wher\ - e\x20the\x20client\x20does\x20not\x20need\x20to\x20know\x20whether\n\x20\ - the\x20upload\x20succeeded\x20or\x20failed.\n\n\r\n\x05\x04\x04\x02\x04\ - \x05\x12\x04\xa1\x01\x02\x06\n\r\n\x05\x04\x04\x02\x04\x01\x12\x04\xa1\ - \x01\x07\x0e\n\r\n\x05\x04\x04\x02\x04\x03\x12\x04\xa1\x01\x11\x12\nS\n\ - \x02\x04\x05\x12\x06\xa5\x01\0\xa8\x01\x01\x1aE\x20Empty\x20message\x20t\ - o\x20maintain\x20a\x20application\x20layer\x20keep\x20alive\x20mechanism\ - .\n\n\x0b\n\x03\x04\x05\x01\x12\x04\xa5\x01\x08\x13\nW\n\x04\x04\x05\x02\ - \0\x12\x04\xa7\x01\x02\x16\x1aI\x20At\x20the\x20time\x20of\x20the\x20pin\ - g,\x20whether\x20the\x20client\x20is\x20operating\x20in\x20sleep\x20mode\ - .\n\n\r\n\x05\x04\x05\x02\0\x05\x12\x04\xa7\x01\x02\x06\n\r\n\x05\x04\ - \x05\x02\0\x01\x12\x04\xa7\x01\x07\x11\n\r\n\x05\x04\x05\x02\0\x03\x12\ - \x04\xa7\x01\x14\x15\nD\n\x02\x04\x06\x12\x06\xab\x01\0\xbe\x01\x01\x1a6\ - \x20Configuration\x20update\x20response\x20from\x20client\x20to\x20serve\ - r.\n\n\x0b\n\x03\x04\x06\x01\x12\x04\xab\x01\x08\x1e\n\x0e\n\x04\x04\x06\ - \x03\0\x12\x06\xac\x01\x02\xb2\x01\x03\n\r\n\x05\x04\x06\x03\0\x01\x12\ - \x04\xac\x01\n\x0e\nL\n\x06\x04\x06\x03\0\x02\0\x12\x04\xae\x01\x04\x1d\ - \x1a<\x20The\x20version\x20nonce\x20of\x20the\x20configuration\x20update\ - \x20that\x20failed.\n\n\x0f\n\x07\x04\x06\x03\0\x02\0\x05\x12\x04\xae\ - \x01\x04\n\n\x0f\n\x07\x04\x06\x03\0\x02\0\x01\x12\x04\xae\x01\x0b\x18\n\ - \x0f\n\x07\x04\x06\x03\0\x02\0\x03\x12\x04\xae\x01\x1b\x1c\n/\n\x06\x04\ - \x06\x03\0\x02\x01\x12\x04\xb1\x01\x04\x1d\x1a\x1f\x20Error\x20details\ - \x20of\x20the\x20failure.\n\n\x0f\n\x07\x04\x06\x03\0\x02\x01\x05\x12\ - \x04\xb1\x01\x04\n\n\x0f\n\x07\x04\x06\x03\0\x02\x01\x01\x12\x04\xb1\x01\ - \x0b\x18\n\x0f\n\x07\x04\x06\x03\0\x02\x01\x03\x12\x04\xb1\x01\x1b\x1c\n\ - \xca\x01\n\x04\x04\x06\x02\0\x12\x04\xb7\x01\x02(\x1a\xbb\x01\x20The\x20\ - version\x20nonce\x20that\x20the\x20client\x20is\x20actually\x20using.\ - \x20This\x20version\x20nonce\x20was\x20sent\x20in\x20a\n\x20Configuratio\ - nUpdate\x20message.\x20If\x20no\x20configuration\x20has\x20been\x20appli\ - ed\x20(NACK\x20only)\x20this\x20will\x20be\n\x20empty.\n\n\r\n\x05\x04\ - \x06\x02\0\x05\x12\x04\xb7\x01\x02\x08\n\r\n\x05\x04\x06\x02\0\x01\x12\ - \x04\xb7\x01\t#\n\r\n\x05\x04\x06\x02\0\x03\x12\x04\xb7\x01&'\n\xaa\x02\ - \n\x04\x04\x06\x02\x01\x12\x04\xbd\x01\x02\x10\x1a\x9b\x02\x20If\x20a\ - \x20configuration\x20update\x20failed,\x20the\x20client\x20should\x20res\ - pond\x20to\x20the\x20server\x20and\x20let\x20it\x20know.\n\x20It\x20shou\ - ld\x20continue\x20to\x20use\x20the\x20last\x20good\x20config.\x20This\ - \x20message\x20is\x20empty\x20on\x20success,\x20and\x20the\n\x20client\ - \x20should\x20respond\x20with\x20last_applied_version_nonce\x20being\x20\ - equal\x20to\x20the\x20update\x20that\x20was\n\x20applied.\n\n\r\n\x05\ - \x04\x06\x02\x01\x06\x12\x04\xbd\x01\x02\x06\n\r\n\x05\x04\x06\x02\x01\ - \x01\x12\x04\xbd\x01\x07\x0b\n\r\n\x05\x04\x06\x02\x01\x03\x12\x04\xbd\ - \x01\x0e\x0f\n\xba\x02\n\x02\x04\x07\x12\x06\xc4\x01\0\xd8\x01\x01\x1a\ - \xab\x02\x20A\x20multiplexed\x20request\x20sent\x20over\x20the\x20bitdri\ - ft\x20API.\x20Upon\x20stream\x20creation,\x20the\n\x20client\x20will\x20\ - issue\x20a\x20single\x20handshake\x20request,\x20then\x20await\x20a\x20h\ - andshake\n\x20response.\x20Once\x20the\x20handshake\x20has\x20completed,\ - \x20the\x20client\x20may\x20issue\x20any\x20number\n\x20of\x20non-handsh\ - ake\x20requests;\x20corresponding\x20responses\x20may\x20come\x20in\x20a\ - ny\x20order.\n\n\x0b\n\x03\x04\x07\x01\x12\x04\xc4\x01\x08\x12\n\x0e\n\ - \x04\x04\x07\x08\0\x12\x06\xc5\x01\x02\xd4\x01\x03\n\r\n\x05\x04\x07\x08\ - \0\x01\x12\x04\xc5\x01\x08\x14\n\r\n\x05\x04\x07\x08\0\x02\x12\x04\xc6\ - \x01\x04&\n\x0f\n\x07\x04\x07\x08\0\x02\xaf\x08\x12\x04\xc6\x01\x04&\n\ - \x0c\n\x04\x04\x07\x02\0\x12\x04\xc8\x01\x04#\n\r\n\x05\x04\x07\x02\0\ - \x06\x12\x04\xc8\x01\x04\x14\n\r\n\x05\x04\x07\x02\0\x01\x12\x04\xc8\x01\ - \x15\x1e\n\r\n\x05\x04\x07\x02\0\x03\x12\x04\xc8\x01!\"\n\x0c\n\x04\x04\ - \x07\x02\x01\x12\x04\xc9\x01\x041\n\r\n\x05\x04\x07\x02\x01\x06\x12\x04\ - \xc9\x01\x04\x1a\n\r\n\x05\x04\x07\x02\x01\x01\x12\x04\xc9\x01\x1b,\n\r\ - \n\x05\x04\x07\x02\x01\x03\x12\x04\xc9\x01/0\n\x0c\n\x04\x04\x07\x02\x02\ - \x12\x04\xca\x01\x04$\n\r\n\x05\x04\x07\x02\x02\x06\x12\x04\xca\x01\x04\ - \x14\n\r\n\x05\x04\x07\x02\x02\x01\x12\x04\xca\x01\x15\x1f\n\r\n\x05\x04\ - \x07\x02\x02\x03\x12\x04\xca\x01\"#\n\x0c\n\x04\x04\x07\x02\x03\x12\x04\ - \xcb\x01\x04(\n\r\n\x05\x04\x07\x02\x03\x06\x12\x04\xcb\x01\x04\x16\n\r\ - \n\x05\x04\x07\x02\x03\x01\x12\x04\xcb\x01\x17#\n\r\n\x05\x04\x07\x02\ - \x03\x03\x12\x04\xcb\x01&'\n\x0c\n\x04\x04\x07\x02\x04\x12\x04\xcc\x01\ - \x04\x19\n\r\n\x05\x04\x07\x02\x04\x06\x12\x04\xcc\x01\x04\x0f\n\r\n\x05\ - \x04\x07\x02\x04\x01\x12\x04\xcc\x01\x10\x14\n\r\n\x05\x04\x07\x02\x04\ - \x03\x12\x04\xcc\x01\x17\x18\n\x0c\n\x04\x04\x07\x02\x05\x12\x04\xcd\x01\ - \x048\n\r\n\x05\x04\x07\x02\x05\x06\x12\x04\xcd\x01\x04\x1a\n\r\n\x05\ - \x04\x07\x02\x05\x01\x12\x04\xcd\x01\x1b3\n\r\n\x05\x04\x07\x02\x05\x03\ - \x12\x04\xcd\x0167\n\x0c\n\x04\x04\x07\x02\x06\x12\x04\xce\x01\x042\n\r\ - \n\x05\x04\x07\x02\x06\x06\x12\x04\xce\x01\x04\x1a\n\r\n\x05\x04\x07\x02\ - \x06\x01\x12\x04\xce\x01\x1b-\n\r\n\x05\x04\x07\x02\x06\x03\x12\x04\xce\ - \x0101\n\x0c\n\x04\x04\x07\x02\x07\x12\x04\xcf\x01\x044\n\r\n\x05\x04\ - \x07\x02\x07\x06\x12\x04\xcf\x01\x04\x1b\n\r\n\x05\x04\x07\x02\x07\x01\ - \x12\x04\xcf\x01\x1c.\n\r\n\x05\x04\x07\x02\x07\x03\x12\x04\xcf\x0113\n\ - \x0c\n\x04\x04\x07\x02\x08\x12\x04\xd0\x01\x04+\n\r\n\x05\x04\x07\x02\ - \x08\x06\x12\x04\xd0\x01\x04\x17\n\r\n\x05\x04\x07\x02\x08\x01\x12\x04\ - \xd0\x01\x18%\n\r\n\x05\x04\x07\x02\x08\x03\x12\x04\xd0\x01(*\n\x0c\n\ - \x04\x04\x07\x02\t\x12\x04\xd1\x01\x04/\n\r\n\x05\x04\x07\x02\t\x06\x12\ - \x04\xd1\x01\x04\x19\n\r\n\x05\x04\x07\x02\t\x01\x12\x04\xd1\x01\x1a)\n\ - \r\n\x05\x04\x07\x02\t\x03\x12\x04\xd1\x01,.\n\x0c\n\x04\x04\x07\x02\n\ - \x12\x04\xd2\x01\x045\n\r\n\x05\x04\x07\x02\n\x06\x12\x04\xd2\x01\x04\ - \x1f\n\r\n\x05\x04\x07\x02\n\x01\x12\x04\xd2\x01\x20/\n\r\n\x05\x04\x07\ - \x02\n\x03\x12\x04\xd2\x0124\n\x0c\n\x04\x04\x07\x02\x0b\x12\x04\xd3\x01\ - \x04%\n\r\n\x05\x04\x07\x02\x0b\x06\x12\x04\xd3\x01\x04\x14\n\r\n\x05\ - \x04\x07\x02\x0b\x01\x12\x04\xd3\x01\x15\x1f\n\r\n\x05\x04\x07\x02\x0b\ - \x03\x12\x04\xd3\x01\"$\n\x0b\n\x03\x04\x07\t\x12\x04\xd6\x01\x02\r\n\ - \x0c\n\x04\x04\x07\t\0\x12\x04\xd6\x01\x0b\x0c\n\r\n\x05\x04\x07\t\0\x01\ - \x12\x04\xd6\x01\x0b\x0c\n\r\n\x05\x04\x07\t\0\x02\x12\x04\xd6\x01\x0b\ - \x0c\n\x0b\n\x03\x04\x07\t\x12\x04\xd7\x01\x02\r\n\x0c\n\x04\x04\x07\t\ - \x01\x12\x04\xd7\x01\x0b\x0c\n\r\n\x05\x04\x07\t\x01\x01\x12\x04\xd7\x01\ - \x0b\x0c\n\r\n\x05\x04\x07\t\x01\x02\x12\x04\xd7\x01\x0b\x0c\n:\n\x02\ - \x04\x08\x12\x06\xdb\x01\0\xee\x01\x01\x1a,\x20A\x20request\x20to\x20upl\ - oad\x20a\x20Sankey\x20diagram\x20path.\n\n\x0b\n\x03\x04\x08\x01\x12\x04\ - \xdb\x01\x08\x1f\nf\n\x04\x04\x08\x02\0\x12\x04\xdd\x01\x02B\x1aX\x20Upl\ - oad\x20UUID\x20used\x20to\x20provide\x20idempotence\x20and\x20to\x20corr\ - elate\x20a\x20response\x20with\x20this\x20request.\n\n\r\n\x05\x04\x08\ - \x02\0\x05\x12\x04\xdd\x01\x02\x08\n\r\n\x05\x04\x08\x02\0\x01\x12\x04\ - \xdd\x01\t\x14\n\r\n\x05\x04\x08\x02\0\x03\x12\x04\xdd\x01\x17\x18\n\r\n\ - \x05\x04\x08\x02\0\x08\x12\x04\xdd\x01\x19A\n\x10\n\x08\x04\x08\x02\0\ - \x08\xaf\x08\x0e\x12\x04\xdd\x01\x1a@\n\xc1\x01\n\x04\x04\x08\x03\0\x12\ - \x06\xe1\x01\x02\xe4\x01\x03\x1a\xb0\x01\x20A\x20single\x20node\x20in\ - \x20the\x20Sankey\x20diagram.\x20This\x20differs\x20from\x20workflow\x20\ - states.\x20Each\x20node\x20corresponds\n\x20to\x20a\x20single\x20transit\ - ion\x20from\x20a\x20workflow\x20origin\x20state\x20to\x20a\x20workflow\ - \x20target\x20state.\n\n\r\n\x05\x04\x08\x03\0\x01\x12\x04\xe1\x01\n\x0e\ - \n;\n\x06\x04\x08\x03\0\x02\0\x12\x04\xe3\x01\x04H\x1a+\x20The\x20value\ - \x20extracted\x20from\x20the\x20matched\x20log.\n\n\x0f\n\x07\x04\x08\ - \x03\0\x02\0\x05\x12\x04\xe3\x01\x04\n\n\x0f\n\x07\x04\x08\x03\0\x02\0\ - \x01\x12\x04\xe3\x01\x0b\x1a\n\x0f\n\x07\x04\x08\x03\0\x02\0\x03\x12\x04\ - \xe3\x01\x1d\x1e\n\x0f\n\x07\x04\x08\x03\0\x02\0\x08\x12\x04\xe3\x01\x1f\ - G\n\x12\n\n\x04\x08\x03\0\x02\0\x08\xaf\x08\x0e\x12\x04\xe3\x01\x20F\n\"\ - \n\x04\x04\x08\x02\x01\x12\x04\xe7\x01\x029\x1a\x14\x20Sankey\x20diagram\ - \x20ID.\n\n\r\n\x05\x04\x08\x02\x01\x05\x12\x04\xe7\x01\x02\x08\n\r\n\ - \x05\x04\x08\x02\x01\x01\x12\x04\xe7\x01\t\x0b\n\r\n\x05\x04\x08\x02\x01\ - \x03\x12\x04\xe7\x01\x0e\x0f\n\r\n\x05\x04\x08\x02\x01\x08\x12\x04\xe7\ - \x01\x108\n\x10\n\x08\x04\x08\x02\x01\x08\xaf\x08\x0e\x12\x04\xe7\x01\ - \x117\n\x8d\x02\n\x04\x04\x08\x02\x02\x12\x04\xeb\x01\x02>\x1a\xfe\x01\ - \x20The\x20identifier\x20that\x20represents\x20a\x20traversed\x20state's\ - \x20path\x20registered\x20for\x20a\x20diagram.\x20Two\x20diagram\x20path\ - s\n\x20within\x20the\x20same\x20diagram\x20can\x20have\x20the\x20same\ - \x20ID\x20only\x20if\x20their\x20nodes\x20are\x20identical.\n\x20Conflic\ - ts\x20in\x20diagram\x20path\x20IDs\x20between\x20different\x20diagrams\ - \x20are\x20possible.\n\n\r\n\x05\x04\x08\x02\x02\x05\x12\x04\xeb\x01\x02\ - \x08\n\r\n\x05\x04\x08\x02\x02\x01\x12\x04\xeb\x01\t\x10\n\r\n\x05\x04\ - \x08\x02\x02\x03\x12\x04\xeb\x01\x13\x14\n\r\n\x05\x04\x08\x02\x02\x08\ - \x12\x04\xeb\x01\x15=\n\x10\n\x08\x04\x08\x02\x02\x08\xaf\x08\x0e\x12\ - \x04\xeb\x01\x16<\n4\n\x04\x04\x08\x02\x03\x12\x04\xed\x01\x02G\x1a&\x20\ - The\x20list\x20of\x20traversed\x20diagram\x20nodes.\n\n\r\n\x05\x04\x08\ - \x02\x03\x04\x12\x04\xed\x01\x02\n\n\r\n\x05\x04\x08\x02\x03\x06\x12\x04\ - \xed\x01\x0b\x0f\n\r\n\x05\x04\x08\x02\x03\x01\x12\x04\xed\x01\x10\x15\n\ - \r\n\x05\x04\x08\x02\x03\x03\x12\x04\xed\x01\x18\x19\n\r\n\x05\x04\x08\ - \x02\x03\x08\x12\x04\xed\x01\x1aF\n\x10\n\x08\x04\x08\x02\x03\x08\xaf\ - \x08\x12\x12\x04\xed\x01\x1bE\nA\n\x02\x04\t\x12\x06\xf1\x01\0\xfa\x01\ - \x01\x1a3\x20A\x20request\x20to\x20ask\x20whether\x20to\x20upload\x20a\ - \x20Sankey\x20path.\n\n\x0b\n\x03\x04\t\x01\x12\x04\xf1\x01\x08\x1b\nq\n\ - \x04\x04\t\x02\0\x12\x04\xf3\x01\x02B\x1ac\x20The\x20UUID\x20of\x20the\ - \x20intent\x20being\x20negotiated.\x20This\x20is\x20used\x20to\x20correl\ - ate\x20the\x20response\x20with\x20the\x20request.\n\n\r\n\x05\x04\t\x02\ - \0\x05\x12\x04\xf3\x01\x02\x08\n\r\n\x05\x04\t\x02\0\x01\x12\x04\xf3\x01\ - \t\x14\n\r\n\x05\x04\t\x02\0\x03\x12\x04\xf3\x01\x17\x18\n\r\n\x05\x04\t\ - \x02\0\x08\x12\x04\xf3\x01\x19A\n\x10\n\x08\x04\t\x02\0\x08\xaf\x08\x0e\ - \x12\x04\xf3\x01\x1a@\nG\n\x04\x04\t\x02\x01\x12\x04\xf6\x01\x02>\x1a9\ - \x20The\x20ID\x20of\x20the\x20path\x20that\x20is\x20being\x20considered\ - \x20for\x20upload.\n\n\r\n\x05\x04\t\x02\x01\x05\x12\x04\xf6\x01\x02\x08\ - \n\r\n\x05\x04\t\x02\x01\x01\x12\x04\xf6\x01\t\x10\n\r\n\x05\x04\t\x02\ - \x01\x03\x12\x04\xf6\x01\x13\x14\n\r\n\x05\x04\t\x02\x01\x08\x12\x04\xf6\ - \x01\x15=\n\x10\n\x08\x04\t\x02\x01\x08\xaf\x08\x0e\x12\x04\xf6\x01\x16<\ - \nF\n\x04\x04\t\x02\x02\x12\x04\xf9\x01\x02H\x1a8\x20The\x20ID\x20of\x20\ - the\x20diagram\x20that\x20the\x20path\x20was\x20discovered\x20in.\n\n\r\ - \n\x05\x04\t\x02\x02\x05\x12\x04\xf9\x01\x02\x08\n\r\n\x05\x04\t\x02\x02\ - \x01\x12\x04\xf9\x01\t\x1a\n\r\n\x05\x04\t\x02\x02\x03\x12\x04\xf9\x01\ - \x1d\x1e\n\r\n\x05\x04\t\x02\x02\x08\x12\x04\xf9\x01\x1fG\n\x10\n\x08\ - \x04\t\x02\x02\x08\xaf\x08\x0e\x12\x04\xf9\x01\x20F\n\x0c\n\x02\x04\n\ - \x12\x06\xfc\x01\0\x92\x02\x01\n\x0b\n\x03\x04\n\x01\x12\x04\xfc\x01\x08\ - #\nq\n\x04\x04\n\x02\0\x12\x04\xfe\x01\x02B\x1ac\x20The\x20UUID\x20of\ - \x20the\x20intent\x20being\x20negotiated.\x20This\x20is\x20used\x20to\ - \x20correlate\x20the\x20response\x20with\x20the\x20request.\n\n\r\n\x05\ - \x04\n\x02\0\x05\x12\x04\xfe\x01\x02\x08\n\r\n\x05\x04\n\x02\0\x01\x12\ - \x04\xfe\x01\t\x14\n\r\n\x05\x04\n\x02\0\x03\x12\x04\xfe\x01\x17\x18\n\r\ - \n\x05\x04\n\x02\0\x08\x12\x04\xfe\x01\x19A\n\x10\n\x08\x04\n\x02\0\x08\ - \xaf\x08\x0e\x12\x04\xfe\x01\x1a@\nE\n\x04\x04\n\x02\x01\x12\x04\x81\x02\ - \x02>\x1a7\x20The\x20type\x20of\x20the\x20artifact\x20being\x20considere\ - d\x20for\x20upload.\n\n\r\n\x05\x04\n\x02\x01\x05\x12\x04\x81\x02\x02\ - \x08\n\r\n\x05\x04\n\x02\x01\x01\x12\x04\x81\x02\t\x10\n\r\n\x05\x04\n\ - \x02\x01\x03\x12\x04\x81\x02\x13\x14\n\r\n\x05\x04\n\x02\x01\x08\x12\x04\ - \x81\x02\x15=\n\x10\n\x08\x04\n\x02\x01\x08\xaf\x08\x0e\x12\x04\x81\x02\ - \x16<\n\x0b\n\x03\x04\n\t\x12\x04\x83\x02\x02\r\n\x0c\n\x04\x04\n\t\0\ - \x12\x04\x83\x02\x0b\x0c\n\r\n\x05\x04\n\t\0\x01\x12\x04\x83\x02\x0b\x0c\ - \n\r\n\x05\x04\n\t\0\x02\x12\x04\x83\x02\x0b\x0c\n\xd5\x02\n\x04\x04\n\ - \x02\x02\x12\x04\x86\x02\x02,\x1a\xc6\x02\x20The\x20metadata\x20associat\ - ed\x20with\x20the\x20artifact.\x20The\x20contents\x20within\x20this\x20m\ - ap\x20depends\x20on\x20the\x20type\x20of\x20the\x20artfact\x20but\x20wil\ - l\x20generally\x20contain\x20information\x20that\x20can\x20help\x20the\ - \x20server\x20make\x20a\x20decision\x20about\x20whether\x20to\x20accept\ - \x20the\x20upload\x20or\x20not.\x20For\x20example,\x20for\x20issue\x20re\ - ports\x20this\x20may\x20contain\x20the\x20\"fields\"\x20associated\x20wi\ - th\x20the\x20issue\x20report.\n\n\r\n\x05\x04\n\x02\x02\x06\x12\x04\x86\ - \x02\x02\x1e\n\r\n\x05\x04\n\x02\x02\x01\x12\x04\x86\x02\x1f'\n\r\n\x05\ - \x04\n\x02\x02\x03\x12\x04\x86\x02*+\n\x92\x01\n\x04\x04\n\x02\x03\x12\ - \x04\x8a\x02\x02B\x1a\x83\x01\x20A\x20client-generated\x20ID\x20that\x20\ - uniquely\x20identifies\x20the\x20artifact.\x20This\x20is\x20used\x20to\ - \x20correlate\x20the\x20artifact\n\x20with\x20logs\x20that\x20reference\ - \x20it.\n\n\r\n\x05\x04\n\x02\x03\x05\x12\x04\x8a\x02\x02\x08\n\r\n\x05\ - \x04\n\x02\x03\x01\x12\x04\x8a\x02\t\x14\n\r\n\x05\x04\n\x02\x03\x03\x12\ - \x04\x8a\x02\x17\x18\n\r\n\x05\x04\n\x02\x03\x08\x12\x04\x8a\x02\x19A\n\ - \x10\n\x08\x04\n\x02\x03\x08\xaf\x08\x0e\x12\x04\x8a\x02\x1a@\n\x8f\x01\ - \n\x04\x04\n\x02\x04\x12\x04\x8d\x02\x02S\x1a\x80\x01\x20The\x20timestam\ - p\x20associated\x20with\x20the\x20artifact\x20being\x20uploaded.\x20This\ - \x20allows\x20us\x20to\x20possibly\x20reject\x20the\x20upload\x20of\x20v\ - ery\x20old\x20artifacts.\n\n\r\n\x05\x04\n\x02\x04\x06\x12\x04\x8d\x02\ - \x02\x1b\n\r\n\x05\x04\n\x02\x04\x01\x12\x04\x8d\x02\x1c\x20\n\r\n\x05\ - \x04\n\x02\x04\x03\x12\x04\x8d\x02#$\n\r\n\x05\x04\n\x02\x04\x08\x12\x04\ - \x8d\x02%R\n\x10\n\x08\x04\n\x02\x04\x08\xaf\x08\x11\x12\x04\x8d\x02&Q\n\ - \xc8\x01\n\x04\x04\n\x02\x05\x12\x04\x91\x02\x02!\x1a\xb9\x01\x20The\x20\ - session\x20ID\x20associated\x20with\x20the\x20artifact.\x20This\x20allow\ - s\x20correlating\x20the\x20intent\x20with\x20a\x20specific\x20user\x20se\ - ssion.\n\x20This\x20may\x20not\x20be\x20set\x20for\x20all\x20kinds\x20of\ - \x20artifacts,\x20such\x20as\x20state\x20snapshots.\n\n\r\n\x05\x04\n\ - \x02\x05\x04\x12\x04\x91\x02\x02\n\n\r\n\x05\x04\n\x02\x05\x05\x12\x04\ - \x91\x02\x0b\x11\n\r\n\x05\x04\n\x02\x05\x01\x12\x04\x91\x02\x12\x1c\n\r\ - \n\x05\x04\n\x02\x05\x03\x12\x04\x91\x02\x1f\x20\n\x0c\n\x02\x04\x0b\x12\ - \x06\x94\x02\0\xa3\x02\x01\n\x0b\n\x03\x04\x0b\x01\x12\x04\x94\x02\x08$\ - \nq\n\x04\x04\x0b\x02\0\x12\x04\x96\x02\x02B\x1ac\x20The\x20UUID\x20of\ - \x20the\x20intent\x20being\x20negotiated.\x20This\x20is\x20used\x20to\ - \x20correlate\x20the\x20response\x20with\x20the\x20request.\n\n\r\n\x05\ - \x04\x0b\x02\0\x05\x12\x04\x96\x02\x02\x08\n\r\n\x05\x04\x0b\x02\0\x01\ - \x12\x04\x96\x02\t\x14\n\r\n\x05\x04\x0b\x02\0\x03\x12\x04\x96\x02\x17\ - \x18\n\r\n\x05\x04\x0b\x02\0\x08\x12\x04\x96\x02\x19A\n\x10\n\x08\x04\ - \x0b\x02\0\x08\xaf\x08\x0e\x12\x04\x96\x02\x1a@\n\x0c\n\x04\x04\x0b\x03\ - \0\x12\x04\x98\x02\x02\x1e\n\r\n\x05\x04\x0b\x03\0\x01\x12\x04\x98\x02\n\ - \x1b\n\x0c\n\x04\x04\x0b\x03\x01\x12\x04\x9a\x02\x02\x11\n\r\n\x05\x04\ - \x0b\x03\x01\x01\x12\x04\x9a\x02\n\x0e\n\x0e\n\x04\x04\x0b\x08\0\x12\x06\ - \x9c\x02\x02\xa2\x02\x03\n\r\n\x05\x04\x0b\x08\0\x01\x12\x04\x9c\x02\x08\ - \x10\n<\n\x04\x04\x0b\x02\x01\x12\x04\x9e\x02\x04-\x1a.\x20The\x20artifa\ - ct\x20should\x20be\x20uploaded\x20immediately.\n\n\r\n\x05\x04\x0b\x02\ - \x01\x06\x12\x04\x9e\x02\x04\x15\n\r\n\x05\x04\x0b\x02\x01\x01\x12\x04\ - \x9e\x02\x16(\n\r\n\x05\x04\x0b\x02\x01\x03\x12\x04\x9e\x02+,\n9\n\x04\ - \x04\x0b\x02\x02\x12\x04\xa1\x02\x04\x12\x1a+\x20The\x20candidate\x20art\ - ifact\x20should\x20be\x20dropped.\n\n\r\n\x05\x04\x0b\x02\x02\x06\x12\ - \x04\xa1\x02\x04\x08\n\r\n\x05\x04\x0b\x02\x02\x01\x12\x04\xa1\x02\t\r\n\ - \r\n\x05\x04\x0b\x02\x02\x03\x12\x04\xa1\x02\x10\x11\n\x0c\n\x02\x04\x0c\ - \x12\x06\xa5\x02\0\xbf\x02\x01\n\x0b\n\x03\x04\x0c\x01\x12\x04\xa5\x02\ - \x08\x1d\nf\n\x04\x04\x0c\x02\0\x12\x04\xa7\x02\x02B\x1aX\x20Upload\x20U\ - UID\x20used\x20to\x20provide\x20idempotence\x20and\x20to\x20correlate\ - \x20a\x20response\x20with\x20this\x20request.\n\n\r\n\x05\x04\x0c\x02\0\ - \x05\x12\x04\xa7\x02\x02\x08\n\r\n\x05\x04\x0c\x02\0\x01\x12\x04\xa7\x02\ - \t\x14\n\r\n\x05\x04\x0c\x02\0\x03\x12\x04\xa7\x02\x17\x18\n\r\n\x05\x04\ - \x0c\x02\0\x08\x12\x04\xa7\x02\x19A\n\x10\n\x08\x04\x0c\x02\0\x08\xaf\ - \x08\x0e\x12\x04\xa7\x02\x1a@\n8\n\x04\x04\x0c\x02\x01\x12\x04\xaa\x02\ - \x02>\x1a*\x20The\x20type\x20of\x20the\x20artifact\x20being\x20uploaded.\ - \n\n\r\n\x05\x04\x0c\x02\x01\x05\x12\x04\xaa\x02\x02\x08\n\r\n\x05\x04\ - \x0c\x02\x01\x01\x12\x04\xaa\x02\t\x10\n\r\n\x05\x04\x0c\x02\x01\x03\x12\ - \x04\xaa\x02\x13\x14\n\r\n\x05\x04\x0c\x02\x01\x08\x12\x04\xaa\x02\x15=\ - \n\x10\n\x08\x04\x0c\x02\x01\x08\xaf\x08\x0e\x12\x04\xaa\x02\x16<\nu\n\ - \x04\x04\x0c\x02\x02\x12\x04\xad\x02\x02\x15\x1ag\x20The\x20artifact\x20\ + \x01\x02\x10\x01\x12\"\n\nsession_id\x18\x07\x20\x01(\tH\0R\tsessionId\ + \x88\x01\x01\x1af\n\rMetadataEntry\x12\x10\n\x03key\x18\x01\x20\x01(\tR\ + \x03key\x12?\n\x05value\x18\x02\x20\x01(\x0b2).bitdrift_public.protobuf.\ + logging.v1.DataR\x05value:\x028\x01B\r\n\x0b_session_idJ\x04\x08\x03\x10\ + \x04\"\xd4\x02\n\x1cUploadArtifactIntentResponse\x12(\n\x0bintent_uuid\ + \x18\x01\x20\x01(\tR\nintentUuidB\x07\xfaB\x04r\x02\x10\x01\x12\x83\x01\ + \n\x12upload_immediately\x18\x03\x20\x01(\x0b2R.bitdrift_public.protobuf\ + .client.v1.UploadArtifactIntentResponse.UploadImmediatelyH\0R\x11uploadI\ + mmediately\x12[\n\x04drop\x18\x04\x20\x01(\x0b2E.bitdrift_public.protobu\ + f.client.v1.UploadArtifactIntentResponse.DropH\0R\x04drop\x1a\x13\n\x11U\ + ploadImmediately\x1a\x06\n\x04DropB\n\n\x08decision\"\xba\x04\n\x15Uploa\ + dArtifactRequest\x12(\n\x0bupload_uuid\x18\x01\x20\x01(\tR\nuploadUuidB\ + \x07\xfaB\x04r\x02\x10\x01\x12\x20\n\x07type_id\x18\x02\x20\x01(\tR\x06t\ + ypeIdB\x07\xfaB\x04r\x02\x10\x01\x12\x1a\n\x08contents\x18\x03\x20\x01(\ + \x0cR\x08contents\x12(\n\x0bartifact_id\x18\x04\x20\x01(\tR\nartifactIdB\ + \x07\xfaB\x04r\x02\x10\x01\x12s\n\x0estate_metadata\x18\x05\x20\x03(\x0b\ + 2L.bitdrift_public.protobuf.client.v1.UploadArtifactRequest.StateMetadat\ + aEntryR\rstateMetadata\x128\n\x04time\x18\x06\x20\x01(\x0b2\x1a.google.p\ + rotobuf.TimestampR\x04timeB\x08\xfaB\x05\x8a\x01\x02\x10\x01\x12\x1d\n\n\ + session_id\x18\x07\x20\x01(\tR\tsessionId\x12T\n\rfeature_flags\x18\x08\ + \x20\x03(\x0b2/.bitdrift_public.protobuf.client.v1.FeatureFlagR\x0cfeatu\ + reFlags\x1ak\n\x12StateMetadataEntry\x12\x10\n\x03key\x18\x01\x20\x01(\t\ + R\x03key\x12?\n\x05value\x18\x02\x20\x01(\x0b2).bitdrift_public.protobuf\ + .logging.v1.DataR\x05value:\x028\x01\"X\n\x16UploadArtifactResponse\x12(\ + \n\x0bupload_uuid\x18\x01\x20\x01(\tR\nuploadUuidB\x07\xfaB\x04r\x02\x10\ + \x01\x12\x14\n\x05error\x18\x02\x20\x01(\tR\x05error\"\xf7\x02\n\x11Hand\ + shakeResponse\x12m\n\x0fstream_settings\x18\x01\x20\x01(\x0b2D.bitdrift_\ + public.protobuf.client.v1.HandshakeResponse.StreamSettingsR\x0estreamSet\ + tings\x12>\n\x1bconfiguration_update_status\x18\x02\x20\x01(\rR\x19confi\ + gurationUpdateStatus\x12A\n\x1bopaque_client_state_to_echo\x18\x03\x20\ + \x01(\x0cH\0R\x17opaqueClientStateToEcho\x88\x01\x01\x1aP\n\x0eStreamSet\ + tings\x12>\n\rping_interval\x18\x01\x20\x01(\x0b2\x19.google.protobuf.Du\ + rationR\x0cpingIntervalB\x1e\n\x1c_opaque_client_state_to_echo\"I\n\x0bR\ + ateLimited\x12:\n\x0bretry_after\x18\x01\x20\x01(\x0b2\x19.google.protob\ + uf.DurationR\nretryAfter\"\xca\x01\n\x11LogUploadResponse\x12(\n\x0buplo\ + ad_uuid\x18\x01\x20\x01(\tR\nuploadUuidB\x07\xfaB\x04r\x02\x10\x01\x12\ + \x14\n\x05error\x18\x02\x20\x01(\tR\x05error\x12!\n\x0clogs_dropped\x18\ + \x03\x20\x01(\rR\x0blogsDropped\x12R\n\x0crate_limited\x18\x04\x20\x01(\ + \x0b2/.bitdrift_public.protobuf.client.v1.RateLimitedR\x0brateLimited\"\ + \x9e\n\n\x12StatsUploadRequest\x12(\n\x0bupload_uuid\x18\x01\x20\x01(\tR\ + \nuploadUuidB\x07\xfaB\x04r\x02\x10\x01\x12e\n\x08snapshot\x18\x02\x20\ + \x03(\x0b2?.bitdrift_public.protobuf.client.v1.StatsUploadRequest.Snapsh\ + otR\x08snapshotB\x08\xfaB\x05\x92\x01\x02\x08\x01\x123\n\x07sent_at\x18\ + \x03\x20\x01(\x0b2\x1a.google.protobuf.TimestampR\x06sentAt\x12h\n\ruplo\ + ad_reason\x18\x04\x20\x01(\x0e2C.bitdrift_public.protobuf.client.v1.Stat\ + sUploadRequest.UploadReasonR\x0cuploadReason\x1a\xe9\x06\n\x08Snapshot\ + \x12K\n\x07metrics\x18\x01\x20\x01(\x0b2/.bitdrift_public.protobuf.clien\ + t.v1.MetricsListH\0R\x07metrics\x12l\n\naggregated\x18\x02\x20\x01(\x0b2\ + J.bitdrift_public.protobuf.client.v1.StatsUploadRequest.Snapshot.Aggrega\ + tedH\x01R\naggregated\x12\x86\x01\n\x13metric_id_overflows\x18\x03\x20\ + \x03(\x0b2V.bitdrift_public.protobuf.client.v1.StatsUploadRequest.Snapsh\ + ot.MetricIdOverflowsEntryR\x11metricIdOverflows\x12\x86\x01\n\x13workflo\ + w_debug_data\x18\x04\x20\x03(\x0b2V.bitdrift_public.protobuf.client.v1.S\ + tatsUploadRequest.Snapshot.WorkflowDebugDataEntryR\x11workflowDebugData\ + \x1a\x90\x01\n\nAggregated\x12G\n\x0cperiod_start\x18\x04\x20\x01(\x0b2\ + \x1a.google.protobuf.TimestampR\x0bperiodStartB\x08\xfaB\x05\x8a\x01\x02\ + \x10\x01\x129\n\nperiod_end\x18\x05\x20\x01(\x0b2\x1a.google.protobuf.Ti\ + mestampR\tperiodEnd\x1aD\n\x16MetricIdOverflowsEntry\x12\x10\n\x03key\ + \x18\x01\x20\x01(\tR\x03key\x12\x14\n\x05value\x18\x02\x20\x01(\x04R\x05\ + value:\x028\x01\x1a\x8c\x01\n\x16WorkflowDebugDataEntry\x12\x10\n\x03key\ + \x18\x01\x20\x01(\tR\x03key\x12\\\n\x05value\x18\x02\x20\x01(\x0b2F.bitd\ + rift_public.protobuf.client.v1.DebugDataRequest.WorkflowDebugDataR\x05va\ + lue:\x028\x01B\x14\n\rsnapshot_type\x12\x03\xf8B\x01B\x12\n\x0boccurred_\ + at\x12\x03\xf8B\x01\"l\n\x0cUploadReason\x12\x1d\n\x19UPLOAD_REASON_UNSP\ + ECIFIED\x10\0\x12\x1a\n\x16UPLOAD_REASON_PERIODIC\x10\x01\x12!\n\x1dUPLO\ + AD_REASON_EVENT_TRIGGERED\x10\x02\"~\n\x13StatsUploadResponse\x12(\n\x0b\ + upload_uuid\x18\x01\x20\x01(\tR\nuploadUuidB\x07\xfaB\x04r\x02\x10\x01\ + \x12\x14\n\x05error\x18\x02\x20\x01(\tR\x05error\x12'\n\x0fmetrics_dropp\ + ed\x18\x03\x20\x01(\rR\x0emetricsDropped\"\x0e\n\x0cPongResponse\"\xa1\ + \x06\n\x13ConfigurationUpdate\x12#\n\rversion_nonce\x18\x01\x20\x01(\tR\ + \x0cversionNonce\x12v\n\x12state_of_the_world\x18\x02\x20\x01(\x0b2G.bit\ + drift_public.protobuf.client.v1.ConfigurationUpdate.StateOfTheWorldH\0R\ + \x0fstateOfTheWorld\x1a\xdd\x04\n\x0fStateOfTheWorld\x12b\n\x12buffer_co\ + nfig_list\x18\x03\x20\x01(\x0b24.bitdrift_public.protobuf.config.v1.Buff\ + erConfigListR\x10bufferConfigList\x12u\n\x17workflows_configuration\x18\ + \x04\x20\x01(\x0b2<.bitdrift_public.protobuf.workflow.v1.WorkflowsConfig\ + urationR\x16workflowsConfiguration\x12k\n\x14bdtail_configuration\x18\ + \x06\x20\x01(\x0b28.bitdrift_public.protobuf.bdtail.v1.BdTailConfigurati\ + onsR\x13bdtailConfiguration\x12m\n\x15filters_configuration\x18\x08\x20\ + \x01(\x0b28.bitdrift_public.protobuf.filter.v1.FiltersConfigurationR\x14\ + filtersConfiguration\x12e\n\x0fdebug_workflows\x18\t\x20\x01(\x0b2<.bitd\ + rift_public.protobuf.workflow.v1.WorkflowsConfigurationR\x0edebugWorkflo\ + wsJ\x04\x08\x02\x10\x03J\x04\x08\x07\x10\x08R\x08mll_listR\x16insights_c\ + onfigurationB\r\n\x0bupdate_type\"{\n\rRuntimeUpdate\x12#\n\rversion_non\ + ce\x18\x01\x20\x01(\tR\x0cversionNonce\x12E\n\x07runtime\x18\x02\x20\x01\ + (\x0b2+.bitdrift_public.protobuf.client.v1.RuntimeR\x07runtime\"\xa7\x01\ + \n\rErrorShutdown\x12\x1f\n\x0bgrpc_status\x18\x01\x20\x01(\x05R\ngrpcSt\ + atus\x12!\n\x0cgrpc_message\x18\x02\x20\x01(\tR\x0bgrpcMessage\x12R\n\ + \x0crate_limited\x18\x03\x20\x01(\x0b2/.bitdrift_public.protobuf.client.\ + v1.RateLimitedR\x0brateLimited\"4\n\x0cFlushBuffers\x12$\n\x0ebuffer_id_\ + list\x18\x01\x20\x03(\tR\x0cbufferIdList\"Z\n\x18SankeyPathUploadRespons\ + e\x12(\n\x0bupload_uuid\x18\x01\x20\x01(\tR\nuploadUuidB\x07\xfaB\x04r\ + \x02\x10\x01\x12\x14\n\x05error\x18\x02\x20\x01(\tR\x05error\"\xcb\x02\n\ + \x14SankeyIntentResponse\x12(\n\x0bintent_uuid\x18\x01\x20\x01(\tR\ninte\ + ntUuidB\x07\xfaB\x04r\x02\x10\x01\x12{\n\x12upload_immediately\x18\x03\ + \x20\x01(\x0b2J.bitdrift_public.protobuf.client.v1.SankeyIntentResponse.\ + UploadImmediatelyH\0R\x11uploadImmediately\x12S\n\x04drop\x18\x04\x20\ + \x01(\x0b2=.bitdrift_public.protobuf.client.v1.SankeyIntentResponse.Drop\ + H\0R\x04drop\x1a\x13\n\x11UploadImmediately\x1a\x06\n\x04DropB\n\n\x08de\ + cisionJ\x04\x08\x02\x10\x03R\x08decision\"\xb5\x08\n\x10DebugDataRequest\ + \x12{\n\x13workflow_debug_data\x18\x01\x20\x03(\x0b2K.bitdrift_public.pr\ + otobuf.client.v1.DebugDataRequest.WorkflowDebugDataEntryR\x11workflowDeb\ + ugData\x1a\x87\x02\n\x1bWorkflowTransitionDebugData\x12+\n\x10transition\ + _index\x18\x01\x20\x01(\rH\0R\x0ftransitionIndex\x12/\n\x12timeout_trans\ + ition\x18\x02\x20\x01(\x08H\0R\x11timeoutTransition\x12)\n\x10transition\ + _count\x18\x03\x20\x01(\x04R\x0ftransitionCount\x12L\n\x14last_transitio\ + n_time\x18\x04\x20\x01(\x0b2\x1a.google.protobuf.TimestampR\x12lastTrans\ + itionTimeB\x11\n\x0ftransition_type\x1a\x8c\x01\n\x16WorkflowStateDebugD\ + ata\x12r\n\x0btransitions\x18\x01\x20\x03(\x0b2P.bitdrift_public.protobu\ + f.client.v1.DebugDataRequest.WorkflowTransitionDebugDataR\x0btransitions\ + \x1a\xfb\x02\n\x11WorkflowDebugData\x12j\n\x06states\x18\x01\x20\x03(\ + \x0b2R.bitdrift_public.protobuf.client.v1.DebugDataRequest.WorkflowDebug\ + Data.StatesEntryR\x06states\x12q\n\x0bstart_reset\x18\x02\x20\x01(\x0b2P\ + .bitdrift_public.protobuf.client.v1.DebugDataRequest.WorkflowTransitionD\ + ebugDataR\nstartReset\x1a\x86\x01\n\x0bStatesEntry\x12\x10\n\x03key\x18\ + \x01\x20\x01(\tR\x03key\x12a\n\x05value\x18\x02\x20\x01(\x0b2K.bitdrift_\ + public.protobuf.client.v1.DebugDataRequest.WorkflowStateDebugDataR\x05va\ + lue:\x028\x01\x1a\x8c\x01\n\x16WorkflowDebugDataEntry\x12\x10\n\x03key\ + \x18\x01\x20\x01(\tR\x03key\x12\\\n\x05value\x18\x02\x20\x01(\x0b2F.bitd\ + rift_public.protobuf.client.v1.DebugDataRequest.WorkflowDebugDataR\x05va\ + lue:\x028\x01\"\x15\n\x13StateUpdateResponse\"\x86\x0b\n\x0bApiResponse\ + \x12U\n\thandshake\x18\x01\x20\x01(\x0b25.bitdrift_public.protobuf.clien\ + t.v1.HandshakeResponseH\0R\thandshake\x12V\n\nlog_upload\x18\x02\x20\x01\ + (\x0b25.bitdrift_public.protobuf.client.v1.LogUploadResponseH\0R\tlogUpl\ + oad\x12i\n\x11log_upload_intent\x18\x08\x20\x01(\x0b2;.bitdrift_public.p\ + rotobuf.client.v1.LogUploadIntentResponseH\0R\x0flogUploadIntent\x12\\\n\ + \x0cstats_upload\x18\x07\x20\x01(\x0b27.bitdrift_public.protobuf.client.\ + v1.StatsUploadResponseH\0R\x0bstatsUpload\x12F\n\x04pong\x18\x03\x20\x01\ + (\x0b20.bitdrift_public.protobuf.client.v1.PongResponseH\0R\x04pong\x12l\ + \n\x14configuration_update\x18\x04\x20\x01(\x0b27.bitdrift_public.protob\ + uf.client.v1.ConfigurationUpdateH\0R\x13configurationUpdate\x12Z\n\x0eru\ + ntime_update\x18\x05\x20\x01(\x0b21.bitdrift_public.protobuf.client.v1.R\ + untimeUpdateH\0R\rruntimeUpdate\x12Z\n\x0eerror_shutdown\x18\x06\x20\x01\ + (\x0b21.bitdrift_public.protobuf.client.v1.ErrorShutdownH\0R\rerrorShutd\ + own\x12W\n\rflush_buffers\x18\t\x20\x01(\x0b20.bitdrift_public.protobuf.\ + client.v1.FlushBuffersH\0R\x0cflushBuffers\x12r\n\x15sankey_diagram_uplo\ + ad\x18\x0c\x20\x01(\x0b2<.bitdrift_public.protobuf.client.v1.SankeyPathU\ + ploadResponseH\0R\x13sankeyDiagramUpload\x12p\n\x16sankey_intent_respons\ + e\x18\r\x20\x01(\x0b28.bitdrift_public.protobuf.client.v1.SankeyIntentRe\ + sponseH\0R\x14sankeyIntentResponse\x12e\n\x0fartifact_upload\x18\x0e\x20\ + \x01(\x0b2:.bitdrift_public.protobuf.client.v1.UploadArtifactResponseH\0\ + R\x0eartifactUpload\x12k\n\x0fartifact_intent\x18\x0f\x20\x01(\x0b2@.bit\ + drift_public.protobuf.client.v1.UploadArtifactIntentResponseH\0R\x0earti\ + factIntent\x12\\\n\x0cstate_update\x18\x10\x20\x01(\x0b27.bitdrift_publi\ + c.protobuf.client.v1.StateUpdateResponseH\0R\x0bstateUpdateB\x14\n\rresp\ + onse_type\x12\x03\xf8B\x01J\x04\x08\n\x10\x0bJ\x04\x08\x0b\x10\x0c2x\n\n\ + ApiService\x12j\n\x03Mux\x12..bitdrift_public.protobuf.client.v1.ApiRequ\ + est\x1a/.bitdrift_public.protobuf.client.v1.ApiResponse(\x010\x01J\xea\ + \xdd\x01\n\x07\x12\x05\x07\0\x92\x05\x01\n\xb8\x02\n\x01\x0c\x12\x03\x07\ + \0\x122\xad\x02\x20api\x20-\x20bitdrift's\x20client/server\x20API\x20def\ + initions\n\x20Copyright\x20Bitdrift,\x20Inc.\x20All\x20rights\x20reserve\ + d.\n\n\x20Use\x20of\x20this\x20source\x20code\x20and\x20APIs\x20are\x20g\ + overned\x20by\x20a\x20source\x20available\x20license\x20that\x20can\x20b\ + e\x20found\x20in\n\x20the\x20LICENSE\x20file\x20or\x20at:\n\x20https://p\ + olyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt\ + \n\n\x08\n\x01\x02\x12\x03\t\0+\n\t\n\x02\x03\0\x12\x03\x0b\0@\n\t\n\x02\ + \x03\x01\x12\x03\x0c\0?\n\t\n\x02\x03\x02\x12\x03\r\09\n\t\n\x02\x03\x03\ + \x12\x03\x0e\0:\n\t\n\x02\x03\x04\x12\x03\x0f\09\n\t\n\x02\x03\x05\x12\ + \x03\x10\09\n\t\n\x02\x03\x06\x12\x03\x11\0;\n\t\n\x02\x03\x07\x12\x03\ + \x12\0=\n\t\n\x02\x03\x08\x12\x03\x13\0(\n\t\n\x02\x03\t\x12\x03\x14\0)\ + \n\t\n\x02\x03\n\x12\x03\x15\0!\n\x94\x01\n\x02\x04\0\x12\x04\x19\0\"\ + \x01\x1a\x87\x01\x20File\x20written\x20to\x20disk\x20if\x20the\x20client\ + \x20has\x20been\x20placed\x20in\x20the\x20\"killed\"\x20state\x20and\x20\ + told\x20not\x20to\n\x20contact\x20the\x20server\x20for\x20some\x20period\ + \x20of\x20time.\n\n\n\n\x03\x04\0\x01\x12\x03\x19\x08\x16\n\xe4\x01\n\ + \x04\x04\0\x02\0\x12\x03\x1d\x02\x19\x1a\xd6\x01\x20This\x20is\x20the\ + \x20hash\x20of\x20the\x20API\x20key.\x20If\x20the\x20API\x20key\x20hash\ + \x20changes,\x20we\x20will\x20always\x20ignore\x20the\n\x20kill_until\ + \x20timestamp.\x20This\x20is\x20to\x20ease\x20local\x20development/onboa\ + rding\x20when\x20folks\x20might\x20be\n\x20confused\x20about\x20what\x20\ + API\x20key\x20to\x20use.\n\n\x0c\n\x05\x04\0\x02\0\x05\x12\x03\x1d\x02\ + \x07\n\x0c\n\x05\x04\0\x02\0\x01\x12\x03\x1d\x08\x14\n\x0c\n\x05\x04\0\ + \x02\0\x03\x12\x03\x1d\x17\x18\nr\n\x04\x04\0\x02\x01\x12\x03!\x02+\x1ae\ + \x20The\x20time\x20the\x20client\x20will\x20be\x20killed\x20until.\x20Af\ + ter\x20this\x20time\x20it\x20will\x20try\x20to\x20contact\x20the\x20serv\ + er\n\x20again.\n\n\x0c\n\x05\x04\0\x02\x01\x06\x12\x03!\x02\x1b\n\x0c\n\ + \x05\x04\0\x02\x01\x01\x12\x03!\x1c&\n\x0c\n\x05\x04\0\x02\x01\x03\x12\ + \x03!)*\n\xbb\x01\n\x02\x04\x01\x12\x04&\09\x01\x1a\xae\x01\x20This\x20i\ + s\x20sent\x20both\x20in\x20the\x20initial\x20handshake\x20as\x20well\x20\ + as\x20mid-stream\x20if\x20any\x20of\x20the\x20attributes\x20have\n\x20ch\ + anged.\x20The\x20handshake\x20will\x20fill\x20in\x20all\x20values\x20as\ + \x20part\x20of\x20an\x20initial\x20update.\n\n\n\n\x03\x04\x01\x01\x12\ + \x03&\x08\x1a\n\x0c\n\x04\x04\x01\x03\0\x12\x04'\x02,\x03\n\x0c\n\x05\ + \x04\x01\x03\0\x01\x12\x03'\n\x18\n7\n\x06\x04\x01\x03\0\x02\0\x12\x03)\ + \x04\x1a\x1a(\x20The\x20session\x20ID\x20of\x20the\x20started\x20session\ + .\n\n\x0e\n\x07\x04\x01\x03\0\x02\0\x05\x12\x03)\x04\n\n\x0e\n\x07\x04\ + \x01\x03\0\x02\0\x01\x12\x03)\x0b\x15\n\x0e\n\x07\x04\x01\x03\0\x02\0\ + \x03\x12\x03)\x18\x19\n/\n\x06\x04\x01\x03\0\x02\x01\x12\x03+\x04-\x1a\ + \x20\x20The\x20start\x20time\x20of\x20the\x20session.\n\n\x0e\n\x07\x04\ + \x01\x03\0\x02\x01\x06\x12\x03+\x04\x1d\n\x0e\n\x07\x04\x01\x03\0\x02\ + \x01\x01\x12\x03+\x1e(\n\x0e\n\x07\x04\x01\x03\0\x02\x01\x03\x12\x03++,\ + \n\x0c\n\x04\x04\x01\x03\x01\x12\x04.\x022\x03\n\x0c\n\x05\x04\x01\x03\ + \x01\x01\x12\x03.\n\x1c\n\xbc\x01\n\x06\x04\x01\x03\x01\x02\0\x12\x031\ + \x04)\x1a\xac\x01\x20If\x20one\x20has\x20been\x20supplied,\x20the\x20opa\ + que\x20entity\x20ID.\x20If\x20an\x20update\x20is\x20sent\x20that\x20null\ + s\x20this\x20out\n\x20it\x20means\x20that\x20the\x20unique\x20entity\x20\ + is\x20no\x20longer\x20bound\x20(for\x20example\x20after\x20a\x20logout).\ + \n\n\x0e\n\x07\x04\x01\x03\x01\x02\0\x04\x12\x031\x04\x0c\n\x0e\n\x07\ + \x04\x01\x03\x01\x02\0\x05\x12\x031\r\x13\n\x0e\n\x07\x04\x01\x03\x01\ + \x02\0\x01\x12\x031\x14$\n\x0e\n\x07\x04\x01\x03\x01\x02\0\x03\x12\x031'\ + (\n(\n\x04\x04\x01\x02\0\x12\x035\x02.\x1a\x1b\x20The\x20opaque\x20entit\ + y\x20update.\n\n\x0c\n\x05\x04\x01\x02\0\x06\x12\x035\x02\x14\n\x0c\n\ + \x05\x04\x01\x02\0\x01\x12\x035\x15)\n\x0c\n\x05\x04\x01\x02\0\x03\x12\ + \x035,-\n,\n\x04\x04\x01\x02\x01\x12\x038\x02/\x1a\x1f\x20The\x20list\ + \x20of\x20started\x20sessions.\n\n\x0c\n\x05\x04\x01\x02\x01\x04\x12\x03\ + 8\x02\n\n\x0c\n\x05\x04\x01\x02\x01\x06\x12\x038\x0b\x19\n\x0c\n\x05\x04\ + \x01\x02\x01\x01\x12\x038\x1a*\n\x0c\n\x05\x04\x01\x02\x01\x03\x12\x038-\ + .\n7\n\x02\x04\x02\x12\x04<\0c\x01\x1a+\x20The\x20initial\x20request\x20\ + sent\x20over\x20the\x20stream.\n\n\n\n\x03\x04\x02\x01\x12\x03<\x08\x18\ + \n\xe4\x01\n\x04\x04\x02\x02\0\x12\x03@\x02:\x1a\xd6\x01\x20A\x20set\x20\ + of\x20opaque\x20metadata\x20that\x20identifies\x20the\x20connecting\x20d\ + evice.\x20These\x20will\n\x20remain\x20static\x20for\x20the\x20duration\ + \x20of\x20this\x20stream.\n\x20TODO(snowp):\x20Support\x20updating\x20th\ + ese\x20throughout\x20the\x20session\x20/\x20move\x20to\x20StateUpdateReq\ + uest.\n\n\x0c\n\x05\x04\x02\x02\0\x06\x12\x03@\x02\x1e\n\x0c\n\x05\x04\ + \x02\x02\0\x01\x12\x03@\x1f5\n\x0c\n\x05\x04\x02\x02\0\x03\x12\x03@89\n\ + \n\n\x03\x04\x02\t\x12\x03B\x02\r\n\x0b\n\x04\x04\x02\t\0\x12\x03B\x0b\ + \x0c\n\x0c\n\x05\x04\x02\t\0\x01\x12\x03B\x0b\x0c\n\x0c\n\x05\x04\x02\t\ + \0\x02\x12\x03B\x0b\x0c\n\xab\x02\n\x04\x04\x02\x02\x01\x12\x03H\x02)\ + \x1a\x9d\x02\x20If\x20the\x20client\x20has\x20an\x20active\x20configurat\ + ion,\x20previously\x20obtained\x20via\x20a\x20ConfigurationUpdate\n\x20m\ + essage,\x20it\x20should\x20indicate\x20it\x20in\x20the\x20handshake.\x20\ + This\x20will\x20allow\x20the\x20server\x20to\x20not\x20have\x20to\n\x20s\ + end\x20out\x20a\x20redundant\x20configuration\x20update.\x20If\x20there\ + \x20is\x20no\x20active\x20configuration\x20this\x20should\n\x20be\x20emp\ + ty.\n\n\x0c\n\x05\x04\x02\x02\x01\x05\x12\x03H\x02\x08\n\x0c\n\x05\x04\ + \x02\x02\x01\x01\x12\x03H\t$\n\x0c\n\x05\x04\x02\x02\x01\x03\x12\x03H'(\ + \n\x93\x02\n\x04\x04\x02\x02\x02\x12\x03N\x02#\x1a\x85\x02\x20If\x20the\ + \x20client\x20has\x20an\x20active\x20runtime,\x20previously\x20obtained\ + \x20via\x20a\x20RuntimeUpdate\n\x20message,\x20it\x20should\x20indicate\ + \x20it\x20in\x20the\x20handshake.\x20This\x20will\x20allow\x20the\x20ser\ + ver\x20to\x20not\x20have\x20to\n\x20send\x20out\x20a\x20redundant\x20run\ + time\x20update.\x20If\x20there\x20is\x20no\x20active\x20runtime\x20this\ + \x20should\n\x20be\x20empty.\n\n\x0c\n\x05\x04\x02\x02\x02\x05\x12\x03N\ + \x02\x08\n\x0c\n\x05\x04\x02\x02\x02\x01\x12\x03N\t\x1e\n\x0c\n\x05\x04\ + \x02\x02\x02\x03\x12\x03N!\"\n\n\n\x03\x04\x02\t\x12\x03P\x02\r\n\x0b\n\ + \x04\x04\x02\t\x01\x12\x03P\x0b\x0c\n\x0c\n\x05\x04\x02\t\x01\x01\x12\ + \x03P\x0b\x0c\n\x0c\n\x05\x04\x02\t\x01\x02\x12\x03P\x0b\x0c\n\x97\x01\n\ + \x04\x04\x02\x02\x03\x12\x03T\x02(\x1a\x89\x01\x20Reports\x20the\x20reas\ + on,\x20if\x20any,\x20that\x20the\x20client\x20was\x20previously\x20disco\ + nnected\x20from\x20the\x20server.\x20This\n\x20is\x20useful\x20for\x20de\ + bugging\x20reconnect\x20loops.\n\n\x0c\n\x05\x04\x02\x02\x03\x05\x12\x03\ + T\x02\x08\n\x0c\n\x05\x04\x02\x02\x03\x01\x12\x03T\t#\n\x0c\n\x05\x04\ + \x02\x02\x03\x03\x12\x03T&'\n[\n\x04\x04\x02\x02\x04\x12\x03W\x02\x16\ + \x1aN\x20At\x20the\x20time\x20of\x20the\x20handshake,\x20whether\x20the\ + \x20client\x20is\x20operating\x20in\x20sleep\x20mode.\n\n\x0c\n\x05\x04\ + \x02\x02\x04\x05\x12\x03W\x02\x06\n\x0c\n\x05\x04\x02\x02\x04\x01\x12\ + \x03W\x07\x11\n\x0c\n\x05\x04\x02\x02\x04\x03\x12\x03W\x14\x15\n\xf6\x01\ + \n\x04\x04\x02\x02\x05\x12\x03\\\x02)\x1a\xe8\x01\x20Opaque\x20client\ + \x20state\x20previously\x20provided\x20by\x20the\x20server\x20in\x20a\ + \x20HandshakeResponse.\x20The\x20client\n\x20should\x20continue\x20to\ + \x20send\x20this\x20on\x20every\x20handshake\x20request\x20until\x20the\ + \x20server\x20provides\x20a\x20new\n\x20value\x20(which\x20may\x20be\x20\ + empty\x20to\x20clear\x20existing\x20state).\n\n\x0c\n\x05\x04\x02\x02\ + \x05\x04\x12\x03\\\x02\n\n\x0c\n\x05\x04\x02\x02\x05\x05\x12\x03\\\x0b\ + \x10\n\x0c\n\x05\x04\x02\x02\x05\x01\x12\x03\\\x11$\n\x0c\n\x05\x04\x02\ + \x02\x05\x03\x12\x03\\'(\n\xbe\x02\n\x04\x04\x02\x02\x06\x12\x03b\x02&\ + \x1a\xb0\x02\x20When\x20the\x20handshake\x20request\x20is\x20sent\x20an\ + \x20initial\x20state\x20update\x20will\x20be\x20included\x20with\x20both\ + \n\x20the\x20opaque\x20entity\x20ID\x20(if\x20provided)\x20as\x20well\ + \x20as\x20at\x20least\x20the\x20current\x20session.\x20There\x20may\x20b\ + e\n\x20multiple\x20sessions\x20included\x20if\x20some\x20session\x20tran\ + sitions\x20have\x20happened\x20while\x20offline\x20and\x20have\n\x20not\ + \x20yet\x20been\x20sent\x20to\x20the\x20server.\n\n\x0c\n\x05\x04\x02\ + \x02\x06\x06\x12\x03b\x02\x14\n\x0c\n\x05\x04\x02\x02\x06\x01\x12\x03b\ + \x15!\n\x0c\n\x05\x04\x02\x02\x06\x03\x12\x03b$%\n\xc7\x03\n\x02\x04\x03\ + \x12\x05j\0\x8f\x01\x01\x1a\xb9\x03\x20Notifies\x20the\x20server\x20abou\ + t\x20the\x20intent\x20to\x20upload\x20one\x20or\x20more\x20batches\x20of\ + \x20logs.\x20The\x20client\x20is\x20expected\x20(but\n\x20not\x20require\ + d,\x20for\x20backwards\x20compatibility)\x20to\x20notify\x20the\x20serve\ + r\x20about\x20the\x20intent\x20to\x20upload\n\x20before\x20uploading.\ + \x20The\x20server\x20is\x20thusly\x20able\x20to\x20influence\x20whether\ + \x20the\x20client\n\x20actually\x20uploads\x20(e.g.\x20the\x20backend\ + \x20no\x20longer\x20wants\x20more\x20of\x20these\x20kind\x20of\x20logs)\ + \n\x20or\x20delay\x20the\x20upload\x20(e.g.\x20we\x20are\x20hitting\x20r\ + ate\x20limits\x20and\x20are\x20applying\x20back-pressure).\n\n\n\n\x03\ + \x04\x03\x01\x12\x03j\x08\x1e\n\x9c\x01\n\x04\x04\x03\x02\0\x12\x03m\x02\ + \x17\x1a\x8e\x01\x20The\x20number\x20of\x20logs\x20that\x20the\x20client\ + \x20wants\x20to\x20upload.\x20Note\x20that\x20for\x20a\x20ListenerUpload\ + \x20this\x20is\n\x20an\x20approximation\x20of\x20all\x20logs\x20across\ + \x20all\x20batches.\n\n\x0c\n\x05\x04\x03\x02\0\x05\x12\x03m\x02\x08\n\ + \x0c\n\x05\x04\x03\x02\0\x01\x12\x03m\t\x12\n\x0c\n\x05\x04\x03\x02\0\ + \x03\x12\x03m\x15\x16\n\x9f\x01\n\x04\x04\x03\x02\x01\x12\x03q\x02\x18\ + \x1a\x91\x01\x20The\x20size\x20of\x20the\x20intended\x20upload,\x20in\ + \x20bytes.\x20Note\x20that\x20for\x20a\x20ListenerUpload\x20this\x20is\n\ + \x20an\x20approximation\x20of\x20the\x20size\x20of\x20all\x20logs\x20acr\ + oss\x20all\x20batches.\n\n\x0c\n\x05\x04\x03\x02\x01\x05\x12\x03q\x02\ + \x08\n\x0c\n\x05\x04\x03\x02\x01\x01\x12\x03q\t\x13\n\x0c\n\x05\x04\x03\ + \x02\x01\x03\x12\x03q\x16\x17\n7\n\x04\x04\x03\x02\x02\x12\x03t\x02\x17\ + \x1a*\x20The\x20buffer\x20these\x20logs\x20are\x20uploaded\x20from.\n\n\ + \x0c\n\x05\x04\x03\x02\x02\x05\x12\x03t\x02\x08\n\x0c\n\x05\x04\x03\x02\ + \x02\x01\x12\x03t\t\x12\n\x0c\n\x05\x04\x03\x02\x02\x03\x12\x03t\x15\x16\ + \n\xd6\x01\n\x04\x04\x03\x02\x03\x12\x03y\x02\x19\x1a\xc8\x01\x20The\x20\ + client\x20generated\x20UUID\x20for\x20this\x20intent.\x20This\x20allows\ + \x20the\x20server\x20to\x20enforce\x20idempotence\n\x20during\x20intent\ + \x20negotiation\x20as\x20well\x20as\x20allowing\x20for\x20parallel\x20in\ + tent\x20requests\x20to\x20be\x20responded\n\x20to\x20out\x20of\x20order.\ + \n\n\x0c\n\x05\x04\x03\x02\x03\x05\x12\x03y\x02\x08\n\x0c\n\x05\x04\x03\ + \x02\x03\x01\x12\x03y\t\x14\n\x0c\n\x05\x04\x03\x02\x03\x03\x12\x03y\x17\ + \x18\n\x8f\x01\n\x04\x04\x03\x02\x04\x12\x03}\x02\x18\x1a\x81\x01\x20The\ + \x20session\x20ID\x20of\x20the\x20log\x20that\x20caused\x20the\x20intent\ + \x20negotiation.\x20This\x20allows\x20correlating\x20the\x20intent\x20wi\ + th\n\x20a\x20specific\x20user\x20session.\n\n\x0c\n\x05\x04\x03\x02\x04\ + \x05\x12\x03}\x02\x08\n\x0c\n\x05\x04\x03\x02\x04\x01\x12\x03}\t\x13\n\ + \x0c\n\x05\x04\x03\x02\x04\x03\x12\x03}\x16\x17\n\r\n\x04\x04\x03\x03\0\ + \x12\x05\x7f\x02\x82\x01\x03\n\x0c\n\x05\x04\x03\x03\0\x01\x12\x03\x7f\n\ + \x1e\n>\n\x06\x04\x03\x03\0\x02\0\x12\x04\x81\x01\x04,\x1a.\x20The\x20li\ + stener(s)\x20which\x20triggered\x20this\x20upload.\n\n\x0f\n\x07\x04\x03\ + \x03\0\x02\0\x04\x12\x04\x81\x01\x04\x0c\n\x0f\n\x07\x04\x03\x03\0\x02\0\ + \x05\x12\x04\x81\x01\r\x13\n\x0f\n\x07\x04\x03\x03\0\x02\0\x01\x12\x04\ + \x81\x01\x14'\n\x0f\n\x07\x04\x03\x03\0\x02\0\x03\x12\x04\x81\x01*+\n\ + \x0e\n\x04\x04\x03\x03\x01\x12\x06\x84\x01\x02\x87\x01\x03\n\r\n\x05\x04\ + \x03\x03\x01\x01\x12\x04\x84\x01\n\x20\nc\n\x06\x04\x03\x03\x01\x02\0\ + \x12\x04\x86\x01\x04;\x1aS\x20An\x20opaque\x20identifier\x20that\x20is\ + \x20used\x20to\x20identify\x20the\x20reason\x20for\x20the\x20session\x20\ + capture.\n\n\x0f\n\x07\x04\x03\x03\x01\x02\0\x05\x12\x04\x86\x01\x04\n\n\ + \x0f\n\x07\x04\x03\x03\x01\x02\0\x01\x12\x04\x86\x01\x0b\r\n\x0f\n\x07\ + \x04\x03\x03\x01\x02\0\x03\x12\x04\x86\x01\x10\x11\n\x0f\n\x07\x04\x03\ + \x03\x01\x02\0\x08\x12\x04\x86\x01\x12:\n\x12\n\n\x04\x03\x03\x01\x02\0\ + \x08\xaf\x08\x0e\x12\x04\x86\x01\x139\n\x0e\n\x04\x04\x03\x08\0\x12\x06\ + \x89\x01\x02\x8e\x01\x03\n\r\n\x05\x04\x03\x08\0\x01\x12\x04\x89\x01\x08\ + \x13\n\x0c\n\x04\x04\x03\x02\x05\x12\x04\x8a\x01\x044\n\r\n\x05\x04\x03\ + \x02\x05\x06\x12\x04\x8a\x01\x04\x18\n\r\n\x05\x04\x03\x02\x05\x01\x12\ + \x04\x8a\x01\x19/\n\r\n\x05\x04\x03\x02\x05\x03\x12\x04\x8a\x0123\nG\n\ + \x04\x04\x03\x02\x06\x12\x04\x8d\x01\x048\x1a9\x20Session\x20capture\x20\ + was\x20explicitly\x20triggered\x20by\x20the\x20client.\n\n\r\n\x05\x04\ + \x03\x02\x06\x06\x12\x04\x8d\x01\x04\x1a\n\r\n\x05\x04\x03\x02\x06\x01\ + \x12\x04\x8d\x01\x1b3\n\r\n\x05\x04\x03\x02\x06\x03\x12\x04\x8d\x0167\n\ + \x0c\n\x02\x04\x04\x12\x06\x91\x01\0\xa2\x01\x01\n\x0b\n\x03\x04\x04\x01\ + \x12\x04\x91\x01\x08\x1f\n8\n\x04\x04\x04\x02\0\x12\x04\x93\x01\x02\x19\ + \x1a*\x20The\x20UUID\x20of\x20the\x20intent\x20being\x20negotiated.\n\n\ + \r\n\x05\x04\x04\x02\0\x05\x12\x04\x93\x01\x02\x08\n\r\n\x05\x04\x04\x02\ + \0\x01\x12\x04\x93\x01\t\x14\n\r\n\x05\x04\x04\x02\0\x03\x12\x04\x93\x01\ + \x17\x18\n\x0c\n\x04\x04\x04\x03\0\x12\x04\x95\x01\x02\x1e\n\r\n\x05\x04\ + \x04\x03\0\x01\x12\x04\x95\x01\n\x1b\na\n\x04\x04\x04\x03\x01\x12\x06\ + \x97\x01\x02\x99\x01\x03\"Q\x20If\x20the\x20upload\x20intent\x20was\x20a\ + \x20ListenerUpload\x20the\x20entire\x20upload\x20should\x20be\x20cancele\ + d.\n\n\r\n\x05\x04\x04\x03\x01\x01\x12\x04\x97\x01\n\x0e\n\x0e\n\x04\x04\ + \x04\x08\0\x12\x06\x9b\x01\x02\xa1\x01\x03\n\r\n\x05\x04\x04\x08\0\x01\ + \x12\x04\x9b\x01\x08\x10\n7\n\x04\x04\x04\x02\x01\x12\x04\x9d\x01\x04-\ + \x1a)\x20The\x20log\x20should\x20be\x20uploaded\x20immediately.\n\n\r\n\ + \x05\x04\x04\x02\x01\x06\x12\x04\x9d\x01\x04\x15\n\r\n\x05\x04\x04\x02\ + \x01\x01\x12\x04\x9d\x01\x16(\n\r\n\x05\x04\x04\x02\x01\x03\x12\x04\x9d\ + \x01+,\n6\n\x04\x04\x04\x02\x02\x12\x04\xa0\x01\x04\x12\x1a(\x20The\x20c\ + andidate\x20batch\x20should\x20be\x20dropped.\n\n\r\n\x05\x04\x04\x02\ + \x02\x06\x12\x04\xa0\x01\x04\x08\n\r\n\x05\x04\x04\x02\x02\x01\x12\x04\ + \xa0\x01\t\r\n\r\n\x05\x04\x04\x02\x02\x03\x12\x04\xa0\x01\x10\x11\n,\n\ + \x02\x04\x05\x12\x06\xa5\x01\0\xb9\x01\x01\x1a\x1e\x20A\x20single\x20log\ + \x20upload\x20payload.\n\n\x0b\n\x03\x04\x05\x01\x12\x04\xa5\x01\x08\x18\ + \n\x88\x01\n\x04\x04\x05\x02\0\x12\x04\xa8\x01\x02B\x1az\x20A\x20UUID\ + \x20(v4)\x20associated\x20with\x20this\x20upload.\x20This\x20should\x20b\ + e\x20generated\x20by\x20the\n\x20client.\x20Retries\x20should\x20use\x20\ + the\x20same\x20upload_id.\n\n\r\n\x05\x04\x05\x02\0\x05\x12\x04\xa8\x01\ + \x02\x08\n\r\n\x05\x04\x05\x02\0\x01\x12\x04\xa8\x01\t\x14\n\r\n\x05\x04\ + \x05\x02\0\x03\x12\x04\xa8\x01\x17\x18\n\r\n\x05\x04\x05\x02\0\x08\x12\ + \x04\xa8\x01\x19A\n\x10\n\x08\x04\x05\x02\0\x08\xaf\x08\x0e\x12\x04\xa8\ + \x01\x1a@\n\xda\x01\n\x04\x04\x05\x02\x01\x12\x04\xad\x01\x02,\x1a\xcb\ + \x01\x20A\x20repeated\x20set\x20of\x20flatbuffer\x20encoding\x20of\x20a\ + \x20number\x20of\x20log\x20lines.\x20Each\x20log\x20line\x20is\x20of\x20\ + type\n\x20Log\x20defined\x20in\x20buffer_log.fbs.\x20This\x20is\x20depre\ + cated.\x20New\x20clients\x20send\x20protobuf\x20encoded\x20logs\n\x20in\ + \x20the\x20'logs'\x20field.\n\n\r\n\x05\x04\x05\x02\x01\x04\x12\x04\xad\ + \x01\x02\n\n\r\n\x05\x04\x05\x02\x01\x05\x12\x04\xad\x01\x0b\x10\n\r\n\ + \x05\x04\x05\x02\x01\x01\x12\x04\xad\x01\x11'\n\r\n\x05\x04\x05\x02\x01\ + \x03\x12\x04\xad\x01*+\nO\n\x04\x04\x05\x02\x02\x12\x04\xb0\x01\x02\x20\ + \x1aA\x20Logs\x20encoded\x20in\x20bitdrift_public.protobuf.logging.v1.Lo\ + g\x20format.\n\n\r\n\x05\x04\x05\x02\x02\x04\x12\x04\xb0\x01\x02\n\n\r\n\ + \x05\x04\x05\x02\x02\x05\x12\x04\xb0\x01\x0b\x10\n\r\n\x05\x04\x05\x02\ + \x02\x01\x12\x04\xb0\x01\x11\x1b\n\r\n\x05\x04\x05\x02\x02\x03\x12\x04\ + \xb0\x01\x1e\x1f\nG\n\x04\x04\x05\x02\x03\x12\x04\xb3\x01\x02B\x1a9\x20T\ + he\x20UUID\x20(v4)\x20of\x20the\x20buffer\x20that\x20is\x20producing\x20\ + the\x20logs.\n\n\r\n\x05\x04\x05\x02\x03\x05\x12\x04\xb3\x01\x02\x08\n\r\ + \n\x05\x04\x05\x02\x03\x01\x12\x04\xb3\x01\t\x14\n\r\n\x05\x04\x05\x02\ + \x03\x03\x12\x04\xb3\x01\x17\x18\n\r\n\x05\x04\x05\x02\x03\x08\x12\x04\ + \xb3\x01\x19A\n\x10\n\x08\x04\x05\x02\x03\x08\xaf\x08\x0e\x12\x04\xb3\ + \x01\x1a@\n\xc8\x01\n\x04\x04\x05\x02\x04\x12\x04\xb8\x01\x02\x13\x1a\ + \xb9\x01\x20Whether\x20the\x20server\x20should\x20not\x20respond\x20to\ + \x20this\x20upload.\x20This\x20is\x20used\x20for\x20high\n\x20throughput\ + ,\x20low\x20value\x20logs\x20where\x20the\x20client\x20does\x20not\x20ne\ + ed\x20to\x20know\x20whether\n\x20the\x20upload\x20succeeded\x20or\x20fai\ + led.\n\n\r\n\x05\x04\x05\x02\x04\x05\x12\x04\xb8\x01\x02\x06\n\r\n\x05\ + \x04\x05\x02\x04\x01\x12\x04\xb8\x01\x07\x0e\n\r\n\x05\x04\x05\x02\x04\ + \x03\x12\x04\xb8\x01\x11\x12\nS\n\x02\x04\x06\x12\x06\xbc\x01\0\xbf\x01\ + \x01\x1aE\x20Empty\x20message\x20to\x20maintain\x20a\x20application\x20l\ + ayer\x20keep\x20alive\x20mechanism.\n\n\x0b\n\x03\x04\x06\x01\x12\x04\ + \xbc\x01\x08\x13\nW\n\x04\x04\x06\x02\0\x12\x04\xbe\x01\x02\x16\x1aI\x20\ + At\x20the\x20time\x20of\x20the\x20ping,\x20whether\x20the\x20client\x20i\ + s\x20operating\x20in\x20sleep\x20mode.\n\n\r\n\x05\x04\x06\x02\0\x05\x12\ + \x04\xbe\x01\x02\x06\n\r\n\x05\x04\x06\x02\0\x01\x12\x04\xbe\x01\x07\x11\ + \n\r\n\x05\x04\x06\x02\0\x03\x12\x04\xbe\x01\x14\x15\nD\n\x02\x04\x07\ + \x12\x06\xc2\x01\0\xd5\x01\x01\x1a6\x20Configuration\x20update\x20respon\ + se\x20from\x20client\x20to\x20server.\n\n\x0b\n\x03\x04\x07\x01\x12\x04\ + \xc2\x01\x08\x1e\n\x0e\n\x04\x04\x07\x03\0\x12\x06\xc3\x01\x02\xc9\x01\ + \x03\n\r\n\x05\x04\x07\x03\0\x01\x12\x04\xc3\x01\n\x0e\nL\n\x06\x04\x07\ + \x03\0\x02\0\x12\x04\xc5\x01\x04\x1d\x1a<\x20The\x20version\x20nonce\x20\ + of\x20the\x20configuration\x20update\x20that\x20failed.\n\n\x0f\n\x07\ + \x04\x07\x03\0\x02\0\x05\x12\x04\xc5\x01\x04\n\n\x0f\n\x07\x04\x07\x03\0\ + \x02\0\x01\x12\x04\xc5\x01\x0b\x18\n\x0f\n\x07\x04\x07\x03\0\x02\0\x03\ + \x12\x04\xc5\x01\x1b\x1c\n/\n\x06\x04\x07\x03\0\x02\x01\x12\x04\xc8\x01\ + \x04\x1d\x1a\x1f\x20Error\x20details\x20of\x20the\x20failure.\n\n\x0f\n\ + \x07\x04\x07\x03\0\x02\x01\x05\x12\x04\xc8\x01\x04\n\n\x0f\n\x07\x04\x07\ + \x03\0\x02\x01\x01\x12\x04\xc8\x01\x0b\x18\n\x0f\n\x07\x04\x07\x03\0\x02\ + \x01\x03\x12\x04\xc8\x01\x1b\x1c\n\xca\x01\n\x04\x04\x07\x02\0\x12\x04\ + \xce\x01\x02(\x1a\xbb\x01\x20The\x20version\x20nonce\x20that\x20the\x20c\ + lient\x20is\x20actually\x20using.\x20This\x20version\x20nonce\x20was\x20\ + sent\x20in\x20a\n\x20ConfigurationUpdate\x20message.\x20If\x20no\x20conf\ + iguration\x20has\x20been\x20applied\x20(NACK\x20only)\x20this\x20will\ + \x20be\n\x20empty.\n\n\r\n\x05\x04\x07\x02\0\x05\x12\x04\xce\x01\x02\x08\ + \n\r\n\x05\x04\x07\x02\0\x01\x12\x04\xce\x01\t#\n\r\n\x05\x04\x07\x02\0\ + \x03\x12\x04\xce\x01&'\n\xaa\x02\n\x04\x04\x07\x02\x01\x12\x04\xd4\x01\ + \x02\x10\x1a\x9b\x02\x20If\x20a\x20configuration\x20update\x20failed,\ + \x20the\x20client\x20should\x20respond\x20to\x20the\x20server\x20and\x20\ + let\x20it\x20know.\n\x20It\x20should\x20continue\x20to\x20use\x20the\x20\ + last\x20good\x20config.\x20This\x20message\x20is\x20empty\x20on\x20succe\ + ss,\x20and\x20the\n\x20client\x20should\x20respond\x20with\x20last_appli\ + ed_version_nonce\x20being\x20equal\x20to\x20the\x20update\x20that\x20was\ + \n\x20applied.\n\n\r\n\x05\x04\x07\x02\x01\x06\x12\x04\xd4\x01\x02\x06\n\ + \r\n\x05\x04\x07\x02\x01\x01\x12\x04\xd4\x01\x07\x0b\n\r\n\x05\x04\x07\ + \x02\x01\x03\x12\x04\xd4\x01\x0e\x0f\n\xba\x02\n\x02\x04\x08\x12\x06\xdb\ + \x01\0\xf0\x01\x01\x1a\xab\x02\x20A\x20multiplexed\x20request\x20sent\ + \x20over\x20the\x20bitdrift\x20API.\x20Upon\x20stream\x20creation,\x20th\ + e\n\x20client\x20will\x20issue\x20a\x20single\x20handshake\x20request,\ + \x20then\x20await\x20a\x20handshake\n\x20response.\x20Once\x20the\x20han\ + dshake\x20has\x20completed,\x20the\x20client\x20may\x20issue\x20any\x20n\ + umber\n\x20of\x20non-handshake\x20requests;\x20corresponding\x20response\ + s\x20may\x20come\x20in\x20any\x20order.\n\n\x0b\n\x03\x04\x08\x01\x12\ + \x04\xdb\x01\x08\x12\n\x0e\n\x04\x04\x08\x08\0\x12\x06\xdc\x01\x02\xec\ + \x01\x03\n\r\n\x05\x04\x08\x08\0\x01\x12\x04\xdc\x01\x08\x14\n\r\n\x05\ + \x04\x08\x08\0\x02\x12\x04\xdd\x01\x04&\n\x0f\n\x07\x04\x08\x08\0\x02\ + \xaf\x08\x12\x04\xdd\x01\x04&\n\x0c\n\x04\x04\x08\x02\0\x12\x04\xdf\x01\ + \x04#\n\r\n\x05\x04\x08\x02\0\x06\x12\x04\xdf\x01\x04\x14\n\r\n\x05\x04\ + \x08\x02\0\x01\x12\x04\xdf\x01\x15\x1e\n\r\n\x05\x04\x08\x02\0\x03\x12\ + \x04\xdf\x01!\"\n\x0c\n\x04\x04\x08\x02\x01\x12\x04\xe0\x01\x041\n\r\n\ + \x05\x04\x08\x02\x01\x06\x12\x04\xe0\x01\x04\x1a\n\r\n\x05\x04\x08\x02\ + \x01\x01\x12\x04\xe0\x01\x1b,\n\r\n\x05\x04\x08\x02\x01\x03\x12\x04\xe0\ + \x01/0\n\x0c\n\x04\x04\x08\x02\x02\x12\x04\xe1\x01\x04$\n\r\n\x05\x04\ + \x08\x02\x02\x06\x12\x04\xe1\x01\x04\x14\n\r\n\x05\x04\x08\x02\x02\x01\ + \x12\x04\xe1\x01\x15\x1f\n\r\n\x05\x04\x08\x02\x02\x03\x12\x04\xe1\x01\"\ + #\n\x0c\n\x04\x04\x08\x02\x03\x12\x04\xe2\x01\x04(\n\r\n\x05\x04\x08\x02\ + \x03\x06\x12\x04\xe2\x01\x04\x16\n\r\n\x05\x04\x08\x02\x03\x01\x12\x04\ + \xe2\x01\x17#\n\r\n\x05\x04\x08\x02\x03\x03\x12\x04\xe2\x01&'\n\x0c\n\ + \x04\x04\x08\x02\x04\x12\x04\xe3\x01\x04\x19\n\r\n\x05\x04\x08\x02\x04\ + \x06\x12\x04\xe3\x01\x04\x0f\n\r\n\x05\x04\x08\x02\x04\x01\x12\x04\xe3\ + \x01\x10\x14\n\r\n\x05\x04\x08\x02\x04\x03\x12\x04\xe3\x01\x17\x18\n\x0c\ + \n\x04\x04\x08\x02\x05\x12\x04\xe4\x01\x048\n\r\n\x05\x04\x08\x02\x05\ + \x06\x12\x04\xe4\x01\x04\x1a\n\r\n\x05\x04\x08\x02\x05\x01\x12\x04\xe4\ + \x01\x1b3\n\r\n\x05\x04\x08\x02\x05\x03\x12\x04\xe4\x0167\n\x0c\n\x04\ + \x04\x08\x02\x06\x12\x04\xe5\x01\x042\n\r\n\x05\x04\x08\x02\x06\x06\x12\ + \x04\xe5\x01\x04\x1a\n\r\n\x05\x04\x08\x02\x06\x01\x12\x04\xe5\x01\x1b-\ + \n\r\n\x05\x04\x08\x02\x06\x03\x12\x04\xe5\x0101\n\x0c\n\x04\x04\x08\x02\ + \x07\x12\x04\xe6\x01\x044\n\r\n\x05\x04\x08\x02\x07\x06\x12\x04\xe6\x01\ + \x04\x1b\n\r\n\x05\x04\x08\x02\x07\x01\x12\x04\xe6\x01\x1c.\n\r\n\x05\ + \x04\x08\x02\x07\x03\x12\x04\xe6\x0113\n\x0c\n\x04\x04\x08\x02\x08\x12\ + \x04\xe7\x01\x04+\n\r\n\x05\x04\x08\x02\x08\x06\x12\x04\xe7\x01\x04\x17\ + \n\r\n\x05\x04\x08\x02\x08\x01\x12\x04\xe7\x01\x18%\n\r\n\x05\x04\x08\ + \x02\x08\x03\x12\x04\xe7\x01(*\n\x0c\n\x04\x04\x08\x02\t\x12\x04\xe8\x01\ + \x04/\n\r\n\x05\x04\x08\x02\t\x06\x12\x04\xe8\x01\x04\x19\n\r\n\x05\x04\ + \x08\x02\t\x01\x12\x04\xe8\x01\x1a)\n\r\n\x05\x04\x08\x02\t\x03\x12\x04\ + \xe8\x01,.\n\x0c\n\x04\x04\x08\x02\n\x12\x04\xe9\x01\x045\n\r\n\x05\x04\ + \x08\x02\n\x06\x12\x04\xe9\x01\x04\x1f\n\r\n\x05\x04\x08\x02\n\x01\x12\ + \x04\xe9\x01\x20/\n\r\n\x05\x04\x08\x02\n\x03\x12\x04\xe9\x0124\n\x0c\n\ + \x04\x04\x08\x02\x0b\x12\x04\xea\x01\x04%\n\r\n\x05\x04\x08\x02\x0b\x06\ + \x12\x04\xea\x01\x04\x14\n\r\n\x05\x04\x08\x02\x0b\x01\x12\x04\xea\x01\ + \x15\x1f\n\r\n\x05\x04\x08\x02\x0b\x03\x12\x04\xea\x01\"$\n\x0c\n\x04\ + \x04\x08\x02\x0c\x12\x04\xeb\x01\x04)\n\r\n\x05\x04\x08\x02\x0c\x06\x12\ + \x04\xeb\x01\x04\x16\n\r\n\x05\x04\x08\x02\x0c\x01\x12\x04\xeb\x01\x17#\ + \n\r\n\x05\x04\x08\x02\x0c\x03\x12\x04\xeb\x01&(\n\x0b\n\x03\x04\x08\t\ + \x12\x04\xee\x01\x02\r\n\x0c\n\x04\x04\x08\t\0\x12\x04\xee\x01\x0b\x0c\n\ + \r\n\x05\x04\x08\t\0\x01\x12\x04\xee\x01\x0b\x0c\n\r\n\x05\x04\x08\t\0\ + \x02\x12\x04\xee\x01\x0b\x0c\n\x0b\n\x03\x04\x08\t\x12\x04\xef\x01\x02\r\ + \n\x0c\n\x04\x04\x08\t\x01\x12\x04\xef\x01\x0b\x0c\n\r\n\x05\x04\x08\t\ + \x01\x01\x12\x04\xef\x01\x0b\x0c\n\r\n\x05\x04\x08\t\x01\x02\x12\x04\xef\ + \x01\x0b\x0c\n:\n\x02\x04\t\x12\x06\xf3\x01\0\x86\x02\x01\x1a,\x20A\x20r\ + equest\x20to\x20upload\x20a\x20Sankey\x20diagram\x20path.\n\n\x0b\n\x03\ + \x04\t\x01\x12\x04\xf3\x01\x08\x1f\nf\n\x04\x04\t\x02\0\x12\x04\xf5\x01\ + \x02B\x1aX\x20Upload\x20UUID\x20used\x20to\x20provide\x20idempotence\x20\ + and\x20to\x20correlate\x20a\x20response\x20with\x20this\x20request.\n\n\ + \r\n\x05\x04\t\x02\0\x05\x12\x04\xf5\x01\x02\x08\n\r\n\x05\x04\t\x02\0\ + \x01\x12\x04\xf5\x01\t\x14\n\r\n\x05\x04\t\x02\0\x03\x12\x04\xf5\x01\x17\ + \x18\n\r\n\x05\x04\t\x02\0\x08\x12\x04\xf5\x01\x19A\n\x10\n\x08\x04\t\ + \x02\0\x08\xaf\x08\x0e\x12\x04\xf5\x01\x1a@\n\xc1\x01\n\x04\x04\t\x03\0\ + \x12\x06\xf9\x01\x02\xfc\x01\x03\x1a\xb0\x01\x20A\x20single\x20node\x20i\ + n\x20the\x20Sankey\x20diagram.\x20This\x20differs\x20from\x20workflow\ + \x20states.\x20Each\x20node\x20corresponds\n\x20to\x20a\x20single\x20tra\ + nsition\x20from\x20a\x20workflow\x20origin\x20state\x20to\x20a\x20workfl\ + ow\x20target\x20state.\n\n\r\n\x05\x04\t\x03\0\x01\x12\x04\xf9\x01\n\x0e\ + \n;\n\x06\x04\t\x03\0\x02\0\x12\x04\xfb\x01\x04H\x1a+\x20The\x20value\ + \x20extracted\x20from\x20the\x20matched\x20log.\n\n\x0f\n\x07\x04\t\x03\ + \0\x02\0\x05\x12\x04\xfb\x01\x04\n\n\x0f\n\x07\x04\t\x03\0\x02\0\x01\x12\ + \x04\xfb\x01\x0b\x1a\n\x0f\n\x07\x04\t\x03\0\x02\0\x03\x12\x04\xfb\x01\ + \x1d\x1e\n\x0f\n\x07\x04\t\x03\0\x02\0\x08\x12\x04\xfb\x01\x1fG\n\x12\n\ + \n\x04\t\x03\0\x02\0\x08\xaf\x08\x0e\x12\x04\xfb\x01\x20F\n\"\n\x04\x04\ + \t\x02\x01\x12\x04\xff\x01\x029\x1a\x14\x20Sankey\x20diagram\x20ID.\n\n\ + \r\n\x05\x04\t\x02\x01\x05\x12\x04\xff\x01\x02\x08\n\r\n\x05\x04\t\x02\ + \x01\x01\x12\x04\xff\x01\t\x0b\n\r\n\x05\x04\t\x02\x01\x03\x12\x04\xff\ + \x01\x0e\x0f\n\r\n\x05\x04\t\x02\x01\x08\x12\x04\xff\x01\x108\n\x10\n\ + \x08\x04\t\x02\x01\x08\xaf\x08\x0e\x12\x04\xff\x01\x117\n\x8d\x02\n\x04\ + \x04\t\x02\x02\x12\x04\x83\x02\x02>\x1a\xfe\x01\x20The\x20identifier\x20\ + that\x20represents\x20a\x20traversed\x20state's\x20path\x20registered\ + \x20for\x20a\x20diagram.\x20Two\x20diagram\x20paths\n\x20within\x20the\ + \x20same\x20diagram\x20can\x20have\x20the\x20same\x20ID\x20only\x20if\ + \x20their\x20nodes\x20are\x20identical.\n\x20Conflicts\x20in\x20diagram\ + \x20path\x20IDs\x20between\x20different\x20diagrams\x20are\x20possible.\ + \n\n\r\n\x05\x04\t\x02\x02\x05\x12\x04\x83\x02\x02\x08\n\r\n\x05\x04\t\ + \x02\x02\x01\x12\x04\x83\x02\t\x10\n\r\n\x05\x04\t\x02\x02\x03\x12\x04\ + \x83\x02\x13\x14\n\r\n\x05\x04\t\x02\x02\x08\x12\x04\x83\x02\x15=\n\x10\ + \n\x08\x04\t\x02\x02\x08\xaf\x08\x0e\x12\x04\x83\x02\x16<\n4\n\x04\x04\t\ + \x02\x03\x12\x04\x85\x02\x02G\x1a&\x20The\x20list\x20of\x20traversed\x20\ + diagram\x20nodes.\n\n\r\n\x05\x04\t\x02\x03\x04\x12\x04\x85\x02\x02\n\n\ + \r\n\x05\x04\t\x02\x03\x06\x12\x04\x85\x02\x0b\x0f\n\r\n\x05\x04\t\x02\ + \x03\x01\x12\x04\x85\x02\x10\x15\n\r\n\x05\x04\t\x02\x03\x03\x12\x04\x85\ + \x02\x18\x19\n\r\n\x05\x04\t\x02\x03\x08\x12\x04\x85\x02\x1aF\n\x10\n\ + \x08\x04\t\x02\x03\x08\xaf\x08\x12\x12\x04\x85\x02\x1bE\nA\n\x02\x04\n\ + \x12\x06\x89\x02\0\x92\x02\x01\x1a3\x20A\x20request\x20to\x20ask\x20whet\ + her\x20to\x20upload\x20a\x20Sankey\x20path.\n\n\x0b\n\x03\x04\n\x01\x12\ + \x04\x89\x02\x08\x1b\nq\n\x04\x04\n\x02\0\x12\x04\x8b\x02\x02B\x1ac\x20T\ + he\x20UUID\x20of\x20the\x20intent\x20being\x20negotiated.\x20This\x20is\ + \x20used\x20to\x20correlate\x20the\x20response\x20with\x20the\x20request\ + .\n\n\r\n\x05\x04\n\x02\0\x05\x12\x04\x8b\x02\x02\x08\n\r\n\x05\x04\n\ + \x02\0\x01\x12\x04\x8b\x02\t\x14\n\r\n\x05\x04\n\x02\0\x03\x12\x04\x8b\ + \x02\x17\x18\n\r\n\x05\x04\n\x02\0\x08\x12\x04\x8b\x02\x19A\n\x10\n\x08\ + \x04\n\x02\0\x08\xaf\x08\x0e\x12\x04\x8b\x02\x1a@\nG\n\x04\x04\n\x02\x01\ + \x12\x04\x8e\x02\x02>\x1a9\x20The\x20ID\x20of\x20the\x20path\x20that\x20\ + is\x20being\x20considered\x20for\x20upload.\n\n\r\n\x05\x04\n\x02\x01\ + \x05\x12\x04\x8e\x02\x02\x08\n\r\n\x05\x04\n\x02\x01\x01\x12\x04\x8e\x02\ + \t\x10\n\r\n\x05\x04\n\x02\x01\x03\x12\x04\x8e\x02\x13\x14\n\r\n\x05\x04\ + \n\x02\x01\x08\x12\x04\x8e\x02\x15=\n\x10\n\x08\x04\n\x02\x01\x08\xaf\ + \x08\x0e\x12\x04\x8e\x02\x16<\nF\n\x04\x04\n\x02\x02\x12\x04\x91\x02\x02\ + H\x1a8\x20The\x20ID\x20of\x20the\x20diagram\x20that\x20the\x20path\x20wa\ + s\x20discovered\x20in.\n\n\r\n\x05\x04\n\x02\x02\x05\x12\x04\x91\x02\x02\ + \x08\n\r\n\x05\x04\n\x02\x02\x01\x12\x04\x91\x02\t\x1a\n\r\n\x05\x04\n\ + \x02\x02\x03\x12\x04\x91\x02\x1d\x1e\n\r\n\x05\x04\n\x02\x02\x08\x12\x04\ + \x91\x02\x1fG\n\x10\n\x08\x04\n\x02\x02\x08\xaf\x08\x0e\x12\x04\x91\x02\ + \x20F\n\x0c\n\x02\x04\x0b\x12\x06\x94\x02\0\xaa\x02\x01\n\x0b\n\x03\x04\ + \x0b\x01\x12\x04\x94\x02\x08#\nq\n\x04\x04\x0b\x02\0\x12\x04\x96\x02\x02\ + B\x1ac\x20The\x20UUID\x20of\x20the\x20intent\x20being\x20negotiated.\x20\ + This\x20is\x20used\x20to\x20correlate\x20the\x20response\x20with\x20the\ + \x20request.\n\n\r\n\x05\x04\x0b\x02\0\x05\x12\x04\x96\x02\x02\x08\n\r\n\ + \x05\x04\x0b\x02\0\x01\x12\x04\x96\x02\t\x14\n\r\n\x05\x04\x0b\x02\0\x03\ + \x12\x04\x96\x02\x17\x18\n\r\n\x05\x04\x0b\x02\0\x08\x12\x04\x96\x02\x19\ + A\n\x10\n\x08\x04\x0b\x02\0\x08\xaf\x08\x0e\x12\x04\x96\x02\x1a@\nE\n\ + \x04\x04\x0b\x02\x01\x12\x04\x99\x02\x02>\x1a7\x20The\x20type\x20of\x20t\ + he\x20artifact\x20being\x20considered\x20for\x20upload.\n\n\r\n\x05\x04\ + \x0b\x02\x01\x05\x12\x04\x99\x02\x02\x08\n\r\n\x05\x04\x0b\x02\x01\x01\ + \x12\x04\x99\x02\t\x10\n\r\n\x05\x04\x0b\x02\x01\x03\x12\x04\x99\x02\x13\ + \x14\n\r\n\x05\x04\x0b\x02\x01\x08\x12\x04\x99\x02\x15=\n\x10\n\x08\x04\ + \x0b\x02\x01\x08\xaf\x08\x0e\x12\x04\x99\x02\x16<\n\x0b\n\x03\x04\x0b\t\ + \x12\x04\x9b\x02\x02\r\n\x0c\n\x04\x04\x0b\t\0\x12\x04\x9b\x02\x0b\x0c\n\ + \r\n\x05\x04\x0b\t\0\x01\x12\x04\x9b\x02\x0b\x0c\n\r\n\x05\x04\x0b\t\0\ + \x02\x12\x04\x9b\x02\x0b\x0c\n\xd5\x02\n\x04\x04\x0b\x02\x02\x12\x04\x9e\ + \x02\x02,\x1a\xc6\x02\x20The\x20metadata\x20associated\x20with\x20the\ + \x20artifact.\x20The\x20contents\x20within\x20this\x20map\x20depends\x20\ + on\x20the\x20type\x20of\x20the\x20artfact\x20but\x20will\x20generally\ + \x20contain\x20information\x20that\x20can\x20help\x20the\x20server\x20ma\ + ke\x20a\x20decision\x20about\x20whether\x20to\x20accept\x20the\x20upload\ + \x20or\x20not.\x20For\x20example,\x20for\x20issue\x20reports\x20this\x20\ + may\x20contain\x20the\x20\"fields\"\x20associated\x20with\x20the\x20issu\ + e\x20report.\n\n\r\n\x05\x04\x0b\x02\x02\x06\x12\x04\x9e\x02\x02\x1e\n\r\ + \n\x05\x04\x0b\x02\x02\x01\x12\x04\x9e\x02\x1f'\n\r\n\x05\x04\x0b\x02\ + \x02\x03\x12\x04\x9e\x02*+\n\x92\x01\n\x04\x04\x0b\x02\x03\x12\x04\xa2\ + \x02\x02B\x1a\x83\x01\x20A\x20client-generated\x20ID\x20that\x20uniquely\ + \x20identifies\x20the\x20artifact.\x20This\x20is\x20used\x20to\x20correl\ + ate\x20the\x20artifact\n\x20with\x20logs\x20that\x20reference\x20it.\n\n\ + \r\n\x05\x04\x0b\x02\x03\x05\x12\x04\xa2\x02\x02\x08\n\r\n\x05\x04\x0b\ + \x02\x03\x01\x12\x04\xa2\x02\t\x14\n\r\n\x05\x04\x0b\x02\x03\x03\x12\x04\ + \xa2\x02\x17\x18\n\r\n\x05\x04\x0b\x02\x03\x08\x12\x04\xa2\x02\x19A\n\ + \x10\n\x08\x04\x0b\x02\x03\x08\xaf\x08\x0e\x12\x04\xa2\x02\x1a@\n\x8f\ + \x01\n\x04\x04\x0b\x02\x04\x12\x04\xa5\x02\x02S\x1a\x80\x01\x20The\x20ti\ + mestamp\x20associated\x20with\x20the\x20artifact\x20being\x20uploaded.\ + \x20This\x20allows\x20us\x20to\x20possibly\x20reject\x20the\x20upload\ + \x20of\x20very\x20old\x20artifacts.\n\n\r\n\x05\x04\x0b\x02\x04\x06\x12\ + \x04\xa5\x02\x02\x1b\n\r\n\x05\x04\x0b\x02\x04\x01\x12\x04\xa5\x02\x1c\ + \x20\n\r\n\x05\x04\x0b\x02\x04\x03\x12\x04\xa5\x02#$\n\r\n\x05\x04\x0b\ + \x02\x04\x08\x12\x04\xa5\x02%R\n\x10\n\x08\x04\x0b\x02\x04\x08\xaf\x08\ + \x11\x12\x04\xa5\x02&Q\n\xc8\x01\n\x04\x04\x0b\x02\x05\x12\x04\xa9\x02\ + \x02!\x1a\xb9\x01\x20The\x20session\x20ID\x20associated\x20with\x20the\ + \x20artifact.\x20This\x20allows\x20correlating\x20the\x20intent\x20with\ + \x20a\x20specific\x20user\x20session.\n\x20This\x20may\x20not\x20be\x20s\ + et\x20for\x20all\x20kinds\x20of\x20artifacts,\x20such\x20as\x20state\x20\ + snapshots.\n\n\r\n\x05\x04\x0b\x02\x05\x04\x12\x04\xa9\x02\x02\n\n\r\n\ + \x05\x04\x0b\x02\x05\x05\x12\x04\xa9\x02\x0b\x11\n\r\n\x05\x04\x0b\x02\ + \x05\x01\x12\x04\xa9\x02\x12\x1c\n\r\n\x05\x04\x0b\x02\x05\x03\x12\x04\ + \xa9\x02\x1f\x20\n\x0c\n\x02\x04\x0c\x12\x06\xac\x02\0\xbb\x02\x01\n\x0b\ + \n\x03\x04\x0c\x01\x12\x04\xac\x02\x08$\nq\n\x04\x04\x0c\x02\0\x12\x04\ + \xae\x02\x02B\x1ac\x20The\x20UUID\x20of\x20the\x20intent\x20being\x20neg\ + otiated.\x20This\x20is\x20used\x20to\x20correlate\x20the\x20response\x20\ + with\x20the\x20request.\n\n\r\n\x05\x04\x0c\x02\0\x05\x12\x04\xae\x02\ + \x02\x08\n\r\n\x05\x04\x0c\x02\0\x01\x12\x04\xae\x02\t\x14\n\r\n\x05\x04\ + \x0c\x02\0\x03\x12\x04\xae\x02\x17\x18\n\r\n\x05\x04\x0c\x02\0\x08\x12\ + \x04\xae\x02\x19A\n\x10\n\x08\x04\x0c\x02\0\x08\xaf\x08\x0e\x12\x04\xae\ + \x02\x1a@\n\x0c\n\x04\x04\x0c\x03\0\x12\x04\xb0\x02\x02\x1e\n\r\n\x05\ + \x04\x0c\x03\0\x01\x12\x04\xb0\x02\n\x1b\n\x0c\n\x04\x04\x0c\x03\x01\x12\ + \x04\xb2\x02\x02\x11\n\r\n\x05\x04\x0c\x03\x01\x01\x12\x04\xb2\x02\n\x0e\ + \n\x0e\n\x04\x04\x0c\x08\0\x12\x06\xb4\x02\x02\xba\x02\x03\n\r\n\x05\x04\ + \x0c\x08\0\x01\x12\x04\xb4\x02\x08\x10\n<\n\x04\x04\x0c\x02\x01\x12\x04\ + \xb6\x02\x04-\x1a.\x20The\x20artifact\x20should\x20be\x20uploaded\x20imm\ + ediately.\n\n\r\n\x05\x04\x0c\x02\x01\x06\x12\x04\xb6\x02\x04\x15\n\r\n\ + \x05\x04\x0c\x02\x01\x01\x12\x04\xb6\x02\x16(\n\r\n\x05\x04\x0c\x02\x01\ + \x03\x12\x04\xb6\x02+,\n9\n\x04\x04\x0c\x02\x02\x12\x04\xb9\x02\x04\x12\ + \x1a+\x20The\x20candidate\x20artifact\x20should\x20be\x20dropped.\n\n\r\ + \n\x05\x04\x0c\x02\x02\x06\x12\x04\xb9\x02\x04\x08\n\r\n\x05\x04\x0c\x02\ + \x02\x01\x12\x04\xb9\x02\t\r\n\r\n\x05\x04\x0c\x02\x02\x03\x12\x04\xb9\ + \x02\x10\x11\n\x0c\n\x02\x04\r\x12\x06\xbd\x02\0\xd7\x02\x01\n\x0b\n\x03\ + \x04\r\x01\x12\x04\xbd\x02\x08\x1d\nf\n\x04\x04\r\x02\0\x12\x04\xbf\x02\ + \x02B\x1aX\x20Upload\x20UUID\x20used\x20to\x20provide\x20idempotence\x20\ + and\x20to\x20correlate\x20a\x20response\x20with\x20this\x20request.\n\n\ + \r\n\x05\x04\r\x02\0\x05\x12\x04\xbf\x02\x02\x08\n\r\n\x05\x04\r\x02\0\ + \x01\x12\x04\xbf\x02\t\x14\n\r\n\x05\x04\r\x02\0\x03\x12\x04\xbf\x02\x17\ + \x18\n\r\n\x05\x04\r\x02\0\x08\x12\x04\xbf\x02\x19A\n\x10\n\x08\x04\r\ + \x02\0\x08\xaf\x08\x0e\x12\x04\xbf\x02\x1a@\n8\n\x04\x04\r\x02\x01\x12\ + \x04\xc2\x02\x02>\x1a*\x20The\x20type\x20of\x20the\x20artifact\x20being\ + \x20uploaded.\n\n\r\n\x05\x04\r\x02\x01\x05\x12\x04\xc2\x02\x02\x08\n\r\ + \n\x05\x04\r\x02\x01\x01\x12\x04\xc2\x02\t\x10\n\r\n\x05\x04\r\x02\x01\ + \x03\x12\x04\xc2\x02\x13\x14\n\r\n\x05\x04\r\x02\x01\x08\x12\x04\xc2\x02\ + \x15=\n\x10\n\x08\x04\r\x02\x01\x08\xaf\x08\x0e\x12\x04\xc2\x02\x16<\nu\ + \n\x04\x04\r\x02\x02\x12\x04\xc5\x02\x02\x15\x1ag\x20The\x20artifact\x20\ to\x20upload.\x20This\x20is\x20a\x20binary\x20blob\x20that\x20is\x20inte\ rpreted\x20by\x20the\x20server\x20based\x20on\x20the\x20type_id.\n\n\r\n\ - \x05\x04\x0c\x02\x02\x05\x12\x04\xad\x02\x02\x07\n\r\n\x05\x04\x0c\x02\ - \x02\x01\x12\x04\xad\x02\x08\x10\n\r\n\x05\x04\x0c\x02\x02\x03\x12\x04\ - \xad\x02\x13\x14\n\xa1\x01\n\x04\x04\x0c\x02\x03\x12\x04\xb1\x02\x02B\ - \x1a\x92\x01\x20A\x20client-generated\x20ID\x20that\x20uniquely\x20ident\ - ifies\x20the\x20artifact\x20being\x20uploaded.\x20This\x20is\x20used\x20\ - to\x20correlate\n\x20the\x20artifact\x20with\x20logs\x20that\x20referenc\ - e\x20it.\n\n\r\n\x05\x04\x0c\x02\x03\x05\x12\x04\xb1\x02\x02\x08\n\r\n\ - \x05\x04\x0c\x02\x03\x01\x12\x04\xb1\x02\t\x14\n\r\n\x05\x04\x0c\x02\x03\ - \x03\x12\x04\xb1\x02\x17\x18\n\r\n\x05\x04\x0c\x02\x03\x08\x12\x04\xb1\ - \x02\x19A\n\x10\n\x08\x04\x0c\x02\x03\x08\xaf\x08\x0e\x12\x04\xb1\x02\ - \x1a@\n\xcb\x01\n\x04\x04\x0c\x02\x04\x12\x04\xb5\x02\x022\x1a\xbc\x01\ - \x20An\x20optional\x20set\x20of\x20key-value\x20data\x20indicating\x20th\ - e\x20state\x20of\x20the\x20device\x20at\x20the\x20time\x20of\x20artifact\ - \x20emission.\x20For\x20example,\n\x20this\x20may\x20capture\x20informat\ - ion\x20about\x20the\x20device\x20at\x20the\x20time\x20of\x20a\x20crash.\ - \n\n\r\n\x05\x04\x0c\x02\x04\x06\x12\x04\xb5\x02\x02\x1e\n\r\n\x05\x04\ - \x0c\x02\x04\x01\x12\x04\xb5\x02\x1f-\n\r\n\x05\x04\x0c\x02\x04\x03\x12\ - \x04\xb5\x0201\n~\n\x04\x04\x0c\x02\x05\x12\x04\xb8\x02\x02S\x1ap\x20The\ - \x20timestamp\x20associated\x20with\x20this\x20upload.\x20This\x20allows\ - \x20us\x20to\x20possibly\x20reject\x20the\x20upload\x20of\x20very\x20old\ - \x20artifacts.\n\n\r\n\x05\x04\x0c\x02\x05\x06\x12\x04\xb8\x02\x02\x1b\n\ - \r\n\x05\x04\x0c\x02\x05\x01\x12\x04\xb8\x02\x1c\x20\n\r\n\x05\x04\x0c\ - \x02\x05\x03\x12\x04\xb8\x02#$\n\r\n\x05\x04\x0c\x02\x05\x08\x12\x04\xb8\ - \x02%R\n\x10\n\x08\x04\x0c\x02\x05\x08\xaf\x08\x11\x12\x04\xb8\x02&Q\nJ\ - \n\x04\x04\x0c\x02\x06\x12\x04\xbb\x02\x02\x18\x1a<\x20The\x20session\ - \x20ID\x20associated\x20with\x20the\x20artifact\x20if\x20applicable.\n\n\ - \r\n\x05\x04\x0c\x02\x06\x05\x12\x04\xbb\x02\x02\x08\n\r\n\x05\x04\x0c\ - \x02\x06\x01\x12\x04\xbb\x02\t\x13\n\r\n\x05\x04\x0c\x02\x06\x03\x12\x04\ - \xbb\x02\x16\x17\n[\n\x04\x04\x0c\x02\x07\x12\x04\xbe\x02\x02)\x1aM\x20T\ - he\x20set\x20of\x20feature\x20flags\x20that\x20were\x20active\x20at\x20t\ - he\x20time\x20of\x20artifact\x20emission.\n\n\r\n\x05\x04\x0c\x02\x07\ - \x04\x12\x04\xbe\x02\x02\n\n\r\n\x05\x04\x0c\x02\x07\x06\x12\x04\xbe\x02\ - \x0b\x16\n\r\n\x05\x04\x0c\x02\x07\x01\x12\x04\xbe\x02\x17$\n\r\n\x05\ - \x04\x0c\x02\x07\x03\x12\x04\xbe\x02'(\n\x0c\n\x02\x04\r\x12\x06\xc1\x02\ - \0\xc7\x02\x01\n\x0b\n\x03\x04\r\x01\x12\x04\xc1\x02\x08\x1e\n=\n\x04\ - \x04\r\x02\0\x12\x04\xc3\x02\x02B\x1a/\x20The\x20UUID\x20corresponding\ - \x20to\x20the\x20upload\x20request.\n\n\r\n\x05\x04\r\x02\0\x05\x12\x04\ - \xc3\x02\x02\x08\n\r\n\x05\x04\r\x02\0\x01\x12\x04\xc3\x02\t\x14\n\r\n\ - \x05\x04\r\x02\0\x03\x12\x04\xc3\x02\x17\x18\n\r\n\x05\x04\r\x02\0\x08\ - \x12\x04\xc3\x02\x19A\n\x10\n\x08\x04\r\x02\0\x08\xaf\x08\x0e\x12\x04\ - \xc3\x02\x1a@\nS\n\x04\x04\r\x02\x01\x12\x04\xc6\x02\x02\x13\x1aE\x20Opt\ - ional\x20error\x20message\x20which\x20indicates\x20that\x20artifact\x20u\ - pload\x20failed.\n\n\r\n\x05\x04\r\x02\x01\x05\x12\x04\xc6\x02\x02\x08\n\ - \r\n\x05\x04\r\x02\x01\x01\x12\x04\xc6\x02\t\x0e\n\r\n\x05\x04\r\x02\x01\ - \x03\x12\x04\xc6\x02\x11\x12\nB\n\x02\x04\x0e\x12\x06\xca\x02\0\xdf\x02\ - \x01\x1a4\x20The\x20response\x20sent\x20as\x20part\x20of\x20stream\x20es\ - tablishment.\n\n\x0b\n\x03\x04\x0e\x01\x12\x04\xca\x02\x08\x19\n\x0e\n\ - \x04\x04\x0e\x03\0\x12\x06\xcb\x02\x02\xd1\x02\x03\n\r\n\x05\x04\x0e\x03\ - \0\x01\x12\x04\xcb\x02\n\x18\n\xe2\x01\n\x06\x04\x0e\x03\0\x02\0\x12\x04\ - \xd0\x02\x04/\x1a\xd1\x01\x20How\x20often\x20the\x20client\x20should\x20\ - ping\x20the\x20server.\x20This\x20informs\x20the\x20client\x20how\n\x20o\ - ften\x20a\x20ping\x20request\x20should\x20be\x20issued\x20over\x20the\ - \x20newly\x20created\x20stream.\n\n\x20If\x20this\x20is\x20not\x20set,\ - \x20the\x20client\x20should\x20not\x20issue\x20ping\x20requests.\n\n\x0f\ - \n\x07\x04\x0e\x03\0\x02\0\x06\x12\x04\xd0\x02\x04\x1c\n\x0f\n\x07\x04\ - \x0e\x03\0\x02\0\x01\x12\x04\xd0\x02\x1d*\n\x0f\n\x07\x04\x0e\x03\0\x02\ - \0\x03\x12\x04\xd0\x02-.\n\x0c\n\x04\x04\x0e\x02\0\x12\x04\xd3\x02\x02%\ - \n\r\n\x05\x04\x0e\x02\0\x06\x12\x04\xd3\x02\x02\x10\n\r\n\x05\x04\x0e\ - \x02\0\x01\x12\x04\xd3\x02\x11\x20\n\r\n\x05\x04\x0e\x02\0\x03\x12\x04\ - \xd3\x02#$\n\x99\x02\n\x04\x04\x0e\x02\x01\x12\x04\xd9\x02\x02)\x1a\x8a\ - \x02\x20A\x20flag\x20set\x20that\x20describes\x20the\x20status\x20of\x20\ - configuration\x20updates\x20based\x20on\x20the\x20provided\n\x20configur\ - ation\x20nonces.\n\x200x1:\x20Runtime\x20is\x20up\x20to\x20date\x20and\ - \x20no\x20further\x20update\x20message\x20will\x20be\x20supplied.\n\x200\ - x2:\x20Configuration\x20is\x20up\x20to\x20date\x20and\x20no\x20further\ - \x20update\x20message\x20will\x20be\x20supplied.\n\n\r\n\x05\x04\x0e\x02\ - \x01\x05\x12\x04\xd9\x02\x02\x08\n\r\n\x05\x04\x0e\x02\x01\x01\x12\x04\ - \xd9\x02\t$\n\r\n\x05\x04\x0e\x02\x01\x03\x12\x04\xd9\x02'(\n\x91\x02\n\ - \x04\x04\x0e\x02\x02\x12\x04\xde\x02\x021\x1a\x82\x02\x20Opaque\x20clien\ - t\x20state\x20that\x20should\x20be\x20echoed\x20back\x20to\x20the\x20ser\ - ver\x20on\x20every\x20future\x20handshake\n\x20request.\x20If\x20unset,\ - \x20the\x20client\x20should\x20continue\x20to\x20send\x20any\x20existing\ - \x20opaque\x20state,\x20or\x20none\n\x20if\x20it\x20has\x20none.\x20Send\ - ing\x20an\x20explicit\x20empty\x20value\x20will\x20clear\x20any\x20exist\ - ing\x20state.\n\n\r\n\x05\x04\x0e\x02\x02\x04\x12\x04\xde\x02\x02\n\n\r\ - \n\x05\x04\x0e\x02\x02\x05\x12\x04\xde\x02\x0b\x10\n\r\n\x05\x04\x0e\x02\ - \x02\x01\x12\x04\xde\x02\x11,\n\r\n\x05\x04\x0e\x02\x02\x03\x12\x04\xde\ - \x02/0\nL\n\x02\x04\x0f\x12\x06\xe2\x02\0\xe5\x02\x01\x1a>\x20A\x20gener\ - al\x20indication\x20of\x20rate\x20limiting\x20from\x20server\x20to\x20cl\ - ient.\n\n\x0b\n\x03\x04\x0f\x01\x12\x04\xe2\x02\x08\x13\nY\n\x04\x04\x0f\ - \x02\0\x12\x04\xe4\x02\x02+\x1aK\x20Optional\x20minimum\x20retry\x20back\ - off\x20duration\x20that\x20the\x20client\x20should\x20adhere\x20to.\n\n\ - \r\n\x05\x04\x0f\x02\0\x06\x12\x04\xe4\x02\x02\x1a\n\r\n\x05\x04\x0f\x02\ - \0\x01\x12\x04\xe4\x02\x1b&\n\r\n\x05\x04\x0f\x02\0\x03\x12\x04\xe4\x02)\ - *\n\xa1\x01\n\x02\x04\x10\x12\x06\xe9\x02\0\xfa\x02\x01\x1a\x92\x01\x20A\ - \x20response\x20to\x20an\x20upload\x20request,\x20intended\x20to\x20ack\ - \x20or\x20nack\x20the\x20success\x20of\x20the\n\x20upload.\x20Upon\x20fa\ - ilure,\x20the\x20client\x20might\x20choose\x20to\x20retry\x20this\x20upl\ - oad.\n\n\x0b\n\x03\x04\x10\x01\x12\x04\xe9\x02\x08\x19\n_\n\x04\x04\x10\ - \x02\0\x12\x04\xec\x02\x02B\x1aQ\x20The\x20upload\x20UUID\x20provided\ - \x20in\x20the\x20upload\x20request\x20corresponding\x20to\x20this\n\x20r\ - esponse.\n\n\r\n\x05\x04\x10\x02\0\x05\x12\x04\xec\x02\x02\x08\n\r\n\x05\ - \x04\x10\x02\0\x01\x12\x04\xec\x02\t\x14\n\r\n\x05\x04\x10\x02\0\x03\x12\ - \x04\xec\x02\x17\x18\n\r\n\x05\x04\x10\x02\0\x08\x12\x04\xec\x02\x19A\n\ - \x10\n\x08\x04\x10\x02\0\x08\xaf\x08\x0e\x12\x04\xec\x02\x1a@\n}\n\x04\ - \x04\x10\x02\x01\x12\x04\xf0\x02\x02\x13\x1ao\x20If\x20set,\x20indicates\ - \x20that\x20the\x20log\x20upload\x20failed.\x20This\x20will\x20be\x20set\ - \x20to\x20a\x20value\n\x20helpful\x20for\x20debugging\x20the\x20failure.\ - \n\n\r\n\x05\x04\x10\x02\x01\x05\x12\x04\xf0\x02\x02\x08\n\r\n\x05\x04\ - \x10\x02\x01\x01\x12\x04\xf0\x02\t\x0e\n\r\n\x05\x04\x10\x02\x01\x03\x12\ - \x04\xf0\x02\x11\x12\n\xe7\x01\n\x04\x04\x10\x02\x02\x12\x04\xf5\x02\x02\ - \x1a\x1a\xd8\x01\x20If\x20any\x20logs\x20were\x20dropped\x20due\x20to\ - \x20validation\x20errors,\x20the\x20count\x20will\x20be\x20supplied\x20h\ - ere.\x20This\x20does\n\x20not\x20count\x20as\x20a\x20total\x20failure\ - \x20and\x20'error'\x20will\x20not\x20be\x20populated.\x20Debugging\x20in\ - formation\x20will\x20be\n\x20available\x20on\x20the\x20server.\n\n\r\n\ - \x05\x04\x10\x02\x02\x05\x12\x04\xf5\x02\x02\x08\n\r\n\x05\x04\x10\x02\ - \x02\x01\x12\x04\xf5\x02\t\x15\n\r\n\x05\x04\x10\x02\x02\x03\x12\x04\xf5\ - \x02\x18\x19\n\x7f\n\x04\x04\x10\x02\x03\x12\x04\xf9\x02\x02\x1f\x1aq\ - \x20If\x20set\x20the\x20log\x20upload\x20was\x20blocked\x20due\x20to\x20\ - rate\x20limiting.\x20Further\x20information\x20is\x20available\x20in\n\ - \x20the\x20`error`\x20field.\n\n\r\n\x05\x04\x10\x02\x03\x06\x12\x04\xf9\ - \x02\x02\r\n\r\n\x05\x04\x10\x02\x03\x01\x12\x04\xf9\x02\x0e\x1a\n\r\n\ - \x05\x04\x10\x02\x03\x03\x12\x04\xf9\x02\x1d\x1e\n\x0c\n\x02\x04\x11\x12\ - \x06\xfc\x02\0\xb9\x03\x01\n\x0b\n\x03\x04\x11\x01\x12\x04\xfc\x02\x08\ - \x1a\n\x0e\n\x04\x04\x11\x04\0\x12\x06\xfd\x02\x02\x86\x03\x03\n\r\n\x05\ - \x04\x11\x04\0\x01\x12\x04\xfd\x02\x07\x13\n4\n\x06\x04\x11\x04\0\x02\0\ - \x12\x04\xff\x02\x04\"\x1a$\x20Default\x20value.\x20Should\x20not\x20be\ - \x20used.\n\n\x0f\n\x07\x04\x11\x04\0\x02\0\x01\x12\x04\xff\x02\x04\x1d\ - \n\x0f\n\x07\x04\x11\x04\0\x02\0\x02\x12\x04\xff\x02\x20!\n+\n\x06\x04\ - \x11\x04\0\x02\x01\x12\x04\x82\x03\x04\x1f\x1a\x1b\x20Periodic\x20upload\ - \x20of\x20stats.\n\n\x0f\n\x07\x04\x11\x04\0\x02\x01\x01\x12\x04\x82\x03\ - \x04\x1a\n\x0f\n\x07\x04\x11\x04\0\x02\x01\x02\x12\x04\x82\x03\x1d\x1e\n\ - K\n\x06\x04\x11\x04\0\x02\x02\x12\x04\x85\x03\x04&\x1a;\x20Upload\x20tri\ - ggered\x20by\x20a\x20specific\x20event,\x20e.g.,\x20buffer\x20flush.\n\n\ - \x0f\n\x07\x04\x11\x04\0\x02\x02\x01\x12\x04\x85\x03\x04!\n\x0f\n\x07\ - \x04\x11\x04\0\x02\x02\x02\x12\x04\x85\x03$%\nf\n\x04\x04\x11\x02\0\x12\ - \x04\x89\x03\x02B\x1aX\x20Upload\x20UUID\x20used\x20to\x20provide\x20ide\ - mpotence\x20and\x20to\x20correlate\x20a\x20response\x20with\x20this\x20r\ - equest.\n\n\r\n\x05\x04\x11\x02\0\x05\x12\x04\x89\x03\x02\x08\n\r\n\x05\ - \x04\x11\x02\0\x01\x12\x04\x89\x03\t\x14\n\r\n\x05\x04\x11\x02\0\x03\x12\ - \x04\x89\x03\x17\x18\n\r\n\x05\x04\x11\x02\0\x08\x12\x04\x89\x03\x19A\n\ - \x10\n\x08\x04\x11\x02\0\x08\xaf\x08\x0e\x12\x04\x89\x03\x1a@\n\x0e\n\ - \x04\x04\x11\x03\0\x12\x06\x8b\x03\x02\xac\x03\x03\n\r\n\x05\x04\x11\x03\ - \0\x01\x12\x04\x8b\x03\n\x12\n\x10\n\x06\x04\x11\x03\0\x08\0\x12\x06\x8c\ - \x03\x04\x90\x03\x05\n\x0f\n\x07\x04\x11\x03\0\x08\0\x01\x12\x04\x8c\x03\ - \n\x17\n\x0f\n\x07\x04\x11\x03\0\x08\0\x02\x12\x04\x8d\x03\x06(\n\x11\n\ - \t\x04\x11\x03\0\x08\0\x02\xaf\x08\x12\x04\x8d\x03\x06(\n\x0e\n\x06\x04\ - \x11\x03\0\x02\0\x12\x04\x8f\x03\x06\x1e\n\x0f\n\x07\x04\x11\x03\0\x02\0\ - \x06\x12\x04\x8f\x03\x06\x11\n\x0f\n\x07\x04\x11\x03\0\x02\0\x01\x12\x04\ - \x8f\x03\x12\x19\n\x0f\n\x07\x04\x11\x03\0\x02\0\x03\x12\x04\x8f\x03\x1c\ - \x1d\n\x10\n\x06\x04\x11\x03\0\x03\0\x12\x06\x92\x03\x04\x9a\x03\x05\n\ - \x0f\n\x07\x04\x11\x03\0\x03\0\x01\x12\x04\x92\x03\x0c\x16\n\xc6\x01\n\ - \x08\x04\x11\x03\0\x03\0\x02\0\x12\x04\x95\x03\x06_\x1a\xb3\x01\x20The\ - \x20point\x20in\x20time\x20where\x20the\x20first\x20set\x20of\x20stats\ - \x20in\x20this\x20aggregation\x20period\x20was\x20aggregated.\n\x20This\ - \x20allows\x20the\x20server\x20to\x20get\x20some\x20understanding\x20how\ - \x20old\x20the\x20stats\x20being\x20uploaded\x20are.\n\n\x11\n\t\x04\x11\ - \x03\0\x03\0\x02\0\x06\x12\x04\x95\x03\x06\x1f\n\x11\n\t\x04\x11\x03\0\ - \x03\0\x02\0\x01\x12\x04\x95\x03\x20,\n\x11\n\t\x04\x11\x03\0\x03\0\x02\ - \0\x03\x12\x04\x95\x03/0\n\x11\n\t\x04\x11\x03\0\x03\0\x02\0\x08\x12\x04\ - \x95\x031^\n\x14\n\x0c\x04\x11\x03\0\x03\0\x02\0\x08\xaf\x08\x11\x12\x04\ - \x95\x032]\n\xc5\x01\n\x08\x04\x11\x03\0\x03\0\x02\x01\x12\x04\x99\x03\ - \x06/\x1a\xb2\x01\x20When\x20the\x20aggregation\x20was\x20closed.\x20If\ - \x20specified,\x20the\x20server\x20can\x20decide\x20to\x20handle\x20vari\ - able\n\x20size\x20aggregation\x20windows\x20by\x20averaging\x20the\x20da\ - ta\x20over\x20the\x20period\x20or\x20some\x20other\x20heuristic.\n\n\x11\ - \n\t\x04\x11\x03\0\x03\0\x02\x01\x06\x12\x04\x99\x03\x06\x1f\n\x11\n\t\ - \x04\x11\x03\0\x03\0\x02\x01\x01\x12\x04\x99\x03\x20*\n\x11\n\t\x04\x11\ - \x03\0\x03\0\x02\x01\x03\x12\x04\x99\x03-.\n\x81\x01\n\x06\x04\x11\x03\0\ - \x08\x01\x12\x06\x9e\x03\x04\xa5\x03\x05\x1ao\x20To\x20support\x20differ\ - ent\x20kinds\x20of\x20snapshots,\x20we\x20support\x20providing\x20inform\ - ation\x20about\x20when\x20the\x20data\x20was\n\x20collected.\n\n\x0f\n\ - \x07\x04\x11\x03\0\x08\x01\x01\x12\x04\x9e\x03\n\x15\n\x0f\n\x07\x04\x11\ - \x03\0\x08\x01\x02\x12\x04\x9f\x03\x06(\n\x11\n\t\x04\x11\x03\0\x08\x01\ - \x02\xaf\x08\x12\x04\x9f\x03\x06(\n\xd4\x01\n\x06\x04\x11\x03\0\x02\x01\ - \x12\x04\xa4\x03\x06\x20\x1a\xc3\x01\x20The\x20snapshot\x20data\x20is\ - \x20aggregated\x20over\x20an\x20indefinite\x20period.\x20This\x20support\ - s\x20metrics\x20where\x20we\n\x20care\x20more\x20about\x20the\x20total\ - \x20data\x20(e.g.\x20counts)\x20than\x20understanding\x20precisely\x20wh\ - en\x20the\x20data\x20was\n\x20recorded.\n\n\x0f\n\x07\x04\x11\x03\0\x02\ - \x01\x06\x12\x04\xa4\x03\x06\x10\n\x0f\n\x07\x04\x11\x03\0\x02\x01\x01\ - \x12\x04\xa4\x03\x11\x1b\n\x0f\n\x07\x04\x11\x03\0\x02\x01\x03\x12\x04\ - \xa4\x03\x1e\x1f\nn\n\x06\x04\x11\x03\0\x02\x02\x12\x04\xa8\x03\x040\x1a\ - ^\x20A\x20map\x20of\x20metric\x20ID\x20to\x20any\x20cardinality\x20overf\ - lows\x20that\x20occurred\x20during\x20this\x20snapshot\x20interval.\n\n\ - \x0f\n\x07\x04\x11\x03\0\x02\x02\x06\x12\x04\xa8\x03\x04\x17\n\x0f\n\x07\ - \x04\x11\x03\0\x02\x02\x01\x12\x04\xa8\x03\x18+\n\x0f\n\x07\x04\x11\x03\ - \0\x02\x02\x03\x12\x04\xa8\x03./\nX\n\x06\x04\x11\x03\0\x02\x03\x12\x04\ - \xab\x03\x04L\x1aH\x20Workflow\x20ID\x20to\x20debug\x20data\x20that\x20o\ - ccurred\x20during\x20this\x20snapshot\x20interval.\n\n\x0f\n\x07\x04\x11\ - \x03\0\x02\x03\x06\x12\x04\xab\x03\x043\n\x0f\n\x07\x04\x11\x03\0\x02\ - \x03\x01\x12\x04\xab\x034G\n\x0f\n\x07\x04\x11\x03\0\x02\x03\x03\x12\x04\ - \xab\x03JK\nN\n\x04\x04\x11\x02\x01\x12\x04\xaf\x03\x02N\x1a@\x20A\x20co\ + \x05\x04\r\x02\x02\x05\x12\x04\xc5\x02\x02\x07\n\r\n\x05\x04\r\x02\x02\ + \x01\x12\x04\xc5\x02\x08\x10\n\r\n\x05\x04\r\x02\x02\x03\x12\x04\xc5\x02\ + \x13\x14\n\xa1\x01\n\x04\x04\r\x02\x03\x12\x04\xc9\x02\x02B\x1a\x92\x01\ + \x20A\x20client-generated\x20ID\x20that\x20uniquely\x20identifies\x20the\ + \x20artifact\x20being\x20uploaded.\x20This\x20is\x20used\x20to\x20correl\ + ate\n\x20the\x20artifact\x20with\x20logs\x20that\x20reference\x20it.\n\n\ + \r\n\x05\x04\r\x02\x03\x05\x12\x04\xc9\x02\x02\x08\n\r\n\x05\x04\r\x02\ + \x03\x01\x12\x04\xc9\x02\t\x14\n\r\n\x05\x04\r\x02\x03\x03\x12\x04\xc9\ + \x02\x17\x18\n\r\n\x05\x04\r\x02\x03\x08\x12\x04\xc9\x02\x19A\n\x10\n\ + \x08\x04\r\x02\x03\x08\xaf\x08\x0e\x12\x04\xc9\x02\x1a@\n\xcb\x01\n\x04\ + \x04\r\x02\x04\x12\x04\xcd\x02\x022\x1a\xbc\x01\x20An\x20optional\x20set\ + \x20of\x20key-value\x20data\x20indicating\x20the\x20state\x20of\x20the\ + \x20device\x20at\x20the\x20time\x20of\x20artifact\x20emission.\x20For\ + \x20example,\n\x20this\x20may\x20capture\x20information\x20about\x20the\ + \x20device\x20at\x20the\x20time\x20of\x20a\x20crash.\n\n\r\n\x05\x04\r\ + \x02\x04\x06\x12\x04\xcd\x02\x02\x1e\n\r\n\x05\x04\r\x02\x04\x01\x12\x04\ + \xcd\x02\x1f-\n\r\n\x05\x04\r\x02\x04\x03\x12\x04\xcd\x0201\n~\n\x04\x04\ + \r\x02\x05\x12\x04\xd0\x02\x02S\x1ap\x20The\x20timestamp\x20associated\ + \x20with\x20this\x20upload.\x20This\x20allows\x20us\x20to\x20possibly\ + \x20reject\x20the\x20upload\x20of\x20very\x20old\x20artifacts.\n\n\r\n\ + \x05\x04\r\x02\x05\x06\x12\x04\xd0\x02\x02\x1b\n\r\n\x05\x04\r\x02\x05\ + \x01\x12\x04\xd0\x02\x1c\x20\n\r\n\x05\x04\r\x02\x05\x03\x12\x04\xd0\x02\ + #$\n\r\n\x05\x04\r\x02\x05\x08\x12\x04\xd0\x02%R\n\x10\n\x08\x04\r\x02\ + \x05\x08\xaf\x08\x11\x12\x04\xd0\x02&Q\nJ\n\x04\x04\r\x02\x06\x12\x04\ + \xd3\x02\x02\x18\x1a<\x20The\x20session\x20ID\x20associated\x20with\x20t\ + he\x20artifact\x20if\x20applicable.\n\n\r\n\x05\x04\r\x02\x06\x05\x12\ + \x04\xd3\x02\x02\x08\n\r\n\x05\x04\r\x02\x06\x01\x12\x04\xd3\x02\t\x13\n\ + \r\n\x05\x04\r\x02\x06\x03\x12\x04\xd3\x02\x16\x17\n[\n\x04\x04\r\x02\ + \x07\x12\x04\xd6\x02\x02)\x1aM\x20The\x20set\x20of\x20feature\x20flags\ + \x20that\x20were\x20active\x20at\x20the\x20time\x20of\x20artifact\x20emi\ + ssion.\n\n\r\n\x05\x04\r\x02\x07\x04\x12\x04\xd6\x02\x02\n\n\r\n\x05\x04\ + \r\x02\x07\x06\x12\x04\xd6\x02\x0b\x16\n\r\n\x05\x04\r\x02\x07\x01\x12\ + \x04\xd6\x02\x17$\n\r\n\x05\x04\r\x02\x07\x03\x12\x04\xd6\x02'(\n\x0c\n\ + \x02\x04\x0e\x12\x06\xd9\x02\0\xdf\x02\x01\n\x0b\n\x03\x04\x0e\x01\x12\ + \x04\xd9\x02\x08\x1e\n=\n\x04\x04\x0e\x02\0\x12\x04\xdb\x02\x02B\x1a/\ + \x20The\x20UUID\x20corresponding\x20to\x20the\x20upload\x20request.\n\n\ + \r\n\x05\x04\x0e\x02\0\x05\x12\x04\xdb\x02\x02\x08\n\r\n\x05\x04\x0e\x02\ + \0\x01\x12\x04\xdb\x02\t\x14\n\r\n\x05\x04\x0e\x02\0\x03\x12\x04\xdb\x02\ + \x17\x18\n\r\n\x05\x04\x0e\x02\0\x08\x12\x04\xdb\x02\x19A\n\x10\n\x08\ + \x04\x0e\x02\0\x08\xaf\x08\x0e\x12\x04\xdb\x02\x1a@\nS\n\x04\x04\x0e\x02\ + \x01\x12\x04\xde\x02\x02\x13\x1aE\x20Optional\x20error\x20message\x20whi\ + ch\x20indicates\x20that\x20artifact\x20upload\x20failed.\n\n\r\n\x05\x04\ + \x0e\x02\x01\x05\x12\x04\xde\x02\x02\x08\n\r\n\x05\x04\x0e\x02\x01\x01\ + \x12\x04\xde\x02\t\x0e\n\r\n\x05\x04\x0e\x02\x01\x03\x12\x04\xde\x02\x11\ + \x12\nB\n\x02\x04\x0f\x12\x06\xe2\x02\0\xf7\x02\x01\x1a4\x20The\x20respo\ + nse\x20sent\x20as\x20part\x20of\x20stream\x20establishment.\n\n\x0b\n\ + \x03\x04\x0f\x01\x12\x04\xe2\x02\x08\x19\n\x0e\n\x04\x04\x0f\x03\0\x12\ + \x06\xe3\x02\x02\xe9\x02\x03\n\r\n\x05\x04\x0f\x03\0\x01\x12\x04\xe3\x02\ + \n\x18\n\xe2\x01\n\x06\x04\x0f\x03\0\x02\0\x12\x04\xe8\x02\x04/\x1a\xd1\ + \x01\x20How\x20often\x20the\x20client\x20should\x20ping\x20the\x20server\ + .\x20This\x20informs\x20the\x20client\x20how\n\x20often\x20a\x20ping\x20\ + request\x20should\x20be\x20issued\x20over\x20the\x20newly\x20created\x20\ + stream.\n\n\x20If\x20this\x20is\x20not\x20set,\x20the\x20client\x20shoul\ + d\x20not\x20issue\x20ping\x20requests.\n\n\x0f\n\x07\x04\x0f\x03\0\x02\0\ + \x06\x12\x04\xe8\x02\x04\x1c\n\x0f\n\x07\x04\x0f\x03\0\x02\0\x01\x12\x04\ + \xe8\x02\x1d*\n\x0f\n\x07\x04\x0f\x03\0\x02\0\x03\x12\x04\xe8\x02-.\n\ + \x0c\n\x04\x04\x0f\x02\0\x12\x04\xeb\x02\x02%\n\r\n\x05\x04\x0f\x02\0\ + \x06\x12\x04\xeb\x02\x02\x10\n\r\n\x05\x04\x0f\x02\0\x01\x12\x04\xeb\x02\ + \x11\x20\n\r\n\x05\x04\x0f\x02\0\x03\x12\x04\xeb\x02#$\n\x99\x02\n\x04\ + \x04\x0f\x02\x01\x12\x04\xf1\x02\x02)\x1a\x8a\x02\x20A\x20flag\x20set\ + \x20that\x20describes\x20the\x20status\x20of\x20configuration\x20updates\ + \x20based\x20on\x20the\x20provided\n\x20configuration\x20nonces.\n\x200x\ + 1:\x20Runtime\x20is\x20up\x20to\x20date\x20and\x20no\x20further\x20updat\ + e\x20message\x20will\x20be\x20supplied.\n\x200x2:\x20Configuration\x20is\ + \x20up\x20to\x20date\x20and\x20no\x20further\x20update\x20message\x20wil\ + l\x20be\x20supplied.\n\n\r\n\x05\x04\x0f\x02\x01\x05\x12\x04\xf1\x02\x02\ + \x08\n\r\n\x05\x04\x0f\x02\x01\x01\x12\x04\xf1\x02\t$\n\r\n\x05\x04\x0f\ + \x02\x01\x03\x12\x04\xf1\x02'(\n\x91\x02\n\x04\x04\x0f\x02\x02\x12\x04\ + \xf6\x02\x021\x1a\x82\x02\x20Opaque\x20client\x20state\x20that\x20should\ + \x20be\x20echoed\x20back\x20to\x20the\x20server\x20on\x20every\x20future\ + \x20handshake\n\x20request.\x20If\x20unset,\x20the\x20client\x20should\ + \x20continue\x20to\x20send\x20any\x20existing\x20opaque\x20state,\x20or\ + \x20none\n\x20if\x20it\x20has\x20none.\x20Sending\x20an\x20explicit\x20e\ + mpty\x20value\x20will\x20clear\x20any\x20existing\x20state.\n\n\r\n\x05\ + \x04\x0f\x02\x02\x04\x12\x04\xf6\x02\x02\n\n\r\n\x05\x04\x0f\x02\x02\x05\ + \x12\x04\xf6\x02\x0b\x10\n\r\n\x05\x04\x0f\x02\x02\x01\x12\x04\xf6\x02\ + \x11,\n\r\n\x05\x04\x0f\x02\x02\x03\x12\x04\xf6\x02/0\nL\n\x02\x04\x10\ + \x12\x06\xfa\x02\0\xfd\x02\x01\x1a>\x20A\x20general\x20indication\x20of\ + \x20rate\x20limiting\x20from\x20server\x20to\x20client.\n\n\x0b\n\x03\ + \x04\x10\x01\x12\x04\xfa\x02\x08\x13\nY\n\x04\x04\x10\x02\0\x12\x04\xfc\ + \x02\x02+\x1aK\x20Optional\x20minimum\x20retry\x20backoff\x20duration\ + \x20that\x20the\x20client\x20should\x20adhere\x20to.\n\n\r\n\x05\x04\x10\ + \x02\0\x06\x12\x04\xfc\x02\x02\x1a\n\r\n\x05\x04\x10\x02\0\x01\x12\x04\ + \xfc\x02\x1b&\n\r\n\x05\x04\x10\x02\0\x03\x12\x04\xfc\x02)*\n\xa1\x01\n\ + \x02\x04\x11\x12\x06\x81\x03\0\x92\x03\x01\x1a\x92\x01\x20A\x20response\ + \x20to\x20an\x20upload\x20request,\x20intended\x20to\x20ack\x20or\x20nac\ + k\x20the\x20success\x20of\x20the\n\x20upload.\x20Upon\x20failure,\x20the\ + \x20client\x20might\x20choose\x20to\x20retry\x20this\x20upload.\n\n\x0b\ + \n\x03\x04\x11\x01\x12\x04\x81\x03\x08\x19\n_\n\x04\x04\x11\x02\0\x12\ + \x04\x84\x03\x02B\x1aQ\x20The\x20upload\x20UUID\x20provided\x20in\x20the\ + \x20upload\x20request\x20corresponding\x20to\x20this\n\x20response.\n\n\ + \r\n\x05\x04\x11\x02\0\x05\x12\x04\x84\x03\x02\x08\n\r\n\x05\x04\x11\x02\ + \0\x01\x12\x04\x84\x03\t\x14\n\r\n\x05\x04\x11\x02\0\x03\x12\x04\x84\x03\ + \x17\x18\n\r\n\x05\x04\x11\x02\0\x08\x12\x04\x84\x03\x19A\n\x10\n\x08\ + \x04\x11\x02\0\x08\xaf\x08\x0e\x12\x04\x84\x03\x1a@\n}\n\x04\x04\x11\x02\ + \x01\x12\x04\x88\x03\x02\x13\x1ao\x20If\x20set,\x20indicates\x20that\x20\ + the\x20log\x20upload\x20failed.\x20This\x20will\x20be\x20set\x20to\x20a\ + \x20value\n\x20helpful\x20for\x20debugging\x20the\x20failure.\n\n\r\n\ + \x05\x04\x11\x02\x01\x05\x12\x04\x88\x03\x02\x08\n\r\n\x05\x04\x11\x02\ + \x01\x01\x12\x04\x88\x03\t\x0e\n\r\n\x05\x04\x11\x02\x01\x03\x12\x04\x88\ + \x03\x11\x12\n\xe7\x01\n\x04\x04\x11\x02\x02\x12\x04\x8d\x03\x02\x1a\x1a\ + \xd8\x01\x20If\x20any\x20logs\x20were\x20dropped\x20due\x20to\x20validat\ + ion\x20errors,\x20the\x20count\x20will\x20be\x20supplied\x20here.\x20Thi\ + s\x20does\n\x20not\x20count\x20as\x20a\x20total\x20failure\x20and\x20'er\ + ror'\x20will\x20not\x20be\x20populated.\x20Debugging\x20information\x20w\ + ill\x20be\n\x20available\x20on\x20the\x20server.\n\n\r\n\x05\x04\x11\x02\ + \x02\x05\x12\x04\x8d\x03\x02\x08\n\r\n\x05\x04\x11\x02\x02\x01\x12\x04\ + \x8d\x03\t\x15\n\r\n\x05\x04\x11\x02\x02\x03\x12\x04\x8d\x03\x18\x19\n\ + \x7f\n\x04\x04\x11\x02\x03\x12\x04\x91\x03\x02\x1f\x1aq\x20If\x20set\x20\ + the\x20log\x20upload\x20was\x20blocked\x20due\x20to\x20rate\x20limiting.\ + \x20Further\x20information\x20is\x20available\x20in\n\x20the\x20`error`\ + \x20field.\n\n\r\n\x05\x04\x11\x02\x03\x06\x12\x04\x91\x03\x02\r\n\r\n\ + \x05\x04\x11\x02\x03\x01\x12\x04\x91\x03\x0e\x1a\n\r\n\x05\x04\x11\x02\ + \x03\x03\x12\x04\x91\x03\x1d\x1e\n\x0c\n\x02\x04\x12\x12\x06\x94\x03\0\ + \xd1\x03\x01\n\x0b\n\x03\x04\x12\x01\x12\x04\x94\x03\x08\x1a\n\x0e\n\x04\ + \x04\x12\x04\0\x12\x06\x95\x03\x02\x9e\x03\x03\n\r\n\x05\x04\x12\x04\0\ + \x01\x12\x04\x95\x03\x07\x13\n4\n\x06\x04\x12\x04\0\x02\0\x12\x04\x97\ + \x03\x04\"\x1a$\x20Default\x20value.\x20Should\x20not\x20be\x20used.\n\n\ + \x0f\n\x07\x04\x12\x04\0\x02\0\x01\x12\x04\x97\x03\x04\x1d\n\x0f\n\x07\ + \x04\x12\x04\0\x02\0\x02\x12\x04\x97\x03\x20!\n+\n\x06\x04\x12\x04\0\x02\ + \x01\x12\x04\x9a\x03\x04\x1f\x1a\x1b\x20Periodic\x20upload\x20of\x20stat\ + s.\n\n\x0f\n\x07\x04\x12\x04\0\x02\x01\x01\x12\x04\x9a\x03\x04\x1a\n\x0f\ + \n\x07\x04\x12\x04\0\x02\x01\x02\x12\x04\x9a\x03\x1d\x1e\nK\n\x06\x04\ + \x12\x04\0\x02\x02\x12\x04\x9d\x03\x04&\x1a;\x20Upload\x20triggered\x20b\ + y\x20a\x20specific\x20event,\x20e.g.,\x20buffer\x20flush.\n\n\x0f\n\x07\ + \x04\x12\x04\0\x02\x02\x01\x12\x04\x9d\x03\x04!\n\x0f\n\x07\x04\x12\x04\ + \0\x02\x02\x02\x12\x04\x9d\x03$%\nf\n\x04\x04\x12\x02\0\x12\x04\xa1\x03\ + \x02B\x1aX\x20Upload\x20UUID\x20used\x20to\x20provide\x20idempotence\x20\ + and\x20to\x20correlate\x20a\x20response\x20with\x20this\x20request.\n\n\ + \r\n\x05\x04\x12\x02\0\x05\x12\x04\xa1\x03\x02\x08\n\r\n\x05\x04\x12\x02\ + \0\x01\x12\x04\xa1\x03\t\x14\n\r\n\x05\x04\x12\x02\0\x03\x12\x04\xa1\x03\ + \x17\x18\n\r\n\x05\x04\x12\x02\0\x08\x12\x04\xa1\x03\x19A\n\x10\n\x08\ + \x04\x12\x02\0\x08\xaf\x08\x0e\x12\x04\xa1\x03\x1a@\n\x0e\n\x04\x04\x12\ + \x03\0\x12\x06\xa3\x03\x02\xc4\x03\x03\n\r\n\x05\x04\x12\x03\0\x01\x12\ + \x04\xa3\x03\n\x12\n\x10\n\x06\x04\x12\x03\0\x08\0\x12\x06\xa4\x03\x04\ + \xa8\x03\x05\n\x0f\n\x07\x04\x12\x03\0\x08\0\x01\x12\x04\xa4\x03\n\x17\n\ + \x0f\n\x07\x04\x12\x03\0\x08\0\x02\x12\x04\xa5\x03\x06(\n\x11\n\t\x04\ + \x12\x03\0\x08\0\x02\xaf\x08\x12\x04\xa5\x03\x06(\n\x0e\n\x06\x04\x12\ + \x03\0\x02\0\x12\x04\xa7\x03\x06\x1e\n\x0f\n\x07\x04\x12\x03\0\x02\0\x06\ + \x12\x04\xa7\x03\x06\x11\n\x0f\n\x07\x04\x12\x03\0\x02\0\x01\x12\x04\xa7\ + \x03\x12\x19\n\x0f\n\x07\x04\x12\x03\0\x02\0\x03\x12\x04\xa7\x03\x1c\x1d\ + \n\x10\n\x06\x04\x12\x03\0\x03\0\x12\x06\xaa\x03\x04\xb2\x03\x05\n\x0f\n\ + \x07\x04\x12\x03\0\x03\0\x01\x12\x04\xaa\x03\x0c\x16\n\xc6\x01\n\x08\x04\ + \x12\x03\0\x03\0\x02\0\x12\x04\xad\x03\x06_\x1a\xb3\x01\x20The\x20point\ + \x20in\x20time\x20where\x20the\x20first\x20set\x20of\x20stats\x20in\x20t\ + his\x20aggregation\x20period\x20was\x20aggregated.\n\x20This\x20allows\ + \x20the\x20server\x20to\x20get\x20some\x20understanding\x20how\x20old\ + \x20the\x20stats\x20being\x20uploaded\x20are.\n\n\x11\n\t\x04\x12\x03\0\ + \x03\0\x02\0\x06\x12\x04\xad\x03\x06\x1f\n\x11\n\t\x04\x12\x03\0\x03\0\ + \x02\0\x01\x12\x04\xad\x03\x20,\n\x11\n\t\x04\x12\x03\0\x03\0\x02\0\x03\ + \x12\x04\xad\x03/0\n\x11\n\t\x04\x12\x03\0\x03\0\x02\0\x08\x12\x04\xad\ + \x031^\n\x14\n\x0c\x04\x12\x03\0\x03\0\x02\0\x08\xaf\x08\x11\x12\x04\xad\ + \x032]\n\xc5\x01\n\x08\x04\x12\x03\0\x03\0\x02\x01\x12\x04\xb1\x03\x06/\ + \x1a\xb2\x01\x20When\x20the\x20aggregation\x20was\x20closed.\x20If\x20sp\ + ecified,\x20the\x20server\x20can\x20decide\x20to\x20handle\x20variable\n\ + \x20size\x20aggregation\x20windows\x20by\x20averaging\x20the\x20data\x20\ + over\x20the\x20period\x20or\x20some\x20other\x20heuristic.\n\n\x11\n\t\ + \x04\x12\x03\0\x03\0\x02\x01\x06\x12\x04\xb1\x03\x06\x1f\n\x11\n\t\x04\ + \x12\x03\0\x03\0\x02\x01\x01\x12\x04\xb1\x03\x20*\n\x11\n\t\x04\x12\x03\ + \0\x03\0\x02\x01\x03\x12\x04\xb1\x03-.\n\x81\x01\n\x06\x04\x12\x03\0\x08\ + \x01\x12\x06\xb6\x03\x04\xbd\x03\x05\x1ao\x20To\x20support\x20different\ + \x20kinds\x20of\x20snapshots,\x20we\x20support\x20providing\x20informati\ + on\x20about\x20when\x20the\x20data\x20was\n\x20collected.\n\n\x0f\n\x07\ + \x04\x12\x03\0\x08\x01\x01\x12\x04\xb6\x03\n\x15\n\x0f\n\x07\x04\x12\x03\ + \0\x08\x01\x02\x12\x04\xb7\x03\x06(\n\x11\n\t\x04\x12\x03\0\x08\x01\x02\ + \xaf\x08\x12\x04\xb7\x03\x06(\n\xd4\x01\n\x06\x04\x12\x03\0\x02\x01\x12\ + \x04\xbc\x03\x06\x20\x1a\xc3\x01\x20The\x20snapshot\x20data\x20is\x20agg\ + regated\x20over\x20an\x20indefinite\x20period.\x20This\x20supports\x20me\ + trics\x20where\x20we\n\x20care\x20more\x20about\x20the\x20total\x20data\ + \x20(e.g.\x20counts)\x20than\x20understanding\x20precisely\x20when\x20th\ + e\x20data\x20was\n\x20recorded.\n\n\x0f\n\x07\x04\x12\x03\0\x02\x01\x06\ + \x12\x04\xbc\x03\x06\x10\n\x0f\n\x07\x04\x12\x03\0\x02\x01\x01\x12\x04\ + \xbc\x03\x11\x1b\n\x0f\n\x07\x04\x12\x03\0\x02\x01\x03\x12\x04\xbc\x03\ + \x1e\x1f\nn\n\x06\x04\x12\x03\0\x02\x02\x12\x04\xc0\x03\x040\x1a^\x20A\ + \x20map\x20of\x20metric\x20ID\x20to\x20any\x20cardinality\x20overflows\ + \x20that\x20occurred\x20during\x20this\x20snapshot\x20interval.\n\n\x0f\ + \n\x07\x04\x12\x03\0\x02\x02\x06\x12\x04\xc0\x03\x04\x17\n\x0f\n\x07\x04\ + \x12\x03\0\x02\x02\x01\x12\x04\xc0\x03\x18+\n\x0f\n\x07\x04\x12\x03\0\ + \x02\x02\x03\x12\x04\xc0\x03./\nX\n\x06\x04\x12\x03\0\x02\x03\x12\x04\ + \xc3\x03\x04L\x1aH\x20Workflow\x20ID\x20to\x20debug\x20data\x20that\x20o\ + ccurred\x20during\x20this\x20snapshot\x20interval.\n\n\x0f\n\x07\x04\x12\ + \x03\0\x02\x03\x06\x12\x04\xc3\x03\x043\n\x0f\n\x07\x04\x12\x03\0\x02\ + \x03\x01\x12\x04\xc3\x034G\n\x0f\n\x07\x04\x12\x03\0\x02\x03\x03\x12\x04\ + \xc3\x03JK\nN\n\x04\x04\x12\x02\x01\x12\x04\xc7\x03\x02N\x1a@\x20A\x20co\ llection\x20of\x20stats\x20snapshots\x20to\x20be\x20recorded\x20by\x20th\ - e\x20backend.\n\n\r\n\x05\x04\x11\x02\x01\x04\x12\x04\xaf\x03\x02\n\n\r\ - \n\x05\x04\x11\x02\x01\x06\x12\x04\xaf\x03\x0b\x13\n\r\n\x05\x04\x11\x02\ - \x01\x01\x12\x04\xaf\x03\x14\x1c\n\r\n\x05\x04\x11\x02\x01\x03\x12\x04\ - \xaf\x03\x1f\x20\n\r\n\x05\x04\x11\x02\x01\x08\x12\x04\xaf\x03!M\n\x10\n\ - \x08\x04\x11\x02\x01\x08\xaf\x08\x12\x12\x04\xaf\x03\"L\n\x94\x02\n\x04\ - \x04\x11\x02\x02\x12\x04\xb5\x03\x02(\x1a\x85\x02\x20The\x20point\x20in\ + e\x20backend.\n\n\r\n\x05\x04\x12\x02\x01\x04\x12\x04\xc7\x03\x02\n\n\r\ + \n\x05\x04\x12\x02\x01\x06\x12\x04\xc7\x03\x0b\x13\n\r\n\x05\x04\x12\x02\ + \x01\x01\x12\x04\xc7\x03\x14\x1c\n\r\n\x05\x04\x12\x02\x01\x03\x12\x04\ + \xc7\x03\x1f\x20\n\r\n\x05\x04\x12\x02\x01\x08\x12\x04\xc7\x03!M\n\x10\n\ + \x08\x04\x12\x02\x01\x08\xaf\x08\x12\x12\x04\xc7\x03\"L\n\x94\x02\n\x04\ + \x04\x12\x02\x02\x12\x04\xcd\x03\x02(\x1a\x85\x02\x20The\x20point\x20in\ \x20time\x20when\x20the\x20client\x20initialized\x20the\x20process\x20of\ \x20uploading\x20collected\x20snapshots.\n\x20Used\x20by\x20the\x20serve\ r\x20to\x20detect\x20clients\x20with\x20skewed\x20clocks.\n\x20The\x20id\ ea\x20is\x20that\x20upon\x20receiving\x20the\x20stats\x20payload,\x20the\ \x20server's\x20current\x20time\x20should\x20be\x20close\x20to\x20this\n\ - \x20value.\n\n\r\n\x05\x04\x11\x02\x02\x06\x12\x04\xb5\x03\x02\x1b\n\r\n\ - \x05\x04\x11\x02\x02\x01\x12\x04\xb5\x03\x1c#\n\r\n\x05\x04\x11\x02\x02\ - \x03\x12\x04\xb5\x03&'\n1\n\x04\x04\x11\x02\x03\x12\x04\xb8\x03\x02!\x1a\ + \x20value.\n\n\r\n\x05\x04\x12\x02\x02\x06\x12\x04\xcd\x03\x02\x1b\n\r\n\ + \x05\x04\x12\x02\x02\x01\x12\x04\xcd\x03\x1c#\n\r\n\x05\x04\x12\x02\x02\ + \x03\x12\x04\xcd\x03&'\n1\n\x04\x04\x12\x02\x03\x12\x04\xd0\x03\x02!\x1a\ #\x20The\x20reason\x20for\x20this\x20stats\x20upload.\n\n\r\n\x05\x04\ - \x11\x02\x03\x06\x12\x04\xb8\x03\x02\x0e\n\r\n\x05\x04\x11\x02\x03\x01\ - \x12\x04\xb8\x03\x0f\x1c\n\r\n\x05\x04\x11\x02\x03\x03\x12\x04\xb8\x03\ - \x1f\x20\n\x0c\n\x02\x04\x12\x12\x06\xbb\x03\0\xc6\x03\x01\n\x0b\n\x03\ - \x04\x12\x01\x12\x04\xbb\x03\x08\x1b\n=\n\x04\x04\x12\x02\0\x12\x04\xbd\ + \x12\x02\x03\x06\x12\x04\xd0\x03\x02\x0e\n\r\n\x05\x04\x12\x02\x03\x01\ + \x12\x04\xd0\x03\x0f\x1c\n\r\n\x05\x04\x12\x02\x03\x03\x12\x04\xd0\x03\ + \x1f\x20\n\x0c\n\x02\x04\x13\x12\x06\xd3\x03\0\xde\x03\x01\n\x0b\n\x03\ + \x04\x13\x01\x12\x04\xd3\x03\x08\x1b\n=\n\x04\x04\x13\x02\0\x12\x04\xd5\ \x03\x02B\x1a/\x20The\x20UUID\x20corresponding\x20to\x20the\x20upload\ - \x20request.\n\n\r\n\x05\x04\x12\x02\0\x05\x12\x04\xbd\x03\x02\x08\n\r\n\ - \x05\x04\x12\x02\0\x01\x12\x04\xbd\x03\t\x14\n\r\n\x05\x04\x12\x02\0\x03\ - \x12\x04\xbd\x03\x17\x18\n\r\n\x05\x04\x12\x02\0\x08\x12\x04\xbd\x03\x19\ - A\n\x10\n\x08\x04\x12\x02\0\x08\xaf\x08\x0e\x12\x04\xbd\x03\x1a@\nr\n\ - \x04\x04\x12\x02\x01\x12\x04\xc1\x03\x02\x13\x1ad\x20Optional\x20error\ + \x20request.\n\n\r\n\x05\x04\x13\x02\0\x05\x12\x04\xd5\x03\x02\x08\n\r\n\ + \x05\x04\x13\x02\0\x01\x12\x04\xd5\x03\t\x14\n\r\n\x05\x04\x13\x02\0\x03\ + \x12\x04\xd5\x03\x17\x18\n\r\n\x05\x04\x13\x02\0\x08\x12\x04\xd5\x03\x19\ + A\n\x10\n\x08\x04\x13\x02\0\x08\xaf\x08\x0e\x12\x04\xd5\x03\x1a@\nr\n\ + \x04\x04\x13\x02\x01\x12\x04\xd9\x03\x02\x13\x1ad\x20Optional\x20error\ \x20message\x20which\x20indicates\x20that\x20stats\x20upload\x20failed\ - \x20and/or\x20some\x20metrics\x20were\n\x20dropped.\n\n\r\n\x05\x04\x12\ - \x02\x01\x05\x12\x04\xc1\x03\x02\x08\n\r\n\x05\x04\x12\x02\x01\x01\x12\ - \x04\xc1\x03\t\x0e\n\r\n\x05\x04\x12\x02\x01\x03\x12\x04\xc1\x03\x11\x12\ - \n\xb9\x01\n\x04\x04\x12\x02\x02\x12\x04\xc5\x03\x02\x1d\x1a\xaa\x01\x20\ + \x20and/or\x20some\x20metrics\x20were\n\x20dropped.\n\n\r\n\x05\x04\x13\ + \x02\x01\x05\x12\x04\xd9\x03\x02\x08\n\r\n\x05\x04\x13\x02\x01\x01\x12\ + \x04\xd9\x03\t\x0e\n\r\n\x05\x04\x13\x02\x01\x03\x12\x04\xd9\x03\x11\x12\ + \n\xb9\x01\n\x04\x04\x13\x02\x02\x12\x04\xdd\x03\x02\x1d\x1a\xaa\x01\x20\ If\x20any\x20metrics\x20were\x20dropped\x20due\x20to\x20validation\x20er\ rors,\x20the\x20count\x20will\x20be\x20supplied\x20here.\x20Error\n\x20w\ ill\x20be\x20populated\x20with\x20debugging\x20information\x20to\x20help\ - \x20understand\x20the\x20error.\n\n\r\n\x05\x04\x12\x02\x02\x05\x12\x04\ - \xc5\x03\x02\x08\n\r\n\x05\x04\x12\x02\x02\x01\x12\x04\xc5\x03\t\x18\n\r\ - \n\x05\x04\x12\x02\x02\x03\x12\x04\xc5\x03\x1b\x1c\n(\n\x02\x04\x13\x12\ - \x04\xc9\x03\0\x17\x1a\x1c\x20Response\x20to\x20a\x20client\x20ping.\n\n\ - \x0b\n\x03\x04\x13\x01\x12\x04\xc9\x03\x08\x14\n;\n\x02\x04\x14\x12\x06\ - \xcc\x03\0\xf4\x03\x01\x1a-\x20Configuration\x20update\x20from\x20server\ - \x20to\x20client.\n\n\x0b\n\x03\x04\x14\x01\x12\x04\xcc\x03\x08\x1b\nx\n\ - \x04\x04\x14\x03\0\x12\x06\xcf\x03\x02\xea\x03\x03\x1ah\x20A\x20complete\ + \x20understand\x20the\x20error.\n\n\r\n\x05\x04\x13\x02\x02\x05\x12\x04\ + \xdd\x03\x02\x08\n\r\n\x05\x04\x13\x02\x02\x01\x12\x04\xdd\x03\t\x18\n\r\ + \n\x05\x04\x13\x02\x02\x03\x12\x04\xdd\x03\x1b\x1c\n(\n\x02\x04\x14\x12\ + \x04\xe1\x03\0\x17\x1a\x1c\x20Response\x20to\x20a\x20client\x20ping.\n\n\ + \x0b\n\x03\x04\x14\x01\x12\x04\xe1\x03\x08\x14\n;\n\x02\x04\x15\x12\x06\ + \xe4\x03\0\x8c\x04\x01\x1a-\x20Configuration\x20update\x20from\x20server\ + \x20to\x20client.\n\n\x0b\n\x03\x04\x15\x01\x12\x04\xe4\x03\x08\x1b\nx\n\ + \x04\x04\x15\x03\0\x12\x06\xe7\x03\x02\x82\x04\x03\x1ah\x20A\x20complete\ \x20configuration\x20snapshot.\x20The\x20client\x20should\x20reconfigure\ \x20to\x20match\x20the\x20supplied\n\x20configuration.\n\n\r\n\x05\x04\ - \x14\x03\0\x01\x12\x04\xcf\x03\n\x19\nd\n\x05\x04\x14\x03\0\n\x12\x04\ - \xd1\x03\x04\x18\x1aU\x20Replaced\x20with\x20`workflow_list`\x20and\x20n\ + \x15\x03\0\x01\x12\x04\xe7\x03\n\x19\nd\n\x05\x04\x15\x03\0\n\x12\x04\ + \xe9\x03\x04\x18\x1aU\x20Replaced\x20with\x20`workflow_list`\x20and\x20n\ ot\x20available\x20for\x20clients\x20with\x20config_version\x206+.\n\n\ - \x0e\n\x06\x04\x14\x03\0\n\0\x12\x04\xd1\x03\r\x17\n\r\n\x05\x04\x14\x03\ - \0\t\x12\x04\xd2\x03\x04\x0f\n\x0e\n\x06\x04\x14\x03\0\t\0\x12\x04\xd2\ - \x03\r\x0e\n\x0f\n\x07\x04\x14\x03\0\t\0\x01\x12\x04\xd2\x03\r\x0e\n\x0f\ - \n\x07\x04\x14\x03\0\t\0\x02\x12\x04\xd2\x03\r\x0e\n&\n\x06\x04\x14\x03\ - \0\x02\0\x12\x04\xd5\x03\x046\x1a\x16\x20The\x20list\x20of\x20buffers.\n\ - \n\x0f\n\x07\x04\x14\x03\0\x02\0\x06\x12\x04\xd5\x03\x04\x1e\n\x0f\n\x07\ - \x04\x14\x03\0\x02\0\x01\x12\x04\xd5\x03\x1f1\n\x0f\n\x07\x04\x14\x03\0\ - \x02\0\x03\x12\x04\xd5\x0345\n.\n\x06\x04\x14\x03\0\x02\x01\x12\x04\xd8\ + \x0e\n\x06\x04\x15\x03\0\n\0\x12\x04\xe9\x03\r\x17\n\r\n\x05\x04\x15\x03\ + \0\t\x12\x04\xea\x03\x04\x0f\n\x0e\n\x06\x04\x15\x03\0\t\0\x12\x04\xea\ + \x03\r\x0e\n\x0f\n\x07\x04\x15\x03\0\t\0\x01\x12\x04\xea\x03\r\x0e\n\x0f\ + \n\x07\x04\x15\x03\0\t\0\x02\x12\x04\xea\x03\r\x0e\n&\n\x06\x04\x15\x03\ + \0\x02\0\x12\x04\xed\x03\x046\x1a\x16\x20The\x20list\x20of\x20buffers.\n\ + \n\x0f\n\x07\x04\x15\x03\0\x02\0\x06\x12\x04\xed\x03\x04\x1e\n\x0f\n\x07\ + \x04\x15\x03\0\x02\0\x01\x12\x04\xed\x03\x1f1\n\x0f\n\x07\x04\x15\x03\0\ + \x02\0\x03\x12\x04\xed\x0345\n.\n\x06\x04\x15\x03\0\x02\x01\x12\x04\xf0\ \x03\x04C\x1a\x1e\x20The\x20workflows\x20configuration.\n\n\x0f\n\x07\ - \x04\x14\x03\0\x02\x01\x06\x12\x04\xd8\x03\x04&\n\x0f\n\x07\x04\x14\x03\ - \0\x02\x01\x01\x12\x04\xd8\x03'>\n\x0f\n\x07\x04\x14\x03\0\x02\x01\x03\ - \x12\x04\xd8\x03AB\n5\n\x06\x04\x14\x03\0\x02\x02\x12\x04\xdb\x03\x04<\ + \x04\x15\x03\0\x02\x01\x06\x12\x04\xf0\x03\x04&\n\x0f\n\x07\x04\x15\x03\ + \0\x02\x01\x01\x12\x04\xf0\x03'>\n\x0f\n\x07\x04\x15\x03\0\x02\x01\x03\ + \x12\x04\xf0\x03AB\n5\n\x06\x04\x15\x03\0\x02\x02\x12\x04\xf3\x03\x04<\ \x1a%\x20The\x20list\x20of\x20active\x20bdtail\x20sessions.\n\n\x0f\n\ - \x07\x04\x14\x03\0\x02\x02\x06\x12\x04\xdb\x03\x04\"\n\x0f\n\x07\x04\x14\ - \x03\0\x02\x02\x01\x12\x04\xdb\x03#7\n\x0f\n\x07\x04\x14\x03\0\x02\x02\ - \x03\x12\x04\xdb\x03:;\n\r\n\x05\x04\x14\x03\0\n\x12\x04\xdd\x03\x04&\n\ - \x0e\n\x06\x04\x14\x03\0\n\x01\x12\x04\xdd\x03\r%\n\r\n\x05\x04\x14\x03\ - \0\t\x12\x04\xde\x03\x04\x0f\n\x0e\n\x06\x04\x14\x03\0\t\x01\x12\x04\xde\ - \x03\r\x0e\n\x0f\n\x07\x04\x14\x03\0\t\x01\x01\x12\x04\xde\x03\r\x0e\n\ - \x0f\n\x07\x04\x14\x03\0\t\x01\x02\x12\x04\xde\x03\r\x0e\n,\n\x06\x04\ - \x14\x03\0\x02\x03\x12\x04\xe1\x03\x04=\x1a\x1c\x20The\x20filters\x20con\ - figuration.\n\n\x0f\n\x07\x04\x14\x03\0\x02\x03\x06\x12\x04\xe1\x03\x04\ - \"\n\x0f\n\x07\x04\x14\x03\0\x02\x03\x01\x12\x04\xe1\x03#8\n\x0f\n\x07\ - \x04\x14\x03\0\x02\x03\x03\x12\x04\xe1\x03;<\n\xd4\x03\n\x06\x04\x14\x03\ - \0\x02\x04\x12\x04\xe9\x03\x04;\x1a\xc3\x03\x20The\x20list\x20of\x20work\ + \x07\x04\x15\x03\0\x02\x02\x06\x12\x04\xf3\x03\x04\"\n\x0f\n\x07\x04\x15\ + \x03\0\x02\x02\x01\x12\x04\xf3\x03#7\n\x0f\n\x07\x04\x15\x03\0\x02\x02\ + \x03\x12\x04\xf3\x03:;\n\r\n\x05\x04\x15\x03\0\n\x12\x04\xf5\x03\x04&\n\ + \x0e\n\x06\x04\x15\x03\0\n\x01\x12\x04\xf5\x03\r%\n\r\n\x05\x04\x15\x03\ + \0\t\x12\x04\xf6\x03\x04\x0f\n\x0e\n\x06\x04\x15\x03\0\t\x01\x12\x04\xf6\ + \x03\r\x0e\n\x0f\n\x07\x04\x15\x03\0\t\x01\x01\x12\x04\xf6\x03\r\x0e\n\ + \x0f\n\x07\x04\x15\x03\0\t\x01\x02\x12\x04\xf6\x03\r\x0e\n,\n\x06\x04\ + \x15\x03\0\x02\x03\x12\x04\xf9\x03\x04=\x1a\x1c\x20The\x20filters\x20con\ + figuration.\n\n\x0f\n\x07\x04\x15\x03\0\x02\x03\x06\x12\x04\xf9\x03\x04\ + \"\n\x0f\n\x07\x04\x15\x03\0\x02\x03\x01\x12\x04\xf9\x03#8\n\x0f\n\x07\ + \x04\x15\x03\0\x02\x03\x03\x12\x04\xf9\x03;<\n\xd4\x03\n\x06\x04\x15\x03\ + \0\x02\x04\x12\x04\x81\x04\x04;\x1a\xc3\x03\x20The\x20list\x20of\x20work\ flows\x20to\x20debug.\x20If\x20the\x20workflow\x20is\x20already\x20deplo\ yed,\x20debug\x20data\x20will\x20be\n\x20generated\x20for\x20it\x20along\ side\x20the\x20deployed\x20workflow.\x20If\x20the\x20workflow\x20is\x20n\ @@ -10650,210 +11378,214 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x20deployed\"\x20implies\x20that\x20the\x20workflow\x20will\x20be\x20fo\ und\x20in\x20the\n\x20workflows_configuration\x20field.\x20The\x20server\ \x20will\x20not\x20de-dup\x20for\x20simplification\x20purposes.\n\n\x0f\ - \n\x07\x04\x14\x03\0\x02\x04\x06\x12\x04\xe9\x03\x04&\n\x0f\n\x07\x04\ - \x14\x03\0\x02\x04\x01\x12\x04\xe9\x03'6\n\x0f\n\x07\x04\x14\x03\0\x02\ - \x04\x03\x12\x04\xe9\x039:\n\x8a\x01\n\x04\x04\x14\x02\0\x12\x04\xee\x03\ + \n\x07\x04\x15\x03\0\x02\x04\x06\x12\x04\x81\x04\x04&\n\x0f\n\x07\x04\ + \x15\x03\0\x02\x04\x01\x12\x04\x81\x04'6\n\x0f\n\x07\x04\x15\x03\0\x02\ + \x04\x03\x12\x04\x81\x049:\n\x8a\x01\n\x04\x04\x15\x02\0\x12\x04\x86\x04\ \x02\x1b\x1a|\x20A\x20version\x20nonce\x20that\x20can\x20be\x20used\x20f\ or\x20both\x20tracking\x20the\x20last\x20applied\x20update\x20as\x20well\ \x20as\x20for\n\x20responding\x20with\x20a\x20NACK\x20message.\n\n\r\n\ - \x05\x04\x14\x02\0\x05\x12\x04\xee\x03\x02\x08\n\r\n\x05\x04\x14\x02\0\ - \x01\x12\x04\xee\x03\t\x16\n\r\n\x05\x04\x14\x02\0\x03\x12\x04\xee\x03\ - \x19\x1a\n\x0e\n\x04\x04\x14\x08\0\x12\x06\xf0\x03\x02\xf3\x03\x03\n\r\n\ - \x05\x04\x14\x08\0\x01\x12\x04\xf0\x03\x08\x13\nH\n\x04\x04\x14\x02\x01\ - \x12\x04\xf2\x03\x04+\x1a:\x20SoTW\x20is\x20the\x20only\x20currently\x20\ - supported\x20configuration\x20type.\n\n\r\n\x05\x04\x14\x02\x01\x06\x12\ - \x04\xf2\x03\x04\x13\n\r\n\x05\x04\x14\x02\x01\x01\x12\x04\xf2\x03\x14&\ - \n\r\n\x05\x04\x14\x02\x01\x03\x12\x04\xf2\x03)*\n5\n\x02\x04\x15\x12\ - \x06\xf7\x03\0\xfe\x03\x01\x1a'\x20Runtime\x20update\x20from\x20server\ - \x20to\x20client.\n\n\x0b\n\x03\x04\x15\x01\x12\x04\xf7\x03\x08\x15\n\ - \x8a\x01\n\x04\x04\x15\x02\0\x12\x04\xfa\x03\x02\x1b\x1a|\x20A\x20versio\ + \x05\x04\x15\x02\0\x05\x12\x04\x86\x04\x02\x08\n\r\n\x05\x04\x15\x02\0\ + \x01\x12\x04\x86\x04\t\x16\n\r\n\x05\x04\x15\x02\0\x03\x12\x04\x86\x04\ + \x19\x1a\n\x0e\n\x04\x04\x15\x08\0\x12\x06\x88\x04\x02\x8b\x04\x03\n\r\n\ + \x05\x04\x15\x08\0\x01\x12\x04\x88\x04\x08\x13\nH\n\x04\x04\x15\x02\x01\ + \x12\x04\x8a\x04\x04+\x1a:\x20SoTW\x20is\x20the\x20only\x20currently\x20\ + supported\x20configuration\x20type.\n\n\r\n\x05\x04\x15\x02\x01\x06\x12\ + \x04\x8a\x04\x04\x13\n\r\n\x05\x04\x15\x02\x01\x01\x12\x04\x8a\x04\x14&\ + \n\r\n\x05\x04\x15\x02\x01\x03\x12\x04\x8a\x04)*\n5\n\x02\x04\x16\x12\ + \x06\x8f\x04\0\x96\x04\x01\x1a'\x20Runtime\x20update\x20from\x20server\ + \x20to\x20client.\n\n\x0b\n\x03\x04\x16\x01\x12\x04\x8f\x04\x08\x15\n\ + \x8a\x01\n\x04\x04\x16\x02\0\x12\x04\x92\x04\x02\x1b\x1a|\x20A\x20versio\ n\x20nonce\x20that\x20can\x20be\x20used\x20for\x20both\x20tracking\x20th\ e\x20last\x20applied\x20update\x20as\x20well\x20as\x20for\n\x20respondin\ - g\x20with\x20a\x20NACK\x20message.\n\n\r\n\x05\x04\x15\x02\0\x05\x12\x04\ - \xfa\x03\x02\x08\n\r\n\x05\x04\x15\x02\0\x01\x12\x04\xfa\x03\t\x16\n\r\n\ - \x05\x04\x15\x02\0\x03\x12\x04\xfa\x03\x19\x1a\n,\n\x04\x04\x15\x02\x01\ - \x12\x04\xfd\x03\x02\x16\x1a\x1e\x20The\x20runtime\x20instance\x20to\x20\ - use.\n\n\r\n\x05\x04\x15\x02\x01\x06\x12\x04\xfd\x03\x02\t\n\r\n\x05\x04\ - \x15\x02\x01\x01\x12\x04\xfd\x03\n\x11\n\r\n\x05\x04\x15\x02\x01\x03\x12\ - \x04\xfd\x03\x14\x15\n\x8b\x02\n\x02\x04\x16\x12\x06\x83\x04\0\x8c\x04\ + g\x20with\x20a\x20NACK\x20message.\n\n\r\n\x05\x04\x16\x02\0\x05\x12\x04\ + \x92\x04\x02\x08\n\r\n\x05\x04\x16\x02\0\x01\x12\x04\x92\x04\t\x16\n\r\n\ + \x05\x04\x16\x02\0\x03\x12\x04\x92\x04\x19\x1a\n,\n\x04\x04\x16\x02\x01\ + \x12\x04\x95\x04\x02\x16\x1a\x1e\x20The\x20runtime\x20instance\x20to\x20\ + use.\n\n\r\n\x05\x04\x16\x02\x01\x06\x12\x04\x95\x04\x02\t\n\r\n\x05\x04\ + \x16\x02\x01\x01\x12\x04\x95\x04\n\x11\n\r\n\x05\x04\x16\x02\x01\x03\x12\ + \x04\x95\x04\x14\x15\n\x8b\x02\n\x02\x04\x17\x12\x06\x9b\x04\0\xa4\x04\ \x01\x1a\xfc\x01\x20In\x20order\x20to\x20support\x20clients\x20that\x20c\ an't\x20easily\x20implement\x20gRPC\x20(e.g.,\x20iOS\x20URLSession),\x20\ instead\x20of\n\x20closing\x20a\x20stream\x20with\x20trailers,\x20this\ \x20frame\x20will\x20be\x20sent\x20followed\x20by\x20stream\x20closure.\ \x20This\x20allows\n\x20an\x20easier\x20way\x20for\x20the\x20client\x20t\ - o\x20debug\x20and\x20handle\x20errors.\n\n\x0b\n\x03\x04\x16\x01\x12\x04\ - \x83\x04\x08\x15\nA\n\x04\x04\x16\x02\0\x12\x04\x85\x04\x02\x18\x1a3\x20\ + o\x20debug\x20and\x20handle\x20errors.\n\n\x0b\n\x03\x04\x17\x01\x12\x04\ + \x9b\x04\x08\x15\nA\n\x04\x04\x17\x02\0\x12\x04\x9d\x04\x02\x18\x1a3\x20\ The\x20status\x20that\x20would\x20have\x20been\x20sent\x20in\x20trailers\ - .\n\n\r\n\x05\x04\x16\x02\0\x05\x12\x04\x85\x04\x02\x07\n\r\n\x05\x04\ - \x16\x02\0\x01\x12\x04\x85\x04\x08\x13\n\r\n\x05\x04\x16\x02\0\x03\x12\ - \x04\x85\x04\x16\x17\nB\n\x04\x04\x16\x02\x01\x12\x04\x88\x04\x02\x1a\ + .\n\n\r\n\x05\x04\x17\x02\0\x05\x12\x04\x9d\x04\x02\x07\n\r\n\x05\x04\ + \x17\x02\0\x01\x12\x04\x9d\x04\x08\x13\n\r\n\x05\x04\x17\x02\0\x03\x12\ + \x04\x9d\x04\x16\x17\nB\n\x04\x04\x17\x02\x01\x12\x04\xa0\x04\x02\x1a\ \x1a4\x20The\x20message\x20that\x20would\x20have\x20been\x20sent\x20in\ - \x20trailers.\n\n\r\n\x05\x04\x16\x02\x01\x05\x12\x04\x88\x04\x02\x08\n\ - \r\n\x05\x04\x16\x02\x01\x01\x12\x04\x88\x04\t\x15\n\r\n\x05\x04\x16\x02\ - \x01\x03\x12\x04\x88\x04\x18\x19\nH\n\x04\x04\x16\x02\x02\x12\x04\x8b\ + \x20trailers.\n\n\r\n\x05\x04\x17\x02\x01\x05\x12\x04\xa0\x04\x02\x08\n\ + \r\n\x05\x04\x17\x02\x01\x01\x12\x04\xa0\x04\t\x15\n\r\n\x05\x04\x17\x02\ + \x01\x03\x12\x04\xa0\x04\x18\x19\nH\n\x04\x04\x17\x02\x02\x12\x04\xa3\ \x04\x02\x1f\x1a:\x20Optional\x20rate\x20limiting\x20that\x20the\x20clie\ - nt\x20should\x20adhere\x20to.\n\n\r\n\x05\x04\x16\x02\x02\x06\x12\x04\ - \x8b\x04\x02\r\n\r\n\x05\x04\x16\x02\x02\x01\x12\x04\x8b\x04\x0e\x1a\n\r\ - \n\x05\x04\x16\x02\x02\x03\x12\x04\x8b\x04\x1d\x1e\n\x86\x02\n\x02\x04\ - \x17\x12\x06\x91\x04\0\x96\x04\x01\x1a\xf7\x01\x20Called\x20by\x20the\ + nt\x20should\x20adhere\x20to.\n\n\r\n\x05\x04\x17\x02\x02\x06\x12\x04\ + \xa3\x04\x02\r\n\r\n\x05\x04\x17\x02\x02\x01\x12\x04\xa3\x04\x0e\x1a\n\r\ + \n\x05\x04\x17\x02\x02\x03\x12\x04\xa3\x04\x1d\x1e\n\x86\x02\n\x02\x04\ + \x18\x12\x06\xa9\x04\0\xae\x04\x01\x1a\xf7\x01\x20Called\x20by\x20the\ \x20server\x20to\x20tell\x20the\x20client\x20to\x20flush\x20a\x20set\x20\ of\x20owned\x20buffers.\x20When\x20this\x20command\x20is\n\x20received\ \x20by\x20the\x20client\x20it\x20should\x20proceed\x20with\x20normal\x20\ behavior\x20as\x20if\x20it\x20had\x20decided\x20to\x20flush\n\x20the\x20\ buffers\x20locally\x20(e.g.,\x20rate\x20limiting,\x20intents,\x20etc.).\ - \n\n\x0b\n\x03\x04\x17\x01\x12\x04\x91\x04\x08\x14\n\xfc\x01\n\x04\x04\ - \x17\x02\0\x12\x04\x95\x04\x02%\x1a\xed\x01\x20The\x20list\x20of\x20buff\ + \n\n\x0b\n\x03\x04\x18\x01\x12\x04\xa9\x04\x08\x14\n\xfc\x01\n\x04\x04\ + \x18\x02\0\x12\x04\xad\x04\x02%\x1a\xed\x01\x20The\x20list\x20of\x20buff\ ers\x20to\x20flush.\x20If\x20the\x20list\x20is\x20empty,\x20all\x20buffe\ rs\x20should\x20be\x20flushed.\x20In\x20the\x20case\n\x20of\x20a\x20serv\ er\x20side\x20listener\x20trigger,\x20every\x20occurrence\x20of\x20Actio\ nFlushBuffer\x20in\x20the\x20trigger_actions\n\x20field\x20will\x20popul\ - ate\x20a\x20buffer\x20in\x20this\x20list.\n\n\r\n\x05\x04\x17\x02\0\x04\ - \x12\x04\x95\x04\x02\n\n\r\n\x05\x04\x17\x02\0\x05\x12\x04\x95\x04\x0b\ - \x11\n\r\n\x05\x04\x17\x02\0\x01\x12\x04\x95\x04\x12\x20\n\r\n\x05\x04\ - \x17\x02\0\x03\x12\x04\x95\x04#$\nC\n\x02\x04\x18\x12\x06\x99\x04\0\xa0\ + ate\x20a\x20buffer\x20in\x20this\x20list.\n\n\r\n\x05\x04\x18\x02\0\x04\ + \x12\x04\xad\x04\x02\n\n\r\n\x05\x04\x18\x02\0\x05\x12\x04\xad\x04\x0b\ + \x11\n\r\n\x05\x04\x18\x02\0\x01\x12\x04\xad\x04\x12\x20\n\r\n\x05\x04\ + \x18\x02\0\x03\x12\x04\xad\x04#$\nC\n\x02\x04\x19\x12\x06\xb1\x04\0\xb8\ \x04\x01\x1a5\x20The\x20response\x20to\x20Sankey\x20diagram\x20path\x20u\ - pload\x20request.\n\n\x0b\n\x03\x04\x18\x01\x12\x04\x99\x04\x08\x20\n=\n\ - \x04\x04\x18\x02\0\x12\x04\x9b\x04\x02B\x1a/\x20The\x20UUID\x20correspon\ - ding\x20to\x20the\x20upload\x20request.\n\n\r\n\x05\x04\x18\x02\0\x05\ - \x12\x04\x9b\x04\x02\x08\n\r\n\x05\x04\x18\x02\0\x01\x12\x04\x9b\x04\t\ - \x14\n\r\n\x05\x04\x18\x02\0\x03\x12\x04\x9b\x04\x17\x18\n\r\n\x05\x04\ - \x18\x02\0\x08\x12\x04\x9b\x04\x19A\n\x10\n\x08\x04\x18\x02\0\x08\xaf\ - \x08\x0e\x12\x04\x9b\x04\x1a@\ns\n\x04\x04\x18\x02\x01\x12\x04\x9f\x04\ + pload\x20request.\n\n\x0b\n\x03\x04\x19\x01\x12\x04\xb1\x04\x08\x20\n=\n\ + \x04\x04\x19\x02\0\x12\x04\xb3\x04\x02B\x1a/\x20The\x20UUID\x20correspon\ + ding\x20to\x20the\x20upload\x20request.\n\n\r\n\x05\x04\x19\x02\0\x05\ + \x12\x04\xb3\x04\x02\x08\n\r\n\x05\x04\x19\x02\0\x01\x12\x04\xb3\x04\t\ + \x14\n\r\n\x05\x04\x19\x02\0\x03\x12\x04\xb3\x04\x17\x18\n\r\n\x05\x04\ + \x19\x02\0\x08\x12\x04\xb3\x04\x19A\n\x10\n\x08\x04\x19\x02\0\x08\xaf\ + \x08\x0e\x12\x04\xb3\x04\x1a@\ns\n\x04\x04\x19\x02\x01\x12\x04\xb7\x04\ \x02\x13\x1ae\x20Optional\x20error\x20message\x20which\x20indicates\x20t\ hat\x20sankey\x20upload\x20failed\x20and/or\x20some\x20metrics\x20were\n\ - \x20dropped.\n\n\r\n\x05\x04\x18\x02\x01\x05\x12\x04\x9f\x04\x02\x08\n\r\ - \n\x05\x04\x18\x02\x01\x01\x12\x04\x9f\x04\t\x0e\n\r\n\x05\x04\x18\x02\ - \x01\x03\x12\x04\x9f\x04\x11\x12\n>\n\x02\x04\x19\x12\x06\xa3\x04\0\xb4\ + \x20dropped.\n\n\r\n\x05\x04\x19\x02\x01\x05\x12\x04\xb7\x04\x02\x08\n\r\ + \n\x05\x04\x19\x02\x01\x01\x12\x04\xb7\x04\t\x0e\n\r\n\x05\x04\x19\x02\ + \x01\x03\x12\x04\xb7\x04\x11\x12\n>\n\x02\x04\x1a\x12\x06\xbb\x04\0\xcc\ \x04\x01\x1a0\x20The\x20response\x20to\x20Sankey\x20diagram\x20intent\ - \x20request.\n\n\x0b\n\x03\x04\x19\x01\x12\x04\xa3\x04\x08\x1c\n\x0c\n\ - \x04\x04\x19\x02\0\x12\x04\xa4\x04\x02B\n\r\n\x05\x04\x19\x02\0\x05\x12\ - \x04\xa4\x04\x02\x08\n\r\n\x05\x04\x19\x02\0\x01\x12\x04\xa4\x04\t\x14\n\ - \r\n\x05\x04\x19\x02\0\x03\x12\x04\xa4\x04\x17\x18\n\r\n\x05\x04\x19\x02\ - \0\x08\x12\x04\xa4\x04\x19A\n\x10\n\x08\x04\x19\x02\0\x08\xaf\x08\x0e\ - \x12\x04\xa4\x04\x1a@\n\x0b\n\x03\x04\x19\t\x12\x04\xa6\x04\x02\r\n\x0c\ - \n\x04\x04\x19\t\0\x12\x04\xa6\x04\x0b\x0c\n\r\n\x05\x04\x19\t\0\x01\x12\ - \x04\xa6\x04\x0b\x0c\n\r\n\x05\x04\x19\t\0\x02\x12\x04\xa6\x04\x0b\x0c\n\ - \x0b\n\x03\x04\x19\n\x12\x04\xa7\x04\x02\x16\n\x0c\n\x04\x04\x19\n\0\x12\ - \x04\xa7\x04\x0b\x15\n\x0c\n\x04\x04\x19\x03\0\x12\x04\xa9\x04\x02\x1e\n\ - \r\n\x05\x04\x19\x03\0\x01\x12\x04\xa9\x04\n\x1b\n\x0c\n\x04\x04\x19\x03\ - \x01\x12\x04\xab\x04\x02\x11\n\r\n\x05\x04\x19\x03\x01\x01\x12\x04\xab\ - \x04\n\x0e\n\x0e\n\x04\x04\x19\x08\0\x12\x06\xad\x04\x02\xb3\x04\x03\n\r\ - \n\x05\x04\x19\x08\0\x01\x12\x04\xad\x04\x08\x10\nI\n\x04\x04\x19\x02\ - \x01\x12\x04\xaf\x04\x04-\x1a;\x20The\x20candidate\x20sankey\x20path\x20\ - should\x20be\x20uploaded\x20immediately.\n\n\r\n\x05\x04\x19\x02\x01\x06\ - \x12\x04\xaf\x04\x04\x15\n\r\n\x05\x04\x19\x02\x01\x01\x12\x04\xaf\x04\ - \x16(\n\r\n\x05\x04\x19\x02\x01\x03\x12\x04\xaf\x04+,\n<\n\x04\x04\x19\ - \x02\x02\x12\x04\xb2\x04\x04\x12\x1a.\x20The\x20candidate\x20sankey\x20p\ - ath\x20should\x20be\x20dropped.\n\n\r\n\x05\x04\x19\x02\x02\x06\x12\x04\ - \xb2\x04\x04\x08\n\r\n\x05\x04\x19\x02\x02\x01\x12\x04\xb2\x04\t\r\n\r\n\ - \x05\x04\x19\x02\x02\x03\x12\x04\xb2\x04\x10\x11\nj\n\x02\x04\x1a\x12\ - \x06\xb7\x04\0\xdb\x04\x01\x1a\\\x20Debug\x20data\x20that\x20is\x20perio\ + \x20request.\n\n\x0b\n\x03\x04\x1a\x01\x12\x04\xbb\x04\x08\x1c\n\x0c\n\ + \x04\x04\x1a\x02\0\x12\x04\xbc\x04\x02B\n\r\n\x05\x04\x1a\x02\0\x05\x12\ + \x04\xbc\x04\x02\x08\n\r\n\x05\x04\x1a\x02\0\x01\x12\x04\xbc\x04\t\x14\n\ + \r\n\x05\x04\x1a\x02\0\x03\x12\x04\xbc\x04\x17\x18\n\r\n\x05\x04\x1a\x02\ + \0\x08\x12\x04\xbc\x04\x19A\n\x10\n\x08\x04\x1a\x02\0\x08\xaf\x08\x0e\ + \x12\x04\xbc\x04\x1a@\n\x0b\n\x03\x04\x1a\t\x12\x04\xbe\x04\x02\r\n\x0c\ + \n\x04\x04\x1a\t\0\x12\x04\xbe\x04\x0b\x0c\n\r\n\x05\x04\x1a\t\0\x01\x12\ + \x04\xbe\x04\x0b\x0c\n\r\n\x05\x04\x1a\t\0\x02\x12\x04\xbe\x04\x0b\x0c\n\ + \x0b\n\x03\x04\x1a\n\x12\x04\xbf\x04\x02\x16\n\x0c\n\x04\x04\x1a\n\0\x12\ + \x04\xbf\x04\x0b\x15\n\x0c\n\x04\x04\x1a\x03\0\x12\x04\xc1\x04\x02\x1e\n\ + \r\n\x05\x04\x1a\x03\0\x01\x12\x04\xc1\x04\n\x1b\n\x0c\n\x04\x04\x1a\x03\ + \x01\x12\x04\xc3\x04\x02\x11\n\r\n\x05\x04\x1a\x03\x01\x01\x12\x04\xc3\ + \x04\n\x0e\n\x0e\n\x04\x04\x1a\x08\0\x12\x06\xc5\x04\x02\xcb\x04\x03\n\r\ + \n\x05\x04\x1a\x08\0\x01\x12\x04\xc5\x04\x08\x10\nI\n\x04\x04\x1a\x02\ + \x01\x12\x04\xc7\x04\x04-\x1a;\x20The\x20candidate\x20sankey\x20path\x20\ + should\x20be\x20uploaded\x20immediately.\n\n\r\n\x05\x04\x1a\x02\x01\x06\ + \x12\x04\xc7\x04\x04\x15\n\r\n\x05\x04\x1a\x02\x01\x01\x12\x04\xc7\x04\ + \x16(\n\r\n\x05\x04\x1a\x02\x01\x03\x12\x04\xc7\x04+,\n<\n\x04\x04\x1a\ + \x02\x02\x12\x04\xca\x04\x04\x12\x1a.\x20The\x20candidate\x20sankey\x20p\ + ath\x20should\x20be\x20dropped.\n\n\r\n\x05\x04\x1a\x02\x02\x06\x12\x04\ + \xca\x04\x04\x08\n\r\n\x05\x04\x1a\x02\x02\x01\x12\x04\xca\x04\t\r\n\r\n\ + \x05\x04\x1a\x02\x02\x03\x12\x04\xca\x04\x10\x11\nj\n\x02\x04\x1b\x12\ + \x06\xcf\x04\0\xf3\x04\x01\x1a\\\x20Debug\x20data\x20that\x20is\x20perio\ dically\x20sent\x20when\x20instructed\x20via\x20the\x20DebugControlRespo\ - nse\x20message.\n\n\x0b\n\x03\x04\x1a\x01\x12\x04\xb7\x04\x08\x18\n\x0e\ - \n\x04\x04\x1a\x03\0\x12\x06\xb8\x04\x02\xc6\x04\x03\n\r\n\x05\x04\x1a\ - \x03\0\x01\x12\x04\xb8\x04\n%\n\x10\n\x06\x04\x1a\x03\0\x08\0\x12\x06\ - \xb9\x04\x04\xbf\x04\x05\n\x0f\n\x07\x04\x1a\x03\0\x08\0\x01\x12\x04\xb9\ - \x04\n\x19\nQ\n\x06\x04\x1a\x03\0\x02\0\x12\x04\xbb\x04\x06\"\x1aA\x20Th\ + nse\x20message.\n\n\x0b\n\x03\x04\x1b\x01\x12\x04\xcf\x04\x08\x18\n\x0e\ + \n\x04\x04\x1b\x03\0\x12\x06\xd0\x04\x02\xde\x04\x03\n\r\n\x05\x04\x1b\ + \x03\0\x01\x12\x04\xd0\x04\n%\n\x10\n\x06\x04\x1b\x03\0\x08\0\x12\x06\ + \xd1\x04\x04\xd7\x04\x05\n\x0f\n\x07\x04\x1b\x03\0\x08\0\x01\x12\x04\xd1\ + \x04\n\x19\nQ\n\x06\x04\x1b\x03\0\x02\0\x12\x04\xd3\x04\x06\"\x1aA\x20Th\ e\x20index\x20of\x20the\x20transition\x20that\x20was\x20taken\x20to\x20l\ - eave\x20this\x20state.\n\n\x0f\n\x07\x04\x1a\x03\0\x02\0\x05\x12\x04\xbb\ - \x04\x06\x0c\n\x0f\n\x07\x04\x1a\x03\0\x02\0\x01\x12\x04\xbb\x04\r\x1d\n\ - \x0f\n\x07\x04\x1a\x03\0\x02\0\x03\x12\x04\xbb\x04\x20!\nC\n\x06\x04\x1a\ - \x03\0\x02\x01\x12\x04\xbe\x04\x06\"\x1a3\x20Whether\x20this\x20transiti\ - on\x20was\x20a\x20timeout\x20transition.\n\n\x0f\n\x07\x04\x1a\x03\0\x02\ - \x01\x05\x12\x04\xbe\x04\x06\n\n\x0f\n\x07\x04\x1a\x03\0\x02\x01\x01\x12\ - \x04\xbe\x04\x0b\x1d\n\x0f\n\x07\x04\x1a\x03\0\x02\x01\x03\x12\x04\xbe\ - \x04\x20!\nY\n\x06\x04\x1a\x03\0\x02\x02\x12\x04\xc2\x04\x04\x20\x1aI\ + eave\x20this\x20state.\n\n\x0f\n\x07\x04\x1b\x03\0\x02\0\x05\x12\x04\xd3\ + \x04\x06\x0c\n\x0f\n\x07\x04\x1b\x03\0\x02\0\x01\x12\x04\xd3\x04\r\x1d\n\ + \x0f\n\x07\x04\x1b\x03\0\x02\0\x03\x12\x04\xd3\x04\x20!\nC\n\x06\x04\x1b\ + \x03\0\x02\x01\x12\x04\xd6\x04\x06\"\x1a3\x20Whether\x20this\x20transiti\ + on\x20was\x20a\x20timeout\x20transition.\n\n\x0f\n\x07\x04\x1b\x03\0\x02\ + \x01\x05\x12\x04\xd6\x04\x06\n\n\x0f\n\x07\x04\x1b\x03\0\x02\x01\x01\x12\ + \x04\xd6\x04\x0b\x1d\n\x0f\n\x07\x04\x1b\x03\0\x02\x01\x03\x12\x04\xd6\ + \x04\x20!\nY\n\x06\x04\x1b\x03\0\x02\x02\x12\x04\xda\x04\x04\x20\x1aI\ \x20The\x20number\x20of\x20times\x20this\x20state/transition\x20has\x20b\ - een\x20transitioned\x20out\x20of.\n\n\x0f\n\x07\x04\x1a\x03\0\x02\x02\ - \x05\x12\x04\xc2\x04\x04\n\n\x0f\n\x07\x04\x1a\x03\0\x02\x02\x01\x12\x04\ - \xc2\x04\x0b\x1b\n\x0f\n\x07\x04\x1a\x03\0\x02\x02\x03\x12\x04\xc2\x04\ - \x1e\x1f\nN\n\x06\x04\x1a\x03\0\x02\x03\x12\x04\xc5\x04\x047\x1a>\x20The\ + een\x20transitioned\x20out\x20of.\n\n\x0f\n\x07\x04\x1b\x03\0\x02\x02\ + \x05\x12\x04\xda\x04\x04\n\n\x0f\n\x07\x04\x1b\x03\0\x02\x02\x01\x12\x04\ + \xda\x04\x0b\x1b\n\x0f\n\x07\x04\x1b\x03\0\x02\x02\x03\x12\x04\xda\x04\ + \x1e\x1f\nN\n\x06\x04\x1b\x03\0\x02\x03\x12\x04\xdd\x04\x047\x1a>\x20The\ \x20last\x20time\x20this\x20state/transition\x20was\x20transitioned\x20o\ - ut\x20of.\n\n\x0f\n\x07\x04\x1a\x03\0\x02\x03\x06\x12\x04\xc5\x04\x04\ - \x1d\n\x0f\n\x07\x04\x1a\x03\0\x02\x03\x01\x12\x04\xc5\x04\x1e2\n\x0f\n\ - \x07\x04\x1a\x03\0\x02\x03\x03\x12\x04\xc5\x0456\n\x0e\n\x04\x04\x1a\x03\ - \x01\x12\x06\xc8\x04\x02\xca\x04\x03\n\r\n\x05\x04\x1a\x03\x01\x01\x12\ - \x04\xc8\x04\n\x20\n\x0e\n\x06\x04\x1a\x03\x01\x02\0\x12\x04\xc9\x04\x04\ - 9\n\x0f\n\x07\x04\x1a\x03\x01\x02\0\x04\x12\x04\xc9\x04\x04\x0c\n\x0f\n\ - \x07\x04\x1a\x03\x01\x02\0\x06\x12\x04\xc9\x04\r(\n\x0f\n\x07\x04\x1a\ - \x03\x01\x02\0\x01\x12\x04\xc9\x04)4\n\x0f\n\x07\x04\x1a\x03\x01\x02\0\ - \x03\x12\x04\xc9\x0478\n\x0e\n\x04\x04\x1a\x03\x02\x12\x06\xcc\x04\x02\ - \xd6\x04\x03\n\r\n\x05\x04\x1a\x03\x02\x01\x12\x04\xcc\x04\n\x1b\n\x85\ - \x01\n\x06\x04\x1a\x03\x02\x02\0\x12\x04\xcf\x04\x043\x1au\x20The\x20sta\ + ut\x20of.\n\n\x0f\n\x07\x04\x1b\x03\0\x02\x03\x06\x12\x04\xdd\x04\x04\ + \x1d\n\x0f\n\x07\x04\x1b\x03\0\x02\x03\x01\x12\x04\xdd\x04\x1e2\n\x0f\n\ + \x07\x04\x1b\x03\0\x02\x03\x03\x12\x04\xdd\x0456\n\x0e\n\x04\x04\x1b\x03\ + \x01\x12\x06\xe0\x04\x02\xe2\x04\x03\n\r\n\x05\x04\x1b\x03\x01\x01\x12\ + \x04\xe0\x04\n\x20\n\x0e\n\x06\x04\x1b\x03\x01\x02\0\x12\x04\xe1\x04\x04\ + 9\n\x0f\n\x07\x04\x1b\x03\x01\x02\0\x04\x12\x04\xe1\x04\x04\x0c\n\x0f\n\ + \x07\x04\x1b\x03\x01\x02\0\x06\x12\x04\xe1\x04\r(\n\x0f\n\x07\x04\x1b\ + \x03\x01\x02\0\x01\x12\x04\xe1\x04)4\n\x0f\n\x07\x04\x1b\x03\x01\x02\0\ + \x03\x12\x04\xe1\x0478\n\x0e\n\x04\x04\x1b\x03\x02\x12\x06\xe4\x04\x02\ + \xee\x04\x03\n\r\n\x05\x04\x1b\x03\x02\x01\x12\x04\xe4\x04\n\x1b\n\x85\ + \x01\n\x06\x04\x1b\x03\x02\x02\0\x12\x04\xe7\x04\x043\x1au\x20The\x20sta\ te\x20debug\x20data\x20for\x20each\x20state\x20in\x20the\x20workflow\x20\ that\x20has\x20been\x20transitioned.\x20This\x20is\x20a\x20map\n\x20of\ - \x20state\x20ID\x20to\x20data.\n\n\x0f\n\x07\x04\x1a\x03\x02\x02\0\x06\ - \x12\x04\xcf\x04\x04'\n\x0f\n\x07\x04\x1a\x03\x02\x02\0\x01\x12\x04\xcf\ - \x04(.\n\x0f\n\x07\x04\x1a\x03\x02\x02\0\x03\x12\x04\xcf\x0412\n\xa6\x02\ - \n\x06\x04\x1a\x03\x02\x02\x01\x12\x04\xd5\x04\x040\x1a\x95\x02\x20This\ + \x20state\x20ID\x20to\x20data.\n\n\x0f\n\x07\x04\x1b\x03\x02\x02\0\x06\ + \x12\x04\xe7\x04\x04'\n\x0f\n\x07\x04\x1b\x03\x02\x02\0\x01\x12\x04\xe7\ + \x04(.\n\x0f\n\x07\x04\x1b\x03\x02\x02\0\x03\x12\x04\xe7\x0412\n\xa6\x02\ + \n\x06\x04\x1b\x03\x02\x02\x01\x12\x04\xed\x04\x040\x1a\x95\x02\x20This\ \x20is\x20incremented\x20every\x20time\x20the\x20workflow\x20starts\x20o\ r\x20resets.\x20Effectively\x20it\x20will\x20be\n\x20incremented\x20when\ \x20the\x20workflow\x20is\x20delivered,\x20and\x20every\x20time\x20it\ \x20is\x20reset\x20to\x20the\x20initial\x20state.\n\x20We\x20reuse\x20th\ e\x20existing\x20WorkflowTransitionDebugData\x20message\x20and\x20leave\ - \x20the\x20transition_type\n\x20unset.\n\n\x0f\n\x07\x04\x1a\x03\x02\x02\ - \x01\x06\x12\x04\xd5\x04\x04\x1f\n\x0f\n\x07\x04\x1a\x03\x02\x02\x01\x01\ - \x12\x04\xd5\x04\x20+\n\x0f\n\x07\x04\x1a\x03\x02\x02\x01\x03\x12\x04\ - \xd5\x04./\n\x9a\x01\n\x04\x04\x1a\x02\0\x12\x04\xda\x04\x029\x1a\x8b\ + \x20the\x20transition_type\n\x20unset.\n\n\x0f\n\x07\x04\x1b\x03\x02\x02\ + \x01\x06\x12\x04\xed\x04\x04\x1f\n\x0f\n\x07\x04\x1b\x03\x02\x02\x01\x01\ + \x12\x04\xed\x04\x20+\n\x0f\n\x07\x04\x1b\x03\x02\x02\x01\x03\x12\x04\ + \xed\x04./\n\x9a\x01\n\x04\x04\x1b\x02\0\x12\x04\xf2\x04\x029\x1a\x8b\ \x01\x20If\x20instructed\x20to\x20debug\x20workflows,\x20this\x20will\ \x20contain\x20the\x20debug\x20data\x20for\x20each\x20workflow\x20being\ \n\x20debugged.\x20This\x20is\x20map\x20of\x20workflow\x20ID\x20to\x20da\ - ta.\n\n\r\n\x05\x04\x1a\x02\0\x06\x12\x04\xda\x04\x02\x20\n\r\n\x05\x04\ - \x1a\x02\0\x01\x12\x04\xda\x04!4\n\r\n\x05\x04\x1a\x02\0\x03\x12\x04\xda\ - \x0478\nB\n\x02\x04\x1b\x12\x06\xde\x04\0\xf3\x04\x01\x1a4\x20A\x20multi\ - plexed\x20response\x20sent\x20over\x20the\x20bitdrift\x20API.\n\n\x0b\n\ - \x03\x04\x1b\x01\x12\x04\xde\x04\x08\x13\n\x0e\n\x04\x04\x1b\x08\0\x12\ - \x06\xdf\x04\x02\xef\x04\x03\n\r\n\x05\x04\x1b\x08\0\x01\x12\x04\xdf\x04\ - \x08\x15\n\r\n\x05\x04\x1b\x08\0\x02\x12\x04\xe0\x04\x04&\n\x0f\n\x07\ - \x04\x1b\x08\0\x02\xaf\x08\x12\x04\xe0\x04\x04&\n\x0c\n\x04\x04\x1b\x02\ - \0\x12\x04\xe2\x04\x04$\n\r\n\x05\x04\x1b\x02\0\x06\x12\x04\xe2\x04\x04\ - \x15\n\r\n\x05\x04\x1b\x02\0\x01\x12\x04\xe2\x04\x16\x1f\n\r\n\x05\x04\ - \x1b\x02\0\x03\x12\x04\xe2\x04\"#\n\x0c\n\x04\x04\x1b\x02\x01\x12\x04\ - \xe3\x04\x04%\n\r\n\x05\x04\x1b\x02\x01\x06\x12\x04\xe3\x04\x04\x15\n\r\ - \n\x05\x04\x1b\x02\x01\x01\x12\x04\xe3\x04\x16\x20\n\r\n\x05\x04\x1b\x02\ - \x01\x03\x12\x04\xe3\x04#$\n\x0c\n\x04\x04\x1b\x02\x02\x12\x04\xe4\x04\ - \x042\n\r\n\x05\x04\x1b\x02\x02\x06\x12\x04\xe4\x04\x04\x1b\n\r\n\x05\ - \x04\x1b\x02\x02\x01\x12\x04\xe4\x04\x1c-\n\r\n\x05\x04\x1b\x02\x02\x03\ - \x12\x04\xe4\x0401\n\x0c\n\x04\x04\x1b\x02\x03\x12\x04\xe5\x04\x04)\n\r\ - \n\x05\x04\x1b\x02\x03\x06\x12\x04\xe5\x04\x04\x17\n\r\n\x05\x04\x1b\x02\ - \x03\x01\x12\x04\xe5\x04\x18$\n\r\n\x05\x04\x1b\x02\x03\x03\x12\x04\xe5\ - \x04'(\n\x0c\n\x04\x04\x1b\x02\x04\x12\x04\xe6\x04\x04\x1a\n\r\n\x05\x04\ - \x1b\x02\x04\x06\x12\x04\xe6\x04\x04\x10\n\r\n\x05\x04\x1b\x02\x04\x01\ - \x12\x04\xe6\x04\x11\x15\n\r\n\x05\x04\x1b\x02\x04\x03\x12\x04\xe6\x04\ - \x18\x19\n\x0c\n\x04\x04\x1b\x02\x05\x12\x04\xe7\x04\x041\n\r\n\x05\x04\ - \x1b\x02\x05\x06\x12\x04\xe7\x04\x04\x17\n\r\n\x05\x04\x1b\x02\x05\x01\ - \x12\x04\xe7\x04\x18,\n\r\n\x05\x04\x1b\x02\x05\x03\x12\x04\xe7\x04/0\n\ - \x0c\n\x04\x04\x1b\x02\x06\x12\x04\xe8\x04\x04%\n\r\n\x05\x04\x1b\x02\ - \x06\x06\x12\x04\xe8\x04\x04\x11\n\r\n\x05\x04\x1b\x02\x06\x01\x12\x04\ - \xe8\x04\x12\x20\n\r\n\x05\x04\x1b\x02\x06\x03\x12\x04\xe8\x04#$\n\x0c\n\ - \x04\x04\x1b\x02\x07\x12\x04\xe9\x04\x04%\n\r\n\x05\x04\x1b\x02\x07\x06\ - \x12\x04\xe9\x04\x04\x11\n\r\n\x05\x04\x1b\x02\x07\x01\x12\x04\xe9\x04\ - \x12\x20\n\r\n\x05\x04\x1b\x02\x07\x03\x12\x04\xe9\x04#$\n\x0c\n\x04\x04\ - \x1b\x02\x08\x12\x04\xea\x04\x04#\n\r\n\x05\x04\x1b\x02\x08\x06\x12\x04\ - \xea\x04\x04\x10\n\r\n\x05\x04\x1b\x02\x08\x01\x12\x04\xea\x04\x11\x1e\n\ - \r\n\x05\x04\x1b\x02\x08\x03\x12\x04\xea\x04!\"\n\x0c\n\x04\x04\x1b\x02\ - \t\x12\x04\xeb\x04\x048\n\r\n\x05\x04\x1b\x02\t\x06\x12\x04\xeb\x04\x04\ - \x1c\n\r\n\x05\x04\x1b\x02\t\x01\x12\x04\xeb\x04\x1d2\n\r\n\x05\x04\x1b\ - \x02\t\x03\x12\x04\xeb\x0457\n\x0c\n\x04\x04\x1b\x02\n\x12\x04\xec\x04\ - \x045\n\r\n\x05\x04\x1b\x02\n\x06\x12\x04\xec\x04\x04\x18\n\r\n\x05\x04\ - \x1b\x02\n\x01\x12\x04\xec\x04\x19/\n\r\n\x05\x04\x1b\x02\n\x03\x12\x04\ - \xec\x0424\n\x0c\n\x04\x04\x1b\x02\x0b\x12\x04\xed\x04\x040\n\r\n\x05\ - \x04\x1b\x02\x0b\x06\x12\x04\xed\x04\x04\x1a\n\r\n\x05\x04\x1b\x02\x0b\ - \x01\x12\x04\xed\x04\x1b*\n\r\n\x05\x04\x1b\x02\x0b\x03\x12\x04\xed\x04-\ - /\n\x0c\n\x04\x04\x1b\x02\x0c\x12\x04\xee\x04\x046\n\r\n\x05\x04\x1b\x02\ - \x0c\x06\x12\x04\xee\x04\x04\x20\n\r\n\x05\x04\x1b\x02\x0c\x01\x12\x04\ - \xee\x04!0\n\r\n\x05\x04\x1b\x02\x0c\x03\x12\x04\xee\x0435\n\x0b\n\x03\ - \x04\x1b\t\x12\x04\xf1\x04\x02\x0e\n\x0c\n\x04\x04\x1b\t\0\x12\x04\xf1\ - \x04\x0b\r\n\r\n\x05\x04\x1b\t\0\x01\x12\x04\xf1\x04\x0b\r\n\r\n\x05\x04\ - \x1b\t\0\x02\x12\x04\xf1\x04\x0b\r\n\x0b\n\x03\x04\x1b\t\x12\x04\xf2\x04\ - \x02\x0e\n\x0c\n\x04\x04\x1b\t\x01\x12\x04\xf2\x04\x0b\r\n\r\n\x05\x04\ - \x1b\t\x01\x01\x12\x04\xf2\x04\x0b\r\n\r\n\x05\x04\x1b\t\x01\x02\x12\x04\ - \xf2\x04\x0b\r\n\x0c\n\x02\x06\0\x12\x06\xf5\x04\0\xf7\x04\x01\n\x0b\n\ - \x03\x06\0\x01\x12\x04\xf5\x04\x08\x12\n\x0c\n\x04\x06\0\x02\0\x12\x04\ - \xf6\x04\x02:\n\r\n\x05\x06\0\x02\0\x01\x12\x04\xf6\x04\x06\t\n\r\n\x05\ - \x06\0\x02\0\x05\x12\x04\xf6\x04\n\x10\n\r\n\x05\x06\0\x02\0\x02\x12\x04\ - \xf6\x04\x11\x1b\n\r\n\x05\x06\0\x02\0\x06\x12\x04\xf6\x04&,\n\r\n\x05\ - \x06\0\x02\0\x03\x12\x04\xf6\x04-8b\x06proto3\ + ta.\n\n\r\n\x05\x04\x1b\x02\0\x06\x12\x04\xf2\x04\x02\x20\n\r\n\x05\x04\ + \x1b\x02\0\x01\x12\x04\xf2\x04!4\n\r\n\x05\x04\x1b\x02\0\x03\x12\x04\xf2\ + \x0478\n\n\n\x02\x04\x1c\x12\x04\xf5\x04\0\x1e\n\x0b\n\x03\x04\x1c\x01\ + \x12\x04\xf5\x04\x08\x1b\nB\n\x02\x04\x1d\x12\x06\xf8\x04\0\x8e\x05\x01\ + \x1a4\x20A\x20multiplexed\x20response\x20sent\x20over\x20the\x20bitdrift\ + \x20API.\n\n\x0b\n\x03\x04\x1d\x01\x12\x04\xf8\x04\x08\x13\n\x0e\n\x04\ + \x04\x1d\x08\0\x12\x06\xf9\x04\x02\x8a\x05\x03\n\r\n\x05\x04\x1d\x08\0\ + \x01\x12\x04\xf9\x04\x08\x15\n\r\n\x05\x04\x1d\x08\0\x02\x12\x04\xfa\x04\ + \x04&\n\x0f\n\x07\x04\x1d\x08\0\x02\xaf\x08\x12\x04\xfa\x04\x04&\n\x0c\n\ + \x04\x04\x1d\x02\0\x12\x04\xfc\x04\x04$\n\r\n\x05\x04\x1d\x02\0\x06\x12\ + \x04\xfc\x04\x04\x15\n\r\n\x05\x04\x1d\x02\0\x01\x12\x04\xfc\x04\x16\x1f\ + \n\r\n\x05\x04\x1d\x02\0\x03\x12\x04\xfc\x04\"#\n\x0c\n\x04\x04\x1d\x02\ + \x01\x12\x04\xfd\x04\x04%\n\r\n\x05\x04\x1d\x02\x01\x06\x12\x04\xfd\x04\ + \x04\x15\n\r\n\x05\x04\x1d\x02\x01\x01\x12\x04\xfd\x04\x16\x20\n\r\n\x05\ + \x04\x1d\x02\x01\x03\x12\x04\xfd\x04#$\n\x0c\n\x04\x04\x1d\x02\x02\x12\ + \x04\xfe\x04\x042\n\r\n\x05\x04\x1d\x02\x02\x06\x12\x04\xfe\x04\x04\x1b\ + \n\r\n\x05\x04\x1d\x02\x02\x01\x12\x04\xfe\x04\x1c-\n\r\n\x05\x04\x1d\ + \x02\x02\x03\x12\x04\xfe\x0401\n\x0c\n\x04\x04\x1d\x02\x03\x12\x04\xff\ + \x04\x04)\n\r\n\x05\x04\x1d\x02\x03\x06\x12\x04\xff\x04\x04\x17\n\r\n\ + \x05\x04\x1d\x02\x03\x01\x12\x04\xff\x04\x18$\n\r\n\x05\x04\x1d\x02\x03\ + \x03\x12\x04\xff\x04'(\n\x0c\n\x04\x04\x1d\x02\x04\x12\x04\x80\x05\x04\ + \x1a\n\r\n\x05\x04\x1d\x02\x04\x06\x12\x04\x80\x05\x04\x10\n\r\n\x05\x04\ + \x1d\x02\x04\x01\x12\x04\x80\x05\x11\x15\n\r\n\x05\x04\x1d\x02\x04\x03\ + \x12\x04\x80\x05\x18\x19\n\x0c\n\x04\x04\x1d\x02\x05\x12\x04\x81\x05\x04\ + 1\n\r\n\x05\x04\x1d\x02\x05\x06\x12\x04\x81\x05\x04\x17\n\r\n\x05\x04\ + \x1d\x02\x05\x01\x12\x04\x81\x05\x18,\n\r\n\x05\x04\x1d\x02\x05\x03\x12\ + \x04\x81\x05/0\n\x0c\n\x04\x04\x1d\x02\x06\x12\x04\x82\x05\x04%\n\r\n\ + \x05\x04\x1d\x02\x06\x06\x12\x04\x82\x05\x04\x11\n\r\n\x05\x04\x1d\x02\ + \x06\x01\x12\x04\x82\x05\x12\x20\n\r\n\x05\x04\x1d\x02\x06\x03\x12\x04\ + \x82\x05#$\n\x0c\n\x04\x04\x1d\x02\x07\x12\x04\x83\x05\x04%\n\r\n\x05\ + \x04\x1d\x02\x07\x06\x12\x04\x83\x05\x04\x11\n\r\n\x05\x04\x1d\x02\x07\ + \x01\x12\x04\x83\x05\x12\x20\n\r\n\x05\x04\x1d\x02\x07\x03\x12\x04\x83\ + \x05#$\n\x0c\n\x04\x04\x1d\x02\x08\x12\x04\x84\x05\x04#\n\r\n\x05\x04\ + \x1d\x02\x08\x06\x12\x04\x84\x05\x04\x10\n\r\n\x05\x04\x1d\x02\x08\x01\ + \x12\x04\x84\x05\x11\x1e\n\r\n\x05\x04\x1d\x02\x08\x03\x12\x04\x84\x05!\ + \"\n\x0c\n\x04\x04\x1d\x02\t\x12\x04\x85\x05\x048\n\r\n\x05\x04\x1d\x02\ + \t\x06\x12\x04\x85\x05\x04\x1c\n\r\n\x05\x04\x1d\x02\t\x01\x12\x04\x85\ + \x05\x1d2\n\r\n\x05\x04\x1d\x02\t\x03\x12\x04\x85\x0557\n\x0c\n\x04\x04\ + \x1d\x02\n\x12\x04\x86\x05\x045\n\r\n\x05\x04\x1d\x02\n\x06\x12\x04\x86\ + \x05\x04\x18\n\r\n\x05\x04\x1d\x02\n\x01\x12\x04\x86\x05\x19/\n\r\n\x05\ + \x04\x1d\x02\n\x03\x12\x04\x86\x0524\n\x0c\n\x04\x04\x1d\x02\x0b\x12\x04\ + \x87\x05\x040\n\r\n\x05\x04\x1d\x02\x0b\x06\x12\x04\x87\x05\x04\x1a\n\r\ + \n\x05\x04\x1d\x02\x0b\x01\x12\x04\x87\x05\x1b*\n\r\n\x05\x04\x1d\x02\ + \x0b\x03\x12\x04\x87\x05-/\n\x0c\n\x04\x04\x1d\x02\x0c\x12\x04\x88\x05\ + \x046\n\r\n\x05\x04\x1d\x02\x0c\x06\x12\x04\x88\x05\x04\x20\n\r\n\x05\ + \x04\x1d\x02\x0c\x01\x12\x04\x88\x05!0\n\r\n\x05\x04\x1d\x02\x0c\x03\x12\ + \x04\x88\x0535\n\x0c\n\x04\x04\x1d\x02\r\x12\x04\x89\x05\x04*\n\r\n\x05\ + \x04\x1d\x02\r\x06\x12\x04\x89\x05\x04\x17\n\r\n\x05\x04\x1d\x02\r\x01\ + \x12\x04\x89\x05\x18$\n\r\n\x05\x04\x1d\x02\r\x03\x12\x04\x89\x05')\n\ + \x0b\n\x03\x04\x1d\t\x12\x04\x8c\x05\x02\x0e\n\x0c\n\x04\x04\x1d\t\0\x12\ + \x04\x8c\x05\x0b\r\n\r\n\x05\x04\x1d\t\0\x01\x12\x04\x8c\x05\x0b\r\n\r\n\ + \x05\x04\x1d\t\0\x02\x12\x04\x8c\x05\x0b\r\n\x0b\n\x03\x04\x1d\t\x12\x04\ + \x8d\x05\x02\x0e\n\x0c\n\x04\x04\x1d\t\x01\x12\x04\x8d\x05\x0b\r\n\r\n\ + \x05\x04\x1d\t\x01\x01\x12\x04\x8d\x05\x0b\r\n\r\n\x05\x04\x1d\t\x01\x02\ + \x12\x04\x8d\x05\x0b\r\n\x0c\n\x02\x06\0\x12\x06\x90\x05\0\x92\x05\x01\n\ + \x0b\n\x03\x06\0\x01\x12\x04\x90\x05\x08\x12\n\x0c\n\x04\x06\0\x02\0\x12\ + \x04\x91\x05\x02:\n\r\n\x05\x06\0\x02\0\x01\x12\x04\x91\x05\x06\t\n\r\n\ + \x05\x06\0\x02\0\x05\x12\x04\x91\x05\n\x10\n\r\n\x05\x06\0\x02\0\x02\x12\ + \x04\x91\x05\x11\x1b\n\r\n\x05\x06\0\x02\0\x06\x12\x04\x91\x05&,\n\r\n\ + \x05\x06\0\x02\0\x03\x12\x04\x91\x05-8b\x06proto3\ "; /// `FileDescriptorProto` object which was a source for this generated file @@ -10882,8 +11614,9 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { deps.push(::protobuf::well_known_types::duration::file_descriptor().clone()); deps.push(::protobuf::well_known_types::timestamp::file_descriptor().clone()); deps.push(super::validate::file_descriptor().clone()); - let mut messages = ::std::vec::Vec::with_capacity(45); + let mut messages = ::std::vec::Vec::with_capacity(49); messages.push(ClientKillFile::generated_message_descriptor_data()); + messages.push(StateUpdateRequest::generated_message_descriptor_data()); messages.push(HandshakeRequest::generated_message_descriptor_data()); messages.push(LogUploadIntentRequest::generated_message_descriptor_data()); messages.push(LogUploadIntentResponse::generated_message_descriptor_data()); @@ -10910,7 +11643,10 @@ pub fn file_descriptor() -> &'static ::protobuf::reflect::FileDescriptor { messages.push(SankeyPathUploadResponse::generated_message_descriptor_data()); messages.push(SankeyIntentResponse::generated_message_descriptor_data()); messages.push(DebugDataRequest::generated_message_descriptor_data()); + messages.push(StateUpdateResponse::generated_message_descriptor_data()); messages.push(ApiResponse::generated_message_descriptor_data()); + messages.push(state_update_request::StartedSession::generated_message_descriptor_data()); + messages.push(state_update_request::OpaqueEntityUpdate::generated_message_descriptor_data()); messages.push(log_upload_intent_request::WorkflowActionUpload::generated_message_descriptor_data()); messages.push(log_upload_intent_request::ExplicitSessionCapture::generated_message_descriptor_data()); messages.push(log_upload_intent_response::UploadImmediately::generated_message_descriptor_data()); diff --git a/bd-proto/src/protos/workflow/with_source/workflow.rs b/bd-proto/src/protos/workflow/with_source/workflow.rs index 69739ff54..8793831d2 100644 --- a/bd-proto/src/protos/workflow/with_source/workflow.rs +++ b/bd-proto/src/protos/workflow/with_source/workflow.rs @@ -1007,8 +1007,33 @@ pub mod workflow { } } + // bool on_new_session = 4; + + pub fn on_new_session(&self) -> bool { + match self.rule_type { + ::std::option::Option::Some(rule::Rule_type::OnNewSession(v)) => v, + _ => false, + } + } + + pub fn clear_on_new_session(&mut self) { + self.rule_type = ::std::option::Option::None; + } + + pub fn has_on_new_session(&self) -> bool { + match self.rule_type { + ::std::option::Option::Some(rule::Rule_type::OnNewSession(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_on_new_session(&mut self, v: bool) { + self.rule_type = ::std::option::Option::Some(rule::Rule_type::OnNewSession(v)) + } + pub(in super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(2); + let mut fields = ::std::vec::Vec::with_capacity(3); let mut oneofs = ::std::vec::Vec::with_capacity(1); fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, RuleLogMatch>( "rule_log_match", @@ -1024,6 +1049,12 @@ pub mod workflow { Rule::mut_rule_state_change_match, Rule::set_rule_state_change_match, )); + fields.push(::protobuf::reflect::rt::v2::make_oneof_copy_has_get_set_simpler_accessors::<_, _>( + "on_new_session", + Rule::has_on_new_session, + Rule::on_new_session, + Rule::set_on_new_session, + )); oneofs.push(rule::Rule_type::generated_oneof_descriptor_data()); ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( "Workflow.Rule", @@ -1049,6 +1080,9 @@ pub mod workflow { 26 => { self.rule_type = ::std::option::Option::Some(rule::Rule_type::RuleStateChangeMatch(is.read_message()?)); }, + 32 => { + self.rule_type = ::std::option::Option::Some(rule::Rule_type::OnNewSession(is.read_bool()?)); + }, tag => { ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; }, @@ -1071,6 +1105,9 @@ pub mod workflow { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; }, + &rule::Rule_type::OnNewSession(v) => { + my_size += 1 + 1; + }, }; } my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); @@ -1087,6 +1124,9 @@ pub mod workflow { &rule::Rule_type::RuleStateChangeMatch(ref v) => { ::protobuf::rt::write_message_field_with_cached_size(3, v, os)?; }, + &rule::Rule_type::OnNewSession(v) => { + os.write_bool(4, v)?; + }, }; } os.write_unknown_fields(self.special_fields.unknown_fields())?; @@ -1106,6 +1146,7 @@ pub mod workflow { } fn clear(&mut self) { + self.rule_type = ::std::option::Option::None; self.rule_type = ::std::option::Option::None; self.rule_type = ::std::option::Option::None; self.special_fields.clear(); @@ -1147,6 +1188,8 @@ pub mod workflow { RuleLogMatch(super::RuleLogMatch), // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.workflow.v1.Workflow.Rule.rule_state_change_match) RuleStateChangeMatch(super::RuleStateChangeMatch), + // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.workflow.v1.Workflow.Rule.on_new_session) + OnNewSession(bool), } impl ::protobuf::Oneof for Rule_type { @@ -7716,7 +7759,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ft_public/protobuf/state/v1/scope.proto\x1a5bitdrift_public/protobuf/wor\ kflow/v1/save_field.proto\x1a\x17validate/validate.proto\"f\n\x16Workflo\ wsConfiguration\x12L\n\tworkflows\x18\x01\x20\x03(\x0b2..bitdrift_public\ - .protobuf.workflow.v1.WorkflowR\tworkflows\"\xf3;\n\x08Workflow\x12\x17\ + .protobuf.workflow.v1.WorkflowR\tworkflows\"\x9b<\n\x08Workflow\x12\x17\ \n\x02id\x18\x01\x20\x01(\tR\x02idB\x07\xfaB\x04r\x02\x10\x01\x12V\n\x06\ states\x18\x02\x20\x03(\x0b24.bitdrift_public.protobuf.workflow.v1.Workf\ low.StateR\x06statesB\x08\xfaB\x05\x92\x01\x02\x08\x01\x12V\n\texecution\ @@ -7740,32 +7783,33 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x08\xfaB\x05\x8a\x01\x02\x10\x01\x12O\n\x07actions\x18\x03\x20\x03(\x0b\ 25.bitdrift_public.protobuf.workflow.v1.Workflow.ActionR\x07actions\x12b\ \n\nextensions\x18\x04\x20\x03(\x0b2B.bitdrift_public.protobuf.workflow.\ - v1.Workflow.TransitionExtensionR\nextensions\x1a\x81\x02\n\x04Rule\x12c\ + v1.Workflow.TransitionExtensionR\nextensions\x1a\xa9\x02\n\x04Rule\x12c\ \n\x0erule_log_match\x18\x01\x20\x01(\x0b2;.bitdrift_public.protobuf.wor\ kflow.v1.Workflow.RuleLogMatchH\0R\x0cruleLogMatch\x12|\n\x17rule_state_\ change_match\x18\x03\x20\x01(\x0b2C.bitdrift_public.protobuf.workflow.v1\ - .Workflow.RuleStateChangeMatchH\0R\x14ruleStateChangeMatchB\x10\n\trule_\ - type\x12\x03\xf8B\x01J\x04\x08\x02\x10\x03\x1a\x8b\x06\n\x13TransitionEx\ - tension\x12\xa8\x01\n\x1fsankey_diagram_value_extraction\x18\x01\x20\x01\ - (\x0b2_.bitdrift_public.protobuf.workflow.v1.Workflow.TransitionExtensio\ - n.SankeyDiagramValueExtractionH\0R\x1csankeyDiagramValueExtraction\x12y\ - \n\x0esave_timestamp\x18\x02\x20\x01(\x0b2P.bitdrift_public.protobuf.wor\ - kflow.v1.Workflow.TransitionExtension.SaveTimestampH\0R\rsaveTimestamp\ - \x12P\n\nsave_field\x18\x03\x20\x01(\x0b2/.bitdrift_public.protobuf.work\ - flow.v1.SaveFieldH\0R\tsaveField\x1a\x1f\n\rSaveTimestamp\x12\x0e\n\x02i\ - d\x18\x01\x20\x01(\tR\x02id\x1a\xc3\x02\n\x1cSankeyDiagramValueExtractio\ - n\x123\n\x11sankey_diagram_id\x18\x01\x20\x01(\tR\x0fsankeyDiagramIdB\ - \x07\xfaB\x04r\x02\x10\x01\x12\x1f\n\x05fixed\x18\x02\x20\x01(\tH\0R\x05\ - fixedB\x07\xfaB\x04r\x02\x10\x01\x12h\n\x0ffield_extracted\x18\x03\x20\ - \x01(\x0b2=.bitdrift_public.protobuf.workflow.v1.Workflow.FieldExtracted\ - H\0R\x0efieldExtracted\x12P\n%counts_toward_sankey_extraction_limit\x18\ - \x04\x20\x01(\x08R!countsTowardSankeyExtractionLimitB\x11\n\nvalue_type\ - \x12\x03\xf8B\x01B\x15\n\x0eextension_type\x12\x03\xf8B\x01\x1a\x89\x01\ - \n\x0cRuleLogMatch\x12Z\n\x0blog_matcher\x18\x01\x20\x01(\x0b2/.bitdrift\ - _public.protobuf.matcher.v1.LogMatcherR\nlogMatcherB\x08\xfaB\x05\x8a\ - \x01\x02\x10\x01\x12\x1d\n\x05count\x18\x02\x20\x01(\rR\x05countB\x07\ - \xfaB\x04*\x02\x20\0\x1a\x88\x03\n\x14RuleStateChangeMatch\x12M\n\x05sco\ - pe\x18\x01\x20\x01(\x0e2-.bitdrift_public.protobuf.state.v1.StateScopeR\ + .Workflow.RuleStateChangeMatchH\0R\x14ruleStateChangeMatch\x12&\n\x0eon_\ + new_session\x18\x04\x20\x01(\x08H\0R\x0conNewSessionB\x10\n\trule_type\ + \x12\x03\xf8B\x01J\x04\x08\x02\x10\x03\x1a\x8b\x06\n\x13TransitionExtens\ + ion\x12\xa8\x01\n\x1fsankey_diagram_value_extraction\x18\x01\x20\x01(\ + \x0b2_.bitdrift_public.protobuf.workflow.v1.Workflow.TransitionExtension\ + .SankeyDiagramValueExtractionH\0R\x1csankeyDiagramValueExtraction\x12y\n\ + \x0esave_timestamp\x18\x02\x20\x01(\x0b2P.bitdrift_public.protobuf.workf\ + low.v1.Workflow.TransitionExtension.SaveTimestampH\0R\rsaveTimestamp\x12\ + P\n\nsave_field\x18\x03\x20\x01(\x0b2/.bitdrift_public.protobuf.workflow\ + .v1.SaveFieldH\0R\tsaveField\x1a\x1f\n\rSaveTimestamp\x12\x0e\n\x02id\ + \x18\x01\x20\x01(\tR\x02id\x1a\xc3\x02\n\x1cSankeyDiagramValueExtraction\ + \x123\n\x11sankey_diagram_id\x18\x01\x20\x01(\tR\x0fsankeyDiagramIdB\x07\ + \xfaB\x04r\x02\x10\x01\x12\x1f\n\x05fixed\x18\x02\x20\x01(\tH\0R\x05fixe\ + dB\x07\xfaB\x04r\x02\x10\x01\x12h\n\x0ffield_extracted\x18\x03\x20\x01(\ + \x0b2=.bitdrift_public.protobuf.workflow.v1.Workflow.FieldExtractedH\0R\ + \x0efieldExtracted\x12P\n%counts_toward_sankey_extraction_limit\x18\x04\ + \x20\x01(\x08R!countsTowardSankeyExtractionLimitB\x11\n\nvalue_type\x12\ + \x03\xf8B\x01B\x15\n\x0eextension_type\x12\x03\xf8B\x01\x1a\x89\x01\n\ + \x0cRuleLogMatch\x12Z\n\x0blog_matcher\x18\x01\x20\x01(\x0b2/.bitdrift_p\ + ublic.protobuf.matcher.v1.LogMatcherR\nlogMatcherB\x08\xfaB\x05\x8a\x01\ + \x02\x10\x01\x12\x1d\n\x05count\x18\x02\x20\x01(\rR\x05countB\x07\xfaB\ + \x04*\x02\x20\0\x1a\x88\x03\n\x14RuleStateChangeMatch\x12M\n\x05scope\ + \x18\x01\x20\x01(\x0e2-.bitdrift_public.protobuf.state.v1.StateScopeR\ \x05scopeB\x08\xfaB\x05\x82\x01\x02\x10\x01\x12\x19\n\x03key\x18\x02\x20\ \x01(\tR\x03keyB\x07\xfaB\x04r\x02\x10\x01\x12Y\n\x0eprevious_value\x18\ \x03\x20\x01(\x0b22.bitdrift_public.protobuf.state.v1.StateValueMatchR\r\ @@ -7870,7 +7914,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ y\x18\x02\x20\x01(\tR\x03keyB\x07\xfaB\x04r\x02\x10\x01\x12[\n\x05exact\ \x18\x03\x20\x01(\x0b2C.bitdrift_public.protobuf.workflow.v1.Workflow.St\ ateExtracted.ExactH\0R\x05exact\x1a\x07\n\x05ExactB\x11\n\x0fextraction_\ - typeJ\xbb\xa8\x01\n\x07\x12\x05\x07\0\xd3\x03\x01\n\xb8\x02\n\x01\x0c\ + typeJ\xad\xa9\x01\n\x07\x12\x05\x07\0\xd6\x03\x01\n\xb8\x02\n\x01\x0c\ \x12\x03\x07\0\x122\xad\x02\x20api\x20-\x20bitdrift's\x20client/server\ \x20API\x20definitions\n\x20Copyright\x20Bitdrift,\x20Inc.\x20All\x20rig\ hts\x20reserved.\n\n\x20Use\x20of\x20this\x20source\x20code\x20and\x20AP\ @@ -7888,7 +7932,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x20list\x20of\x20workflows.\n\n\x0c\n\x05\x04\0\x02\0\x04\x12\x03\x15\ \x02\n\n\x0c\n\x05\x04\0\x02\0\x06\x12\x03\x15\x0b\x13\n\x0c\n\x05\x04\0\ \x02\0\x01\x12\x03\x15\x14\x1d\n\x0c\n\x05\x04\0\x02\0\x03\x12\x03\x15\ - \x20!\n\xf9\x01\n\x02\x04\x01\x12\x05\x1b\0\xd3\x03\x01\x1a\xeb\x01\x20A\ + \x20!\n\xf9\x01\n\x02\x04\x01\x12\x05\x1b\0\xd6\x03\x01\x1a\xeb\x01\x20A\ \x20complete\x20workflow\x20configuration.\x20Each\x20traversal\x20of\ \x20the\x20state\x20machine\x20defined\n\x20by\x20the\x20configuration\ \x20is\x20called\x20a\x20*workflow\x20run*.\x20There\x20can\x20be\x20mul\ @@ -7997,439 +8041,444 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x07\x04\x01\x03\x02\x02\x03\x04\x12\x03S\x04\x0c\n\x0e\n\x07\x04\x01\ \x03\x02\x02\x03\x06\x12\x03S\r\x20\n\x0e\n\x07\x04\x01\x03\x02\x02\x03\ \x01\x12\x03S!+\n\x0e\n\x07\x04\x01\x03\x02\x02\x03\x03\x12\x03S./\nN\n\ - \x04\x04\x01\x03\x03\x12\x04W\x02_\x03\x1a@\x20A\x20predicate\x20that\ + \x04\x04\x01\x03\x03\x12\x04W\x02b\x03\x1a@\x20A\x20predicate\x20that\ \x20must\x20be\x20satisfied\x20for\x20a\x20transition\x20to\x20happen.\n\ \n\x0c\n\x05\x04\x01\x03\x03\x01\x12\x03W\n\x0e\n\x0e\n\x06\x04\x01\x03\ - \x03\x08\0\x12\x04X\x04\\\x05\n\x0e\n\x07\x04\x01\x03\x03\x08\0\x01\x12\ + \x03\x08\0\x12\x04X\x04_\x05\n\x0e\n\x07\x04\x01\x03\x03\x08\0\x01\x12\ \x03X\n\x13\n\x0e\n\x07\x04\x01\x03\x03\x08\0\x02\x12\x03Y\x06(\n\x10\n\ \t\x04\x01\x03\x03\x08\0\x02\xaf\x08\x12\x03Y\x06(\n\r\n\x06\x04\x01\x03\ - \x03\x02\0\x12\x03Z\x06&\n\x0e\n\x07\x04\x01\x03\x03\x02\0\x06\x12\x03Z\ - \x06\x12\n\x0e\n\x07\x04\x01\x03\x03\x02\0\x01\x12\x03Z\x13!\n\x0e\n\x07\ - \x04\x01\x03\x03\x02\0\x03\x12\x03Z$%\n\r\n\x06\x04\x01\x03\x03\x02\x01\ - \x12\x03[\x067\n\x0e\n\x07\x04\x01\x03\x03\x02\x01\x06\x12\x03[\x06\x1a\ - \n\x0e\n\x07\x04\x01\x03\x03\x02\x01\x01\x12\x03[\x1b2\n\x0e\n\x07\x04\ - \x01\x03\x03\x02\x01\x03\x12\x03[56\n\x0c\n\x05\x04\x01\x03\x03\t\x12\ - \x03^\x04\x0f\n\r\n\x06\x04\x01\x03\x03\t\0\x12\x03^\r\x0e\n\x0e\n\x07\ - \x04\x01\x03\x03\t\0\x01\x12\x03^\r\x0e\n\x0e\n\x07\x04\x01\x03\x03\t\0\ - \x02\x12\x03^\r\x0e\n?\n\x04\x04\x01\x03\x04\x12\x05b\x02\x85\x01\x03\ - \x1a0\x20An\x20extra\x20configuration\x20for\x20a\x20given\x20transition\ - .\n\n\x0c\n\x05\x04\x01\x03\x04\x01\x12\x03b\n\x1d\n\x0e\n\x06\x04\x01\ - \x03\x04\x08\0\x12\x04c\x04h\x05\n\x0e\n\x07\x04\x01\x03\x04\x08\0\x01\ - \x12\x03c\n\x18\n\x0e\n\x07\x04\x01\x03\x04\x08\0\x02\x12\x03d\x06(\n\ - \x10\n\t\x04\x01\x03\x04\x08\0\x02\xaf\x08\x12\x03d\x06(\n\r\n\x06\x04\ - \x01\x03\x04\x02\0\x12\x03e\x06G\n\x0e\n\x07\x04\x01\x03\x04\x02\0\x06\ - \x12\x03e\x06\"\n\x0e\n\x07\x04\x01\x03\x04\x02\0\x01\x12\x03e#B\n\x0e\n\ - \x07\x04\x01\x03\x04\x02\0\x03\x12\x03eEF\n\r\n\x06\x04\x01\x03\x04\x02\ - \x01\x12\x03f\x06'\n\x0e\n\x07\x04\x01\x03\x04\x02\x01\x06\x12\x03f\x06\ - \x13\n\x0e\n\x07\x04\x01\x03\x04\x02\x01\x01\x12\x03f\x14\"\n\x0e\n\x07\ - \x04\x01\x03\x04\x02\x01\x03\x12\x03f%&\n\r\n\x06\x04\x01\x03\x04\x02\ - \x02\x12\x03g\x06\x1f\n\x0e\n\x07\x04\x01\x03\x04\x02\x02\x06\x12\x03g\ - \x06\x0f\n\x0e\n\x07\x04\x01\x03\x04\x02\x02\x01\x12\x03g\x10\x1a\n\x0e\ - \n\x07\x04\x01\x03\x04\x02\x02\x03\x12\x03g\x1d\x1e\n\xdc\x01\n\x06\x04\ - \x01\x03\x04\x03\0\x12\x04m\x04o\x05\x1a\xcb\x01\x20The\x20timestamp\x20\ - of\x20the\x20transition\x20will\x20be\x20snapped,\x20and\x20persisted\ - \x20to\x20the\x20workflow\x20state.\x20This\n\x20can\x20be\x20looked\x20\ - up\x20by\x20ID\x20by\x20further\x20transitions.\x20The\x20saved\x20times\ - tamp\x20is\x20fraction\x20seconds\x20since\n\x20the\x20Unix\x20epoch.\n\ - \n\x0e\n\x07\x04\x01\x03\x04\x03\0\x01\x12\x03m\x0c\x19\n\x0f\n\x08\x04\ - \x01\x03\x04\x03\0\x02\0\x12\x03n\x06\x14\n\x10\n\t\x04\x01\x03\x04\x03\ - \0\x02\0\x05\x12\x03n\x06\x0c\n\x10\n\t\x04\x01\x03\x04\x03\0\x02\0\x01\ - \x12\x03n\r\x0f\n\x10\n\t\x04\x01\x03\x04\x03\0\x02\0\x03\x12\x03n\x12\ - \x13\nP\n\x06\x04\x01\x03\x04\x03\x01\x12\x05r\x04\x84\x01\x05\x1a?\x20T\ - he\x20configuration\x20of\x20a\x20value\x20extraction\x20for\x20a\x20San\ - key\x20diagram.\n\n\x0e\n\x07\x04\x01\x03\x04\x03\x01\x01\x12\x03r\x0c(\ - \nI\n\x08\x04\x01\x03\x04\x03\x01\x02\0\x12\x03t\x06L\x1a8\x20The\x20ID\ - \x20of\x20the\x20Sankey\x20diagram\x20to\x20extract\x20the\x20value\x20f\ - or.\n\n\x10\n\t\x04\x01\x03\x04\x03\x01\x02\0\x05\x12\x03t\x06\x0c\n\x10\ - \n\t\x04\x01\x03\x04\x03\x01\x02\0\x01\x12\x03t\r\x1e\n\x10\n\t\x04\x01\ - \x03\x04\x03\x01\x02\0\x03\x12\x03t!\"\n\x10\n\t\x04\x01\x03\x04\x03\x01\ - \x02\0\x08\x12\x03t#K\n\x13\n\x0c\x04\x01\x03\x04\x03\x01\x02\0\x08\xaf\ - \x08\x0e\x12\x03t$J\n9\n\x08\x04\x01\x03\x04\x03\x01\x08\0\x12\x04w\x06\ - \x7f\x07\x1a'\x20The\x20name\x20of\x20the\x20Sankey\x20diagram\x20state.\ - \n\n\x10\n\t\x04\x01\x03\x04\x03\x01\x08\0\x01\x12\x03w\x0c\x16\n\x10\n\ - \t\x04\x01\x03\x04\x03\x01\x08\0\x02\x12\x03x\x08*\n\x12\n\x0b\x04\x01\ - \x03\x04\x03\x01\x08\0\x02\xaf\x08\x12\x03x\x08*\n!\n\x08\x04\x01\x03\ - \x04\x03\x01\x02\x01\x12\x03{\x08B\x1a\x10\x20A\x20fixed\x20value.\n\n\ - \x10\n\t\x04\x01\x03\x04\x03\x01\x02\x01\x05\x12\x03{\x08\x0e\n\x10\n\t\ - \x04\x01\x03\x04\x03\x01\x02\x01\x01\x12\x03{\x0f\x14\n\x10\n\t\x04\x01\ - \x03\x04\x03\x01\x02\x01\x03\x12\x03{\x17\x18\n\x10\n\t\x04\x01\x03\x04\ - \x03\x01\x02\x01\x08\x12\x03{\x19A\n\x13\n\x0c\x04\x01\x03\x04\x03\x01\ - \x02\x01\x08\xaf\x08\x0e\x12\x03{\x1a@\n4\n\x08\x04\x01\x03\x04\x03\x01\ - \x02\x02\x12\x03~\x08+\x1a#\x20The\x20value\x20extracted\x20from\x20a\ - \x20field.\n\n\x10\n\t\x04\x01\x03\x04\x03\x01\x02\x02\x06\x12\x03~\x08\ - \x16\n\x10\n\t\x04\x01\x03\x04\x03\x01\x02\x02\x01\x12\x03~\x17&\n\x10\n\ - \t\x04\x01\x03\x04\x03\x01\x02\x02\x03\x12\x03~)*\n\xa4\x01\n\x08\x04\ - \x01\x03\x04\x03\x01\x02\x03\x12\x04\x83\x01\x065\x1a\x91\x01\x20Whether\ - \x20extracting\x20the\x20value\x20with\x20the\x20extension\x20counts\x20\ - toward\x20the\x20limit\x20of\x20the\x20extracted\x20values\n\x20defined\ - \x20on\x20a\x20given\x20emit\x20Sankey\x20diagram\x20action.\n\n\x11\n\t\ - \x04\x01\x03\x04\x03\x01\x02\x03\x05\x12\x04\x83\x01\x06\n\n\x11\n\t\x04\ - \x01\x03\x04\x03\x01\x02\x03\x01\x12\x04\x83\x01\x0b0\n\x11\n\t\x04\x01\ - \x03\x04\x03\x01\x02\x03\x03\x12\x04\x83\x0134\n9\n\x04\x04\x01\x03\x05\ - \x12\x06\x88\x01\x02\x8d\x01\x03\x1a)\x20Rule\x20used\x20to\x20transitio\ - n\x20based\x20on\x20a\x20log.\n\n\r\n\x05\x04\x01\x03\x05\x01\x12\x04\ - \x88\x01\n\x16\n8\n\x06\x04\x01\x03\x05\x02\0\x12\x04\x8a\x01\x04X\x1a(\ - \x20The\x20condition\x20that\x20a\x20log\x20must\x20satisfy.\n\n\x0f\n\ - \x07\x04\x01\x03\x05\x02\0\x06\x12\x04\x8a\x01\x04\x19\n\x0f\n\x07\x04\ - \x01\x03\x05\x02\0\x01\x12\x04\x8a\x01\x1a%\n\x0f\n\x07\x04\x01\x03\x05\ - \x02\0\x03\x12\x04\x8a\x01()\n\x0f\n\x07\x04\x01\x03\x05\x02\0\x08\x12\ - \x04\x8a\x01*W\n\x12\n\n\x04\x01\x03\x05\x02\0\x08\xaf\x08\x11\x12\x04\ - \x8a\x01+V\nR\n\x06\x04\x01\x03\x05\x02\x01\x12\x04\x8c\x01\x046\x1aB\ - \x20The\x20number\x20of\x20times\x20the\x20condition\x20needs\x20to\x20b\ - e\x20met,\x20default\x20is\x201.\n\n\x0f\n\x07\x04\x01\x03\x05\x02\x01\ - \x05\x12\x04\x8c\x01\x04\n\n\x0f\n\x07\x04\x01\x03\x05\x02\x01\x01\x12\ - \x04\x8c\x01\x0b\x10\n\x0f\n\x07\x04\x01\x03\x05\x02\x01\x03\x12\x04\x8c\ - \x01\x13\x14\n\x0f\n\x07\x04\x01\x03\x05\x02\x01\x08\x12\x04\x8c\x01\x15\ - 5\n\x13\n\x0b\x04\x01\x03\x05\x02\x01\x08\xaf\x08\x05\x04\x12\x04\x8c\ - \x01\x164\n\xe5\x01\n\x04\x04\x01\x03\x06\x12\x06\x91\x01\x02\xa1\x01\ - \x03\x1a\xd4\x01\x20Matches\x20against\x20a\x20state\x20change.\x20Every\ - \x20time\x20the\x20value\x20of\x20a\x20scoped\x20key\x20changes\x20(new\ - \x20value\x20is\x20different\x20from\x20previous\x20value),\n\x20the\x20\ - rule\x20evaluates\x20whether\x20the\x20previous\x20and\x20new\x20values\ - \x20match\x20the\x20specified\x20conditions.\n\n\r\n\x05\x04\x01\x03\x06\ - \x01\x12\x04\x91\x01\n\x1e\n6\n\x06\x04\x01\x03\x06\x02\0\x12\x04\x93\ - \x01\x04N\x1a&\x20The\x20scope\x20of\x20the\x20state\x20to\x20watch\x20f\ - or.\n\n\x0f\n\x07\x04\x01\x03\x06\x02\0\x06\x12\x04\x93\x01\x04\x17\n\ - \x0f\n\x07\x04\x01\x03\x06\x02\0\x01\x12\x04\x93\x01\x18\x1d\n\x0f\n\x07\ - \x04\x01\x03\x06\x02\0\x03\x12\x04\x93\x01\x20!\n\x0f\n\x07\x04\x01\x03\ - \x06\x02\0\x08\x12\x04\x93\x01\"M\n\x13\n\x0b\x04\x01\x03\x06\x02\0\x08\ - \xaf\x08\x10\x02\x12\x04\x93\x01#L\n4\n\x06\x04\x01\x03\x06\x02\x01\x12\ - \x04\x96\x01\x04<\x1a$\x20The\x20key\x20of\x20the\x20state\x20to\x20watc\ - h\x20for.\n\n\x0f\n\x07\x04\x01\x03\x06\x02\x01\x05\x12\x04\x96\x01\x04\ - \n\n\x0f\n\x07\x04\x01\x03\x06\x02\x01\x01\x12\x04\x96\x01\x0b\x0e\n\x0f\ - \n\x07\x04\x01\x03\x06\x02\x01\x03\x12\x04\x96\x01\x11\x12\n\x0f\n\x07\ - \x04\x01\x03\x06\x02\x01\x08\x12\x04\x96\x01\x13;\n\x12\n\n\x04\x01\x03\ - \x06\x02\x01\x08\xaf\x08\x0e\x12\x04\x96\x01\x14:\np\n\x06\x04\x01\x03\ - \x06\x02\x02\x12\x04\x99\x01\x040\x1a`\x20The\x20match\x20condition\x20w\ - hich\x20is\x20applied\x20to\x20the\x20previous\x20value\x20of\x20the\x20\ - state\x20during\x20a\x20state\x20change.\n\n\x0f\n\x07\x04\x01\x03\x06\ - \x02\x02\x06\x12\x04\x99\x01\x04\x1c\n\x0f\n\x07\x04\x01\x03\x06\x02\x02\ - \x01\x12\x04\x99\x01\x1d+\n\x0f\n\x07\x04\x01\x03\x06\x02\x02\x03\x12\ - \x04\x99\x01./\nk\n\x06\x04\x01\x03\x06\x02\x03\x12\x04\x9c\x01\x04Y\x1a\ - [\x20The\x20match\x20condition\x20which\x20is\x20applied\x20to\x20the\ - \x20new\x20value\x20of\x20the\x20state\x20during\x20a\x20state\x20change\ - .\n\n\x0f\n\x07\x04\x01\x03\x06\x02\x03\x06\x12\x04\x9c\x01\x04\x1c\n\ - \x0f\n\x07\x04\x01\x03\x06\x02\x03\x01\x12\x04\x9c\x01\x1d&\n\x0f\n\x07\ - \x04\x01\x03\x06\x02\x03\x03\x12\x04\x9c\x01)*\n\x0f\n\x07\x04\x01\x03\ - \x06\x02\x03\x08\x12\x04\x9c\x01+X\n\x12\n\n\x04\x01\x03\x06\x02\x03\x08\ - \xaf\x08\x11\x12\x04\x9c\x01,W\n\xe5\x01\n\x06\x04\x01\x03\x06\x02\x04\ - \x12\x04\xa0\x01\x04*\x1a\xd4\x01\x20Additional\x20properties\x20that\ - \x20must\x20be\x20true\x20at\x20the\x20time\x20of\x20the\x20state\x20cha\ - nge\x20for\x20the\x20rule\x20to\x20match.\n\x20Since\x20state\x20changes\ - \x20do\x20not\x20match\x20against\x20a\x20particular\x20log,\x20tags\x20\ - and\x20messages\x20will\x20not\x20be\x20visibile\x20to\x20this\x20matche\ - r.\n\n\x0f\n\x07\x04\x01\x03\x06\x02\x04\x06\x12\x04\xa0\x01\x04\x19\n\ - \x0f\n\x07\x04\x01\x03\x06\x02\x04\x01\x12\x04\xa0\x01\x1a%\n\x0f\n\x07\ - \x04\x01\x03\x06\x02\x04\x03\x12\x04\xa0\x01()\nC\n\x04\x04\x01\x03\x07\ - \x12\x06\xa4\x01\x02\x9b\x03\x03\x1a3\x20An\x20action\x20to\x20be\x20tak\ - en\x20when\x20moving\x20to\x20a\x20new\x20state.\n\n\r\n\x05\x04\x01\x03\ - \x07\x01\x12\x04\xa4\x01\n\x10\n\x10\n\x06\x04\x01\x03\x07\x08\0\x12\x06\ - \xa5\x01\x04\xad\x01\x05\n\x0f\n\x07\x04\x01\x03\x07\x08\0\x01\x12\x04\ - \xa5\x01\n\x15\n\x0f\n\x07\x04\x01\x03\x07\x08\0\x02\x12\x04\xa6\x01\x06\ - (\n\x11\n\t\x04\x01\x03\x07\x08\0\x02\xaf\x08\x12\x04\xa6\x01\x06(\n\x0e\ - \n\x06\x04\x01\x03\x07\x02\0\x12\x04\xa7\x01\x062\n\x0f\n\x07\x04\x01\ - \x03\x07\x02\0\x06\x12\x04\xa7\x01\x06\x18\n\x0f\n\x07\x04\x01\x03\x07\ - \x02\0\x01\x12\x04\xa7\x01\x19-\n\x0f\n\x07\x04\x01\x03\x07\x02\0\x03\ - \x12\x04\xa7\x0101\n\x0e\n\x06\x04\x01\x03\x07\x02\x01\x12\x04\xa8\x01\ - \x06.\n\x0f\n\x07\x04\x01\x03\x07\x02\x01\x06\x12\x04\xa8\x01\x06\x16\n\ - \x0f\n\x07\x04\x01\x03\x07\x02\x01\x01\x12\x04\xa8\x01\x17)\n\x0f\n\x07\ - \x04\x01\x03\x07\x02\x01\x03\x12\x04\xa8\x01,-\n\x0e\n\x06\x04\x01\x03\ - \x07\x02\x02\x12\x04\xa9\x01\x06=\n\x0f\n\x07\x04\x01\x03\x07\x02\x02\ - \x06\x12\x04\xa9\x01\x06\x1d\n\x0f\n\x07\x04\x01\x03\x07\x02\x02\x01\x12\ - \x04\xa9\x01\x1e8\n\x0f\n\x07\x04\x01\x03\x07\x02\x02\x03\x12\x04\xa9\ - \x01;<\n\x0e\n\x06\x04\x01\x03\x07\x02\x03\x12\x04\xaa\x01\x066\n\x0f\n\ - \x07\x04\x01\x03\x07\x02\x03\x06\x12\x04\xaa\x01\x06\x1a\n\x0f\n\x07\x04\ - \x01\x03\x07\x02\x03\x01\x12\x04\xaa\x01\x1b1\n\x0f\n\x07\x04\x01\x03\ - \x07\x02\x03\x03\x12\x04\xaa\x0145\n\x0e\n\x06\x04\x01\x03\x07\x02\x04\ - \x12\x04\xab\x01\x060\n\x0f\n\x07\x04\x01\x03\x07\x02\x04\x06\x12\x04\ - \xab\x01\x06\x17\n\x0f\n\x07\x04\x01\x03\x07\x02\x04\x01\x12\x04\xab\x01\ - \x18+\n\x0f\n\x07\x04\x01\x03\x07\x02\x04\x03\x12\x04\xab\x01./\n\x0e\n\ - \x06\x04\x01\x03\x07\x02\x05\x12\x04\xac\x01\x062\n\x0f\n\x07\x04\x01\ - \x03\x07\x02\x05\x06\x12\x04\xac\x01\x06\x18\n\x0f\n\x07\x04\x01\x03\x07\ - \x02\x05\x01\x12\x04\xac\x01\x19-\n\x0f\n\x07\x04\x01\x03\x07\x02\x05\ - \x03\x12\x04\xac\x0101\n\xff\x01\n\x06\x04\x01\x03\x07\x03\0\x12\x04\xb2\ - \x01\x04!\x1a\xee\x01\x20Specifies\x20that\x20the\x20current\x20session\ - \x20will\x20start\x20trace\x20sampling.\x20Tracing\x20will\x20stop\x20wh\ - en\x20the\n\x20workflow\x20run\x20ends.\x20The\x20exception\x20to\x20thi\ - s\x20is\x20if\x20the\x20run\x20results\x20in\x20a\x20flush.\x20If\x20thi\ - s\x20happens,\n\x20tracing\x20will\x20stay\x20on\x20until\x20flush\x20st\ - reaming\x20completes.\n\n\x0f\n\x07\x04\x01\x03\x07\x03\0\x01\x12\x04\ - \xb2\x01\x0c\x1e\n\xb7\x01\n\x06\x04\x01\x03\x07\x03\x01\x12\x06\xb6\x01\ - \x04\xf5\x01\x05\x1a\xa4\x01\x20Generates\x20a\x20new\x20log\x20message.\ - \x20This\x20log\x20will\x20be\x20injected\x20into\x20the\x20workflow\x20\ - engine\x20and\x20processed\n\x20like\x20any\x20other\x20log,\x20either\ - \x20by\x20this\x20workflow\x20or\x20by\x20another\x20workflow.\n\n\x0f\n\ - \x07\x04\x01\x03\x07\x03\x01\x01\x12\x04\xb6\x01\x0c\x1d\nP\n\x08\x04\ - \x01\x03\x07\x03\x01\x03\0\x12\x06\xb8\x01\x06\xc7\x01\x07\x1a<\x20Descr\ - ibes\x20how\x20to\x20obtain\x20a\x20value\x20used\x20in\x20field\x20comp\ - osition.\n\n\x11\n\t\x04\x01\x03\x07\x03\x01\x03\0\x01\x12\x04\xb8\x01\ - \x0e\x1c\n\x14\n\n\x04\x01\x03\x07\x03\x01\x03\0\x08\0\x12\x06\xb9\x01\ - \x08\xc6\x01\t\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x08\0\x01\x12\ - \x04\xb9\x01\x0e\"\n5\n\n\x04\x01\x03\x07\x03\x01\x03\0\x02\0\x12\x04\ - \xbb\x01\n\x1b\x1a!\x20Fixed\x20value\x20that\x20never\x20changes.\n\n\ - \x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\0\x05\x12\x04\xbb\x01\n\x10\ - \n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\0\x01\x12\x04\xbb\x01\x11\ - \x16\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\0\x03\x12\x04\xbb\x01\ - \x19\x1a\nB\n\n\x04\x01\x03\x07\x03\x01\x03\0\x02\x01\x12\x04\xbd\x01\n,\ - \x1a.\x20The\x20value\x20of\x20the\x20field\x20from\x20the\x20current\ - \x20log.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x01\x05\x12\x04\ - \xbd\x01\n\x10\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x01\x01\x12\ - \x04\xbd\x01\x11'\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x01\x03\ - \x12\x04\xbd\x01*+\n\x84\x01\n\n\x04\x01\x03\x07\x03\x01\x03\0\x02\x02\ - \x12\x04\xc0\x01\n$\x1ap\x20The\x20value\x20of\x20a\x20field\x20from\x20\ - a\x20previous\x20log,\x20saved\x20via\x20the\x20SaveField\x20extension.\ - \x20This\x20is\n\x20the\x20ID\x20of\x20the\x20extension.\n\n\x13\n\x0b\ - \x04\x01\x03\x07\x03\x01\x03\0\x02\x02\x05\x12\x04\xc0\x01\n\x10\n\x13\n\ - \x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x02\x01\x12\x04\xc0\x01\x11\x1f\n\ - \x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x02\x03\x12\x04\xc0\x01\"#\ - \n\x7f\n\n\x04\x01\x03\x07\x03\x01\x03\0\x02\x03\x12\x04\xc3\x01\n(\x1ak\ - \x20The\x20timestamp\x20of\x20a\x20previous\x20log,\x20saved\x20via\x20t\ - he\x20SaveTimestamp\x20extension.\x20This\x20is\x20the\x20ID\n\x20of\x20\ - the\x20extension.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x03\ - \x05\x12\x04\xc3\x01\n\x10\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\ - \x03\x01\x12\x04\xc3\x01\x11#\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\ - \x02\x03\x03\x12\x04\xc3\x01&'\n4\n\n\x04\x01\x03\x07\x03\x01\x03\0\x02\ - \x04\x12\x04\xc5\x01\n\x18\x1a\x20\x20Fill\x20the\x20field\x20with\x20a\ - \x20UUID\x20v4.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x04\x05\ - \x12\x04\xc5\x01\n\x0e\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x04\ - \x01\x12\x04\xc5\x01\x0f\x13\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\ - \x02\x04\x03\x12\x04\xc5\x01\x16\x17\n'\n\x08\x04\x01\x03\x07\x03\x01\ - \x03\x01\x12\x06\xca\x01\x06\xcd\x01\x07\x1a\x13\x20A\x20pair\x20of\x20v\ - alues.\n\n\x11\n\t\x04\x01\x03\x07\x03\x01\x03\x01\x01\x12\x04\xca\x01\ - \x0e\x20\n\x12\n\n\x04\x01\x03\x07\x03\x01\x03\x01\x02\0\x12\x04\xcb\x01\ - \x08\x1f\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x01\x02\0\x06\x12\x04\ - \xcb\x01\x08\x16\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x01\x02\0\x01\ - \x12\x04\xcb\x01\x17\x1a\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x01\x02\ - \0\x03\x12\x04\xcb\x01\x1d\x1e\n\x12\n\n\x04\x01\x03\x07\x03\x01\x03\x01\ - \x02\x01\x12\x04\xcc\x01\x08\x1f\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\ - \x01\x02\x01\x06\x12\x04\xcc\x01\x08\x16\n\x13\n\x0b\x04\x01\x03\x07\x03\ - \x01\x03\x01\x02\x01\x01\x12\x04\xcc\x01\x17\x1a\n\x13\n\x0b\x04\x01\x03\ - \x07\x03\x01\x03\x01\x02\x01\x03\x12\x04\xcc\x01\x1d\x1e\n\xa1\x01\n\x08\ - \x04\x01\x03\x07\x03\x01\x03\x02\x12\x06\xd1\x01\x06\xe8\x01\x07\x1a\x8c\ - \x01\x20A\x20field\x20to\x20be\x20generated.\x20Note\x20that\x20when\x20\ - operating\x20on\x20timestamps,\x20the\x20values\x20are\x20expected\n\x20\ - to\x20be\x20fractions\x20of\x20seconds\x20since\x20the\x20Unix\x20epoch.\ - \n\n\x11\n\t\x04\x01\x03\x07\x03\x01\x03\x02\x01\x12\x04\xd1\x01\x0e\x1c\ - \n,\n\n\x04\x01\x03\x07\x03\x01\x03\x02\x02\0\x12\x04\xd3\x01\x08\x18\ - \x1a\x18\x20The\x20name\x20of\x20the\x20field.\n\n\x13\n\x0b\x04\x01\x03\ - \x07\x03\x01\x03\x02\x02\0\x05\x12\x04\xd3\x01\x08\x0e\n\x13\n\x0b\x04\ - \x01\x03\x07\x03\x01\x03\x02\x02\0\x01\x12\x04\xd3\x01\x0f\x13\n\x13\n\ - \x0b\x04\x01\x03\x07\x03\x01\x03\x02\x02\0\x03\x12\x04\xd3\x01\x16\x17\n\ - /\n\n\x04\x01\x03\x07\x03\x01\x03\x02\x08\0\x12\x06\xd6\x01\x08\xe7\x01\ - \t\x1a\x19\x20The\x20value\x20of\x20the\x20field.\n\n\x13\n\x0b\x04\x01\ - \x03\x07\x03\x01\x03\x02\x08\0\x01\x12\x04\xd6\x01\x0e(\n\x13\n\x0b\x04\ - \x01\x03\x07\x03\x01\x03\x02\x08\0\x02\x12\x04\xd7\x01\n,\n\x15\n\r\x04\ - \x01\x03\x07\x03\x01\x03\x02\x08\0\x02\xaf\x08\x12\x04\xd7\x01\n,\n%\n\n\ - \x04\x01\x03\x07\x03\x01\x03\x02\x02\x01\x12\x04\xda\x01\n$\x1a\x11\x20A\ - \x20single\x20value.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x02\x02\ - \x01\x06\x12\x04\xda\x01\n\x18\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\ - \x02\x02\x01\x01\x12\x04\xda\x01\x19\x1f\n\x13\n\x0b\x04\x01\x03\x07\x03\ - \x01\x03\x02\x02\x01\x03\x12\x04\xda\x01\"#\nh\n\n\x04\x01\x03\x07\x03\ - \x01\x03\x02\x02\x02\x12\x04\xdd\x01\n*\x1aT\x20Perform\x20subtraction.\ - \x20lhs\x20-\x20rhs.\x20Both\x20values\x20must\x20be\x20convertible\x20t\ + \x03\x02\0\x12\x03[\x06&\n\x0e\n\x07\x04\x01\x03\x03\x02\0\x06\x12\x03[\ + \x06\x12\n\x0e\n\x07\x04\x01\x03\x03\x02\0\x01\x12\x03[\x13!\n\x0e\n\x07\ + \x04\x01\x03\x03\x02\0\x03\x12\x03[$%\n\r\n\x06\x04\x01\x03\x03\x02\x01\ + \x12\x03\\\x067\n\x0e\n\x07\x04\x01\x03\x03\x02\x01\x06\x12\x03\\\x06\ + \x1a\n\x0e\n\x07\x04\x01\x03\x03\x02\x01\x01\x12\x03\\\x1b2\n\x0e\n\x07\ + \x04\x01\x03\x03\x02\x01\x03\x12\x03\\56\n;\n\x06\x04\x01\x03\x03\x02\ + \x02\x12\x03^\x06\x1e\x1a,\x20This\x20will\x20match\x20when\x20a\x20new\ + \x20session\x20starts.\n\n\x0e\n\x07\x04\x01\x03\x03\x02\x02\x05\x12\x03\ + ^\x06\n\n\x0e\n\x07\x04\x01\x03\x03\x02\x02\x01\x12\x03^\x0b\x19\n\x0e\n\ + \x07\x04\x01\x03\x03\x02\x02\x03\x12\x03^\x1c\x1d\n\x0c\n\x05\x04\x01\ + \x03\x03\t\x12\x03a\x04\x0f\n\r\n\x06\x04\x01\x03\x03\t\0\x12\x03a\r\x0e\ + \n\x0e\n\x07\x04\x01\x03\x03\t\0\x01\x12\x03a\r\x0e\n\x0e\n\x07\x04\x01\ + \x03\x03\t\0\x02\x12\x03a\r\x0e\n?\n\x04\x04\x01\x03\x04\x12\x05e\x02\ + \x88\x01\x03\x1a0\x20An\x20extra\x20configuration\x20for\x20a\x20given\ + \x20transition.\n\n\x0c\n\x05\x04\x01\x03\x04\x01\x12\x03e\n\x1d\n\x0e\n\ + \x06\x04\x01\x03\x04\x08\0\x12\x04f\x04k\x05\n\x0e\n\x07\x04\x01\x03\x04\ + \x08\0\x01\x12\x03f\n\x18\n\x0e\n\x07\x04\x01\x03\x04\x08\0\x02\x12\x03g\ + \x06(\n\x10\n\t\x04\x01\x03\x04\x08\0\x02\xaf\x08\x12\x03g\x06(\n\r\n\ + \x06\x04\x01\x03\x04\x02\0\x12\x03h\x06G\n\x0e\n\x07\x04\x01\x03\x04\x02\ + \0\x06\x12\x03h\x06\"\n\x0e\n\x07\x04\x01\x03\x04\x02\0\x01\x12\x03h#B\n\ + \x0e\n\x07\x04\x01\x03\x04\x02\0\x03\x12\x03hEF\n\r\n\x06\x04\x01\x03\ + \x04\x02\x01\x12\x03i\x06'\n\x0e\n\x07\x04\x01\x03\x04\x02\x01\x06\x12\ + \x03i\x06\x13\n\x0e\n\x07\x04\x01\x03\x04\x02\x01\x01\x12\x03i\x14\"\n\ + \x0e\n\x07\x04\x01\x03\x04\x02\x01\x03\x12\x03i%&\n\r\n\x06\x04\x01\x03\ + \x04\x02\x02\x12\x03j\x06\x1f\n\x0e\n\x07\x04\x01\x03\x04\x02\x02\x06\ + \x12\x03j\x06\x0f\n\x0e\n\x07\x04\x01\x03\x04\x02\x02\x01\x12\x03j\x10\ + \x1a\n\x0e\n\x07\x04\x01\x03\x04\x02\x02\x03\x12\x03j\x1d\x1e\n\xdc\x01\ + \n\x06\x04\x01\x03\x04\x03\0\x12\x04p\x04r\x05\x1a\xcb\x01\x20The\x20tim\ + estamp\x20of\x20the\x20transition\x20will\x20be\x20snapped,\x20and\x20pe\ + rsisted\x20to\x20the\x20workflow\x20state.\x20This\n\x20can\x20be\x20loo\ + ked\x20up\x20by\x20ID\x20by\x20further\x20transitions.\x20The\x20saved\ + \x20timestamp\x20is\x20fraction\x20seconds\x20since\n\x20the\x20Unix\x20\ + epoch.\n\n\x0e\n\x07\x04\x01\x03\x04\x03\0\x01\x12\x03p\x0c\x19\n\x0f\n\ + \x08\x04\x01\x03\x04\x03\0\x02\0\x12\x03q\x06\x14\n\x10\n\t\x04\x01\x03\ + \x04\x03\0\x02\0\x05\x12\x03q\x06\x0c\n\x10\n\t\x04\x01\x03\x04\x03\0\ + \x02\0\x01\x12\x03q\r\x0f\n\x10\n\t\x04\x01\x03\x04\x03\0\x02\0\x03\x12\ + \x03q\x12\x13\nP\n\x06\x04\x01\x03\x04\x03\x01\x12\x05u\x04\x87\x01\x05\ + \x1a?\x20The\x20configuration\x20of\x20a\x20value\x20extraction\x20for\ + \x20a\x20Sankey\x20diagram.\n\n\x0e\n\x07\x04\x01\x03\x04\x03\x01\x01\ + \x12\x03u\x0c(\nI\n\x08\x04\x01\x03\x04\x03\x01\x02\0\x12\x03w\x06L\x1a8\ + \x20The\x20ID\x20of\x20the\x20Sankey\x20diagram\x20to\x20extract\x20the\ + \x20value\x20for.\n\n\x10\n\t\x04\x01\x03\x04\x03\x01\x02\0\x05\x12\x03w\ + \x06\x0c\n\x10\n\t\x04\x01\x03\x04\x03\x01\x02\0\x01\x12\x03w\r\x1e\n\ + \x10\n\t\x04\x01\x03\x04\x03\x01\x02\0\x03\x12\x03w!\"\n\x10\n\t\x04\x01\ + \x03\x04\x03\x01\x02\0\x08\x12\x03w#K\n\x13\n\x0c\x04\x01\x03\x04\x03\ + \x01\x02\0\x08\xaf\x08\x0e\x12\x03w$J\n:\n\x08\x04\x01\x03\x04\x03\x01\ + \x08\0\x12\x05z\x06\x82\x01\x07\x1a'\x20The\x20name\x20of\x20the\x20Sank\ + ey\x20diagram\x20state.\n\n\x10\n\t\x04\x01\x03\x04\x03\x01\x08\0\x01\ + \x12\x03z\x0c\x16\n\x10\n\t\x04\x01\x03\x04\x03\x01\x08\0\x02\x12\x03{\ + \x08*\n\x12\n\x0b\x04\x01\x03\x04\x03\x01\x08\0\x02\xaf\x08\x12\x03{\x08\ + *\n!\n\x08\x04\x01\x03\x04\x03\x01\x02\x01\x12\x03~\x08B\x1a\x10\x20A\ + \x20fixed\x20value.\n\n\x10\n\t\x04\x01\x03\x04\x03\x01\x02\x01\x05\x12\ + \x03~\x08\x0e\n\x10\n\t\x04\x01\x03\x04\x03\x01\x02\x01\x01\x12\x03~\x0f\ + \x14\n\x10\n\t\x04\x01\x03\x04\x03\x01\x02\x01\x03\x12\x03~\x17\x18\n\ + \x10\n\t\x04\x01\x03\x04\x03\x01\x02\x01\x08\x12\x03~\x19A\n\x13\n\x0c\ + \x04\x01\x03\x04\x03\x01\x02\x01\x08\xaf\x08\x0e\x12\x03~\x1a@\n5\n\x08\ + \x04\x01\x03\x04\x03\x01\x02\x02\x12\x04\x81\x01\x08+\x1a#\x20The\x20val\ + ue\x20extracted\x20from\x20a\x20field.\n\n\x11\n\t\x04\x01\x03\x04\x03\ + \x01\x02\x02\x06\x12\x04\x81\x01\x08\x16\n\x11\n\t\x04\x01\x03\x04\x03\ + \x01\x02\x02\x01\x12\x04\x81\x01\x17&\n\x11\n\t\x04\x01\x03\x04\x03\x01\ + \x02\x02\x03\x12\x04\x81\x01)*\n\xa4\x01\n\x08\x04\x01\x03\x04\x03\x01\ + \x02\x03\x12\x04\x86\x01\x065\x1a\x91\x01\x20Whether\x20extracting\x20th\ + e\x20value\x20with\x20the\x20extension\x20counts\x20toward\x20the\x20lim\ + it\x20of\x20the\x20extracted\x20values\n\x20defined\x20on\x20a\x20given\ + \x20emit\x20Sankey\x20diagram\x20action.\n\n\x11\n\t\x04\x01\x03\x04\x03\ + \x01\x02\x03\x05\x12\x04\x86\x01\x06\n\n\x11\n\t\x04\x01\x03\x04\x03\x01\ + \x02\x03\x01\x12\x04\x86\x01\x0b0\n\x11\n\t\x04\x01\x03\x04\x03\x01\x02\ + \x03\x03\x12\x04\x86\x0134\n9\n\x04\x04\x01\x03\x05\x12\x06\x8b\x01\x02\ + \x90\x01\x03\x1a)\x20Rule\x20used\x20to\x20transition\x20based\x20on\x20\ + a\x20log.\n\n\r\n\x05\x04\x01\x03\x05\x01\x12\x04\x8b\x01\n\x16\n8\n\x06\ + \x04\x01\x03\x05\x02\0\x12\x04\x8d\x01\x04X\x1a(\x20The\x20condition\x20\ + that\x20a\x20log\x20must\x20satisfy.\n\n\x0f\n\x07\x04\x01\x03\x05\x02\0\ + \x06\x12\x04\x8d\x01\x04\x19\n\x0f\n\x07\x04\x01\x03\x05\x02\0\x01\x12\ + \x04\x8d\x01\x1a%\n\x0f\n\x07\x04\x01\x03\x05\x02\0\x03\x12\x04\x8d\x01(\ + )\n\x0f\n\x07\x04\x01\x03\x05\x02\0\x08\x12\x04\x8d\x01*W\n\x12\n\n\x04\ + \x01\x03\x05\x02\0\x08\xaf\x08\x11\x12\x04\x8d\x01+V\nR\n\x06\x04\x01\ + \x03\x05\x02\x01\x12\x04\x8f\x01\x046\x1aB\x20The\x20number\x20of\x20tim\ + es\x20the\x20condition\x20needs\x20to\x20be\x20met,\x20default\x20is\x20\ + 1.\n\n\x0f\n\x07\x04\x01\x03\x05\x02\x01\x05\x12\x04\x8f\x01\x04\n\n\x0f\ + \n\x07\x04\x01\x03\x05\x02\x01\x01\x12\x04\x8f\x01\x0b\x10\n\x0f\n\x07\ + \x04\x01\x03\x05\x02\x01\x03\x12\x04\x8f\x01\x13\x14\n\x0f\n\x07\x04\x01\ + \x03\x05\x02\x01\x08\x12\x04\x8f\x01\x155\n\x13\n\x0b\x04\x01\x03\x05\ + \x02\x01\x08\xaf\x08\x05\x04\x12\x04\x8f\x01\x164\n\xe5\x01\n\x04\x04\ + \x01\x03\x06\x12\x06\x94\x01\x02\xa4\x01\x03\x1a\xd4\x01\x20Matches\x20a\ + gainst\x20a\x20state\x20change.\x20Every\x20time\x20the\x20value\x20of\ + \x20a\x20scoped\x20key\x20changes\x20(new\x20value\x20is\x20different\ + \x20from\x20previous\x20value),\n\x20the\x20rule\x20evaluates\x20whether\ + \x20the\x20previous\x20and\x20new\x20values\x20match\x20the\x20specified\ + \x20conditions.\n\n\r\n\x05\x04\x01\x03\x06\x01\x12\x04\x94\x01\n\x1e\n6\ + \n\x06\x04\x01\x03\x06\x02\0\x12\x04\x96\x01\x04N\x1a&\x20The\x20scope\ + \x20of\x20the\x20state\x20to\x20watch\x20for.\n\n\x0f\n\x07\x04\x01\x03\ + \x06\x02\0\x06\x12\x04\x96\x01\x04\x17\n\x0f\n\x07\x04\x01\x03\x06\x02\0\ + \x01\x12\x04\x96\x01\x18\x1d\n\x0f\n\x07\x04\x01\x03\x06\x02\0\x03\x12\ + \x04\x96\x01\x20!\n\x0f\n\x07\x04\x01\x03\x06\x02\0\x08\x12\x04\x96\x01\ + \"M\n\x13\n\x0b\x04\x01\x03\x06\x02\0\x08\xaf\x08\x10\x02\x12\x04\x96\ + \x01#L\n4\n\x06\x04\x01\x03\x06\x02\x01\x12\x04\x99\x01\x04<\x1a$\x20The\ + \x20key\x20of\x20the\x20state\x20to\x20watch\x20for.\n\n\x0f\n\x07\x04\ + \x01\x03\x06\x02\x01\x05\x12\x04\x99\x01\x04\n\n\x0f\n\x07\x04\x01\x03\ + \x06\x02\x01\x01\x12\x04\x99\x01\x0b\x0e\n\x0f\n\x07\x04\x01\x03\x06\x02\ + \x01\x03\x12\x04\x99\x01\x11\x12\n\x0f\n\x07\x04\x01\x03\x06\x02\x01\x08\ + \x12\x04\x99\x01\x13;\n\x12\n\n\x04\x01\x03\x06\x02\x01\x08\xaf\x08\x0e\ + \x12\x04\x99\x01\x14:\np\n\x06\x04\x01\x03\x06\x02\x02\x12\x04\x9c\x01\ + \x040\x1a`\x20The\x20match\x20condition\x20which\x20is\x20applied\x20to\ + \x20the\x20previous\x20value\x20of\x20the\x20state\x20during\x20a\x20sta\ + te\x20change.\n\n\x0f\n\x07\x04\x01\x03\x06\x02\x02\x06\x12\x04\x9c\x01\ + \x04\x1c\n\x0f\n\x07\x04\x01\x03\x06\x02\x02\x01\x12\x04\x9c\x01\x1d+\n\ + \x0f\n\x07\x04\x01\x03\x06\x02\x02\x03\x12\x04\x9c\x01./\nk\n\x06\x04\ + \x01\x03\x06\x02\x03\x12\x04\x9f\x01\x04Y\x1a[\x20The\x20match\x20condit\ + ion\x20which\x20is\x20applied\x20to\x20the\x20new\x20value\x20of\x20the\ + \x20state\x20during\x20a\x20state\x20change.\n\n\x0f\n\x07\x04\x01\x03\ + \x06\x02\x03\x06\x12\x04\x9f\x01\x04\x1c\n\x0f\n\x07\x04\x01\x03\x06\x02\ + \x03\x01\x12\x04\x9f\x01\x1d&\n\x0f\n\x07\x04\x01\x03\x06\x02\x03\x03\ + \x12\x04\x9f\x01)*\n\x0f\n\x07\x04\x01\x03\x06\x02\x03\x08\x12\x04\x9f\ + \x01+X\n\x12\n\n\x04\x01\x03\x06\x02\x03\x08\xaf\x08\x11\x12\x04\x9f\x01\ + ,W\n\xe5\x01\n\x06\x04\x01\x03\x06\x02\x04\x12\x04\xa3\x01\x04*\x1a\xd4\ + \x01\x20Additional\x20properties\x20that\x20must\x20be\x20true\x20at\x20\ + the\x20time\x20of\x20the\x20state\x20change\x20for\x20the\x20rule\x20to\ + \x20match.\n\x20Since\x20state\x20changes\x20do\x20not\x20match\x20again\ + st\x20a\x20particular\x20log,\x20tags\x20and\x20messages\x20will\x20not\ + \x20be\x20visibile\x20to\x20this\x20matcher.\n\n\x0f\n\x07\x04\x01\x03\ + \x06\x02\x04\x06\x12\x04\xa3\x01\x04\x19\n\x0f\n\x07\x04\x01\x03\x06\x02\ + \x04\x01\x12\x04\xa3\x01\x1a%\n\x0f\n\x07\x04\x01\x03\x06\x02\x04\x03\ + \x12\x04\xa3\x01()\nC\n\x04\x04\x01\x03\x07\x12\x06\xa7\x01\x02\x9e\x03\ + \x03\x1a3\x20An\x20action\x20to\x20be\x20taken\x20when\x20moving\x20to\ + \x20a\x20new\x20state.\n\n\r\n\x05\x04\x01\x03\x07\x01\x12\x04\xa7\x01\n\ + \x10\n\x10\n\x06\x04\x01\x03\x07\x08\0\x12\x06\xa8\x01\x04\xb0\x01\x05\n\ + \x0f\n\x07\x04\x01\x03\x07\x08\0\x01\x12\x04\xa8\x01\n\x15\n\x0f\n\x07\ + \x04\x01\x03\x07\x08\0\x02\x12\x04\xa9\x01\x06(\n\x11\n\t\x04\x01\x03\ + \x07\x08\0\x02\xaf\x08\x12\x04\xa9\x01\x06(\n\x0e\n\x06\x04\x01\x03\x07\ + \x02\0\x12\x04\xaa\x01\x062\n\x0f\n\x07\x04\x01\x03\x07\x02\0\x06\x12\ + \x04\xaa\x01\x06\x18\n\x0f\n\x07\x04\x01\x03\x07\x02\0\x01\x12\x04\xaa\ + \x01\x19-\n\x0f\n\x07\x04\x01\x03\x07\x02\0\x03\x12\x04\xaa\x0101\n\x0e\ + \n\x06\x04\x01\x03\x07\x02\x01\x12\x04\xab\x01\x06.\n\x0f\n\x07\x04\x01\ + \x03\x07\x02\x01\x06\x12\x04\xab\x01\x06\x16\n\x0f\n\x07\x04\x01\x03\x07\ + \x02\x01\x01\x12\x04\xab\x01\x17)\n\x0f\n\x07\x04\x01\x03\x07\x02\x01\ + \x03\x12\x04\xab\x01,-\n\x0e\n\x06\x04\x01\x03\x07\x02\x02\x12\x04\xac\ + \x01\x06=\n\x0f\n\x07\x04\x01\x03\x07\x02\x02\x06\x12\x04\xac\x01\x06\ + \x1d\n\x0f\n\x07\x04\x01\x03\x07\x02\x02\x01\x12\x04\xac\x01\x1e8\n\x0f\ + \n\x07\x04\x01\x03\x07\x02\x02\x03\x12\x04\xac\x01;<\n\x0e\n\x06\x04\x01\ + \x03\x07\x02\x03\x12\x04\xad\x01\x066\n\x0f\n\x07\x04\x01\x03\x07\x02\ + \x03\x06\x12\x04\xad\x01\x06\x1a\n\x0f\n\x07\x04\x01\x03\x07\x02\x03\x01\ + \x12\x04\xad\x01\x1b1\n\x0f\n\x07\x04\x01\x03\x07\x02\x03\x03\x12\x04\ + \xad\x0145\n\x0e\n\x06\x04\x01\x03\x07\x02\x04\x12\x04\xae\x01\x060\n\ + \x0f\n\x07\x04\x01\x03\x07\x02\x04\x06\x12\x04\xae\x01\x06\x17\n\x0f\n\ + \x07\x04\x01\x03\x07\x02\x04\x01\x12\x04\xae\x01\x18+\n\x0f\n\x07\x04\ + \x01\x03\x07\x02\x04\x03\x12\x04\xae\x01./\n\x0e\n\x06\x04\x01\x03\x07\ + \x02\x05\x12\x04\xaf\x01\x062\n\x0f\n\x07\x04\x01\x03\x07\x02\x05\x06\ + \x12\x04\xaf\x01\x06\x18\n\x0f\n\x07\x04\x01\x03\x07\x02\x05\x01\x12\x04\ + \xaf\x01\x19-\n\x0f\n\x07\x04\x01\x03\x07\x02\x05\x03\x12\x04\xaf\x0101\ + \n\xff\x01\n\x06\x04\x01\x03\x07\x03\0\x12\x04\xb5\x01\x04!\x1a\xee\x01\ + \x20Specifies\x20that\x20the\x20current\x20session\x20will\x20start\x20t\ + race\x20sampling.\x20Tracing\x20will\x20stop\x20when\x20the\n\x20workflo\ + w\x20run\x20ends.\x20The\x20exception\x20to\x20this\x20is\x20if\x20the\ + \x20run\x20results\x20in\x20a\x20flush.\x20If\x20this\x20happens,\n\x20t\ + racing\x20will\x20stay\x20on\x20until\x20flush\x20streaming\x20completes\ + .\n\n\x0f\n\x07\x04\x01\x03\x07\x03\0\x01\x12\x04\xb5\x01\x0c\x1e\n\xb7\ + \x01\n\x06\x04\x01\x03\x07\x03\x01\x12\x06\xb9\x01\x04\xf8\x01\x05\x1a\ + \xa4\x01\x20Generates\x20a\x20new\x20log\x20message.\x20This\x20log\x20w\ + ill\x20be\x20injected\x20into\x20the\x20workflow\x20engine\x20and\x20pro\ + cessed\n\x20like\x20any\x20other\x20log,\x20either\x20by\x20this\x20work\ + flow\x20or\x20by\x20another\x20workflow.\n\n\x0f\n\x07\x04\x01\x03\x07\ + \x03\x01\x01\x12\x04\xb9\x01\x0c\x1d\nP\n\x08\x04\x01\x03\x07\x03\x01\ + \x03\0\x12\x06\xbb\x01\x06\xca\x01\x07\x1a<\x20Describes\x20how\x20to\ + \x20obtain\x20a\x20value\x20used\x20in\x20field\x20composition.\n\n\x11\ + \n\t\x04\x01\x03\x07\x03\x01\x03\0\x01\x12\x04\xbb\x01\x0e\x1c\n\x14\n\n\ + \x04\x01\x03\x07\x03\x01\x03\0\x08\0\x12\x06\xbc\x01\x08\xc9\x01\t\n\x13\ + \n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x08\0\x01\x12\x04\xbc\x01\x0e\"\n5\ + \n\n\x04\x01\x03\x07\x03\x01\x03\0\x02\0\x12\x04\xbe\x01\n\x1b\x1a!\x20F\ + ixed\x20value\x20that\x20never\x20changes.\n\n\x13\n\x0b\x04\x01\x03\x07\ + \x03\x01\x03\0\x02\0\x05\x12\x04\xbe\x01\n\x10\n\x13\n\x0b\x04\x01\x03\ + \x07\x03\x01\x03\0\x02\0\x01\x12\x04\xbe\x01\x11\x16\n\x13\n\x0b\x04\x01\ + \x03\x07\x03\x01\x03\0\x02\0\x03\x12\x04\xbe\x01\x19\x1a\nB\n\n\x04\x01\ + \x03\x07\x03\x01\x03\0\x02\x01\x12\x04\xc0\x01\n,\x1a.\x20The\x20value\ + \x20of\x20the\x20field\x20from\x20the\x20current\x20log.\n\n\x13\n\x0b\ + \x04\x01\x03\x07\x03\x01\x03\0\x02\x01\x05\x12\x04\xc0\x01\n\x10\n\x13\n\ + \x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x01\x01\x12\x04\xc0\x01\x11'\n\ + \x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x01\x03\x12\x04\xc0\x01*+\n\ + \x84\x01\n\n\x04\x01\x03\x07\x03\x01\x03\0\x02\x02\x12\x04\xc3\x01\n$\ + \x1ap\x20The\x20value\x20of\x20a\x20field\x20from\x20a\x20previous\x20lo\ + g,\x20saved\x20via\x20the\x20SaveField\x20extension.\x20This\x20is\n\x20\ + the\x20ID\x20of\x20the\x20extension.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\ + \x01\x03\0\x02\x02\x05\x12\x04\xc3\x01\n\x10\n\x13\n\x0b\x04\x01\x03\x07\ + \x03\x01\x03\0\x02\x02\x01\x12\x04\xc3\x01\x11\x1f\n\x13\n\x0b\x04\x01\ + \x03\x07\x03\x01\x03\0\x02\x02\x03\x12\x04\xc3\x01\"#\n\x7f\n\n\x04\x01\ + \x03\x07\x03\x01\x03\0\x02\x03\x12\x04\xc6\x01\n(\x1ak\x20The\x20timesta\ + mp\x20of\x20a\x20previous\x20log,\x20saved\x20via\x20the\x20SaveTimestam\ + p\x20extension.\x20This\x20is\x20the\x20ID\n\x20of\x20the\x20extension.\ + \n\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x03\x05\x12\x04\xc6\x01\ + \n\x10\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x03\x01\x12\x04\xc6\ + \x01\x11#\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x03\x03\x12\x04\ + \xc6\x01&'\n4\n\n\x04\x01\x03\x07\x03\x01\x03\0\x02\x04\x12\x04\xc8\x01\ + \n\x18\x1a\x20\x20Fill\x20the\x20field\x20with\x20a\x20UUID\x20v4.\n\n\ + \x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x04\x05\x12\x04\xc8\x01\n\ + \x0e\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x04\x01\x12\x04\xc8\ + \x01\x0f\x13\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\0\x02\x04\x03\x12\ + \x04\xc8\x01\x16\x17\n'\n\x08\x04\x01\x03\x07\x03\x01\x03\x01\x12\x06\ + \xcd\x01\x06\xd0\x01\x07\x1a\x13\x20A\x20pair\x20of\x20values.\n\n\x11\n\ + \t\x04\x01\x03\x07\x03\x01\x03\x01\x01\x12\x04\xcd\x01\x0e\x20\n\x12\n\n\ + \x04\x01\x03\x07\x03\x01\x03\x01\x02\0\x12\x04\xce\x01\x08\x1f\n\x13\n\ + \x0b\x04\x01\x03\x07\x03\x01\x03\x01\x02\0\x06\x12\x04\xce\x01\x08\x16\n\ + \x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x01\x02\0\x01\x12\x04\xce\x01\x17\ + \x1a\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x01\x02\0\x03\x12\x04\xce\ + \x01\x1d\x1e\n\x12\n\n\x04\x01\x03\x07\x03\x01\x03\x01\x02\x01\x12\x04\ + \xcf\x01\x08\x1f\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x01\x02\x01\x06\ + \x12\x04\xcf\x01\x08\x16\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x01\x02\ + \x01\x01\x12\x04\xcf\x01\x17\x1a\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\ + \x01\x02\x01\x03\x12\x04\xcf\x01\x1d\x1e\n\xa1\x01\n\x08\x04\x01\x03\x07\ + \x03\x01\x03\x02\x12\x06\xd4\x01\x06\xeb\x01\x07\x1a\x8c\x01\x20A\x20fie\ + ld\x20to\x20be\x20generated.\x20Note\x20that\x20when\x20operating\x20on\ + \x20timestamps,\x20the\x20values\x20are\x20expected\n\x20to\x20be\x20fra\ + ctions\x20of\x20seconds\x20since\x20the\x20Unix\x20epoch.\n\n\x11\n\t\ + \x04\x01\x03\x07\x03\x01\x03\x02\x01\x12\x04\xd4\x01\x0e\x1c\n,\n\n\x04\ + \x01\x03\x07\x03\x01\x03\x02\x02\0\x12\x04\xd6\x01\x08\x18\x1a\x18\x20Th\ + e\x20name\x20of\x20the\x20field.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\ + \x03\x02\x02\0\x05\x12\x04\xd6\x01\x08\x0e\n\x13\n\x0b\x04\x01\x03\x07\ + \x03\x01\x03\x02\x02\0\x01\x12\x04\xd6\x01\x0f\x13\n\x13\n\x0b\x04\x01\ + \x03\x07\x03\x01\x03\x02\x02\0\x03\x12\x04\xd6\x01\x16\x17\n/\n\n\x04\ + \x01\x03\x07\x03\x01\x03\x02\x08\0\x12\x06\xd9\x01\x08\xea\x01\t\x1a\x19\ + \x20The\x20value\x20of\x20the\x20field.\n\n\x13\n\x0b\x04\x01\x03\x07\ + \x03\x01\x03\x02\x08\0\x01\x12\x04\xd9\x01\x0e(\n\x13\n\x0b\x04\x01\x03\ + \x07\x03\x01\x03\x02\x08\0\x02\x12\x04\xda\x01\n,\n\x15\n\r\x04\x01\x03\ + \x07\x03\x01\x03\x02\x08\0\x02\xaf\x08\x12\x04\xda\x01\n,\n%\n\n\x04\x01\ + \x03\x07\x03\x01\x03\x02\x02\x01\x12\x04\xdd\x01\n$\x1a\x11\x20A\x20sing\ + le\x20value.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x02\x02\x01\x06\ + \x12\x04\xdd\x01\n\x18\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x02\x02\ + \x01\x01\x12\x04\xdd\x01\x19\x1f\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\ + \x02\x02\x01\x03\x12\x04\xdd\x01\"#\nh\n\n\x04\x01\x03\x07\x03\x01\x03\ + \x02\x02\x02\x12\x04\xe0\x01\n*\x1aT\x20Perform\x20subtraction.\x20lhs\ + \x20-\x20rhs.\x20Both\x20values\x20must\x20be\x20convertible\x20to\x20fl\ + oating\x20point.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x02\x02\x02\ + \x06\x12\x04\xe0\x01\n\x1c\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x02\ + \x02\x02\x01\x12\x04\xe0\x01\x1d%\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\ + \x03\x02\x02\x02\x03\x12\x04\xe0\x01()\ne\n\n\x04\x01\x03\x07\x03\x01\ + \x03\x02\x02\x03\x12\x04\xe3\x01\n%\x1aQ\x20Perform\x20addition.\x20lhs\ + \x20+\x20rhs.\x20Both\x20values\x20must\x20be\x20convertible\x20to\x20fl\ + oating\x20point.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x02\x02\x03\ + \x06\x12\x04\xe3\x01\n\x1c\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x02\ + \x02\x03\x01\x12\x04\xe3\x01\x1d\x20\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\ + \x03\x02\x02\x03\x03\x12\x04\xe3\x01#$\nk\n\n\x04\x01\x03\x07\x03\x01\ + \x03\x02\x02\x04\x12\x04\xe6\x01\n*\x1aW\x20Perform\x20multiplication.\ + \x20lhs\x20*\x20rhs.\x20Both\x20values\x20must\x20be\x20convertible\x20t\ o\x20floating\x20point.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x02\ - \x02\x02\x06\x12\x04\xdd\x01\n\x1c\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\ - \x03\x02\x02\x02\x01\x12\x04\xdd\x01\x1d%\n\x13\n\x0b\x04\x01\x03\x07\ - \x03\x01\x03\x02\x02\x02\x03\x12\x04\xdd\x01()\ne\n\n\x04\x01\x03\x07\ - \x03\x01\x03\x02\x02\x03\x12\x04\xe0\x01\n%\x1aQ\x20Perform\x20addition.\ - \x20lhs\x20+\x20rhs.\x20Both\x20values\x20must\x20be\x20convertible\x20t\ + \x02\x04\x06\x12\x04\xe6\x01\n\x1c\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\ + \x03\x02\x02\x04\x01\x12\x04\xe6\x01\x1d%\n\x13\n\x0b\x04\x01\x03\x07\ + \x03\x01\x03\x02\x02\x04\x03\x12\x04\xe6\x01()\ne\n\n\x04\x01\x03\x07\ + \x03\x01\x03\x02\x02\x05\x12\x04\xe9\x01\n(\x1aQ\x20Perform\x20division.\ + \x20lhs\x20/\x20rhs.\x20Both\x20values\x20must\x20be\x20convertible\x20t\ o\x20floating\x20point.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\x02\ - \x02\x03\x06\x12\x04\xe0\x01\n\x1c\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\ - \x03\x02\x02\x03\x01\x12\x04\xe0\x01\x1d\x20\n\x13\n\x0b\x04\x01\x03\x07\ - \x03\x01\x03\x02\x02\x03\x03\x12\x04\xe0\x01#$\nk\n\n\x04\x01\x03\x07\ - \x03\x01\x03\x02\x02\x04\x12\x04\xe3\x01\n*\x1aW\x20Perform\x20multiplic\ - ation.\x20lhs\x20*\x20rhs.\x20Both\x20values\x20must\x20be\x20convertibl\ - e\x20to\x20floating\x20point.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\ - \x02\x02\x04\x06\x12\x04\xe3\x01\n\x1c\n\x13\n\x0b\x04\x01\x03\x07\x03\ - \x01\x03\x02\x02\x04\x01\x12\x04\xe3\x01\x1d%\n\x13\n\x0b\x04\x01\x03\ - \x07\x03\x01\x03\x02\x02\x04\x03\x12\x04\xe3\x01()\ne\n\n\x04\x01\x03\ - \x07\x03\x01\x03\x02\x02\x05\x12\x04\xe6\x01\n(\x1aQ\x20Perform\x20divis\ - ion.\x20lhs\x20/\x20rhs.\x20Both\x20values\x20must\x20be\x20convertible\ - \x20to\x20floating\x20point.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\x03\ - \x02\x02\x05\x06\x12\x04\xe6\x01\n\x1c\n\x13\n\x0b\x04\x01\x03\x07\x03\ - \x01\x03\x02\x02\x05\x01\x12\x04\xe6\x01\x1d#\n\x13\n\x0b\x04\x01\x03\ - \x07\x03\x01\x03\x02\x02\x05\x03\x12\x04\xe6\x01&'\n\x10\n\x08\x04\x01\ - \x03\x07\x03\x01\x02\0\x12\x04\xea\x01\x06\x19\n\x11\n\t\x04\x01\x03\x07\ - \x03\x01\x02\0\x05\x12\x04\xea\x01\x06\x0c\n\x11\n\t\x04\x01\x03\x07\x03\ - \x01\x02\0\x01\x12\x04\xea\x01\r\x14\n\x11\n\t\x04\x01\x03\x07\x03\x01\ - \x02\0\x03\x12\x04\xea\x01\x17\x18\n\x10\n\x08\x04\x01\x03\x07\x03\x01\ - \x02\x01\x12\x04\xeb\x01\x06)\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x01\ - \x04\x12\x04\xeb\x01\x06\x0e\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x01\ - \x06\x12\x04\xeb\x01\x0f\x1d\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x01\ - \x01\x12\x04\xeb\x01\x1e$\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x01\x03\ - \x12\x04\xeb\x01'(\n\xa3\x02\n\x08\x04\x01\x03\x07\x03\x01\x02\x02\x12\ - \x04\xf0\x01\x06\x14\x1a\x90\x02\x20A\x20unique\x20identifier\x20for\x20\ - the\x20action.\x20If\x20multiple\x20generate\x20log\x20actions\x20have\ - \x20the\x20same\x20ID\x20and\n\x20are\x20performed\x20as\x20the\x20resul\ - t\x20of\x20processing\x20the\x20same\x20log,\x20a\x20client\x20will\x20e\ - mit\x20only\x20a\x20single\n\x20log\x20as\x20the\x20result.\x20This\x20i\ - mplies\x20that\x20the\x20resulting\x20logs\x20in\x20this\x20case\x20shou\ - ld\x20be\x20identical.\n\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x02\x05\ - \x12\x04\xf0\x01\x06\x0c\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x02\x01\ - \x12\x04\xf0\x01\r\x0f\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x02\x03\x12\ - \x04\xf0\x01\x12\x13\nq\n\x08\x04\x01\x03\x07\x03\x01\x02\x03\x12\x04\ - \xf4\x01\x06\x1a\x1a_\x20Should\x20be\x20one\x20of\x20the\x20log\x20type\ - s\x20in\x20buffer_log.fbs.\x20If\x20unset\x20the\x20default\x20is\x200\ - \x20which\x20is\n\x20Normal.\n\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x03\ - \x05\x12\x04\xf4\x01\x06\x0c\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x03\ - \x01\x12\x04\xf4\x01\r\x15\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x03\x03\ - \x12\x04\xf4\x01\x18\x19\n\xf5\x01\n\x06\x04\x01\x03\x07\x03\x02\x12\x06\ - \xfa\x01\x04\xa8\x02\x05\x1a\xe2\x01\x20Flush\x20the\x20content\x20of\ - \x20the\x20specified\x20buffer(s)\x20to\x20the\x20bitdrift\x20control\ - \x20plane,\x20with\x20the\x20option\x20to\x20continue\n\x20streaming\x20\ - logs\x20incoming\x20to\x20the\x20buffer(s)\x20to\x20remote\x20services,\ - \x20until\x20one\x20of\x20the\x20specified\x20termination\n\x20condition\ - s\x20is\x20met.\n\n\x0f\n\x07\x04\x01\x03\x07\x03\x02\x01\x12\x04\xfa\ - \x01\x0c\x1e\n\xbf\x02\n\x08\x04\x01\x03\x07\x03\x02\x03\0\x12\x06\x80\ - \x02\x06\x9b\x02\x07\x1a\xaa\x02\x20A\x20streaming\x20configuration\x20t\ - o\x20apply\x20when\x20buffer\x20flushing\x20occurs.\n\x20Streaming\x20is\ - \x20active\x20from\x20the\x20time\x20the\x20flush\x20of\x20the\x20specif\ - ied\x20buffers\x20begins\x20until\x20whichever\x20of\n\x20the\x20followi\ - ng\x20happens\x20first:\n\x20\x20\x20*\x20[required]\x20The\x20session\ - \x20ID\x20changes\n\x20\x20\x20*\x20[optional,\x20configurable]\x20The\ - \x20maximum\x20number\x20of\x20logs\x20is\x20reached\n\n\x11\n\t\x04\x01\ - \x03\x07\x03\x02\x03\0\x01\x12\x04\x80\x02\x0e\x17\nM\n\n\x04\x01\x03\ - \x07\x03\x02\x03\0\x03\0\x12\x06\x82\x02\x08\x8d\x02\t\x1a7\x20The\x20cr\ - iteria\x20that\x20can\x20be\x20used\x20to\x20terminate\x20streaming.\n\n\ - \x13\n\x0b\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x01\x12\x04\x82\x02\x10$\ - \n\x16\n\x0c\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x03\0\x12\x06\x83\x02\n\ - \x86\x02\x0b\n\x15\n\r\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x03\0\x01\x12\ - \x04\x83\x02\x12\x1b\nJ\n\x0e\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x03\0\ - \x02\0\x12\x04\x85\x02\x0cG\x1a2\x20The\x20maximum\x20number\x20of\x20lo\ - gs\x20that\x20can\x20be\x20streamed.\n\n\x17\n\x0f\x04\x01\x03\x07\x03\ - \x02\x03\0\x03\0\x03\0\x02\0\x05\x12\x04\x85\x02\x0c\x12\n\x17\n\x0f\x04\ - \x01\x03\x07\x03\x02\x03\0\x03\0\x03\0\x02\0\x01\x12\x04\x85\x02\x13!\n\ - \x17\n\x0f\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x03\0\x02\0\x03\x12\x04\ - \x85\x02$%\n\x17\n\x0f\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x03\0\x02\0\ - \x08\x12\x04\x85\x02&F\n\x1b\n\x13\x04\x01\x03\x07\x03\x02\x03\0\x03\0\ - \x03\0\x02\0\x08\xaf\x08\x06\x04\x12\x04\x85\x02'E\n\x16\n\x0c\x04\x01\ - \x03\x07\x03\x02\x03\0\x03\0\x08\0\x12\x06\x88\x02\n\x8c\x02\x0b\n\x15\n\ - \r\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x08\0\x01\x12\x04\x88\x02\x10\x14\ - \n\x15\n\r\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x08\0\x02\x12\x04\x89\x02\ - \x0c.\n\x17\n\x0f\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x08\0\x02\xaf\x08\ - \x12\x04\x89\x02\x0c.\n\x14\n\x0c\x04\x01\x03\x07\x03\x02\x03\0\x03\0\ - \x02\0\x12\x04\x8b\x02\x0c%\n\x15\n\r\x04\x01\x03\x07\x03\x02\x03\0\x03\ - \0\x02\0\x06\x12\x04\x8b\x02\x0c\x15\n\x15\n\r\x04\x01\x03\x07\x03\x02\ - \x03\0\x03\0\x02\0\x01\x12\x04\x8b\x02\x16\x20\n\x15\n\r\x04\x01\x03\x07\ - \x03\x02\x03\0\x03\0\x02\0\x03\x12\x04\x8b\x02#$\n\xa6\x04\n\n\x04\x01\ - \x03\x07\x03\x02\x03\0\x02\0\x12\x04\x96\x02\x08=\x1a\x91\x04\x20The\x20\ - IDs\x20of\x20*streaming*\x20buffers\x20to\x20which\x20logs\x20should\x20\ - be\x20redirected.\n\x20If\x20a\x20specified\x20buffer\x20doesn't\x20exis\ - t\x20or\x20isn't\x20of\x20a\x20*streaming*\x20type,\x20logs\x20are\x20no\ - t\x20redirected\n\x20and\x20will\x20end\x20up\x20in\x20the\x20buffer(s)\ - \x20they\x20were\x20originally\x20supposed\x20to\x20land\x20in.\x20Other\ - wise,\x20they\x20are\n\x20redirected\x20to\x20all\x20specified,\x20exist\ - ing\x20destination\x20streaming\x20buffers.\n\x20Starting\x20with\x20cli\ - ent\x20configuration\x2011\x20and\x20up:\x20If\x20no\x20destination\x20s\ - treaming\x20buffers\x20are\x20specified,\n\x20the\x20logs\x20are\x20redi\ - rected\x20to\x20one\x20of\x20the\x20existing\x20continuous\x20streaming\ - \x20buffers,\x20if\x20such\x20a\x20buffer\n\x20exists.\n\n\x13\n\x0b\x04\ - \x01\x03\x07\x03\x02\x03\0\x02\0\x04\x12\x04\x96\x02\x08\x10\n\x13\n\x0b\ - \x04\x01\x03\x07\x03\x02\x03\0\x02\0\x05\x12\x04\x96\x02\x11\x17\n\x13\n\ - \x0b\x04\x01\x03\x07\x03\x02\x03\0\x02\0\x01\x12\x04\x96\x02\x188\n\x13\ - \n\x0b\x04\x01\x03\x07\x03\x02\x03\0\x02\0\x03\x12\x04\x96\x02;<\n\xa8\ - \x01\n\n\x04\x01\x03\x07\x03\x02\x03\0\x02\x01\x12\x04\x9a\x02\x08?\x1a\ - \x93\x01\x20Additional\x20termination\x20criteria\x20used\x20to\x20stop\ - \x20streaming.\x20Apart\x20from\x20the\x20criteria\x20specified\x20here,\ - \n\x20a\x20change\x20in\x20session\x20ID\x20will\x20also\x20stop\x20stre\ - aming.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\x02\x03\0\x02\x01\x04\x12\x04\ - \x9a\x02\x08\x10\n\x13\n\x0b\x04\x01\x03\x07\x03\x02\x03\0\x02\x01\x06\ - \x12\x04\x9a\x02\x11%\n\x13\n\x0b\x04\x01\x03\x07\x03\x02\x03\0\x02\x01\ - \x01\x12\x04\x9a\x02&:\n\x13\n\x0b\x04\x01\x03\x07\x03\x02\x03\0\x02\x01\ - \x03\x12\x04\x9a\x02=>\n\x85\x01\n\x08\x04\x01\x03\x07\x03\x02\x02\0\x12\ - \x04\x9f\x02\x06%\x1as\x20An\x20optional\x20array\x20indicating\x20which\ - \x20buffers\x20should\x20be\x20flushed.\x20An\x20empty\x20array\x20or\ - \x20no\x20array\n\x20will\x20flush\x20all\x20buffers.\n\n\x11\n\t\x04\ - \x01\x03\x07\x03\x02\x02\0\x04\x12\x04\x9f\x02\x06\x0e\n\x11\n\t\x04\x01\ - \x03\x07\x03\x02\x02\0\x05\x12\x04\x9f\x02\x0f\x15\n\x11\n\t\x04\x01\x03\ - \x07\x03\x02\x02\0\x01\x12\x04\x9f\x02\x16\x20\n\x11\n\t\x04\x01\x03\x07\ - \x03\x02\x02\0\x03\x12\x04\x9f\x02#$\n\xa8\x01\n\x08\x04\x01\x03\x07\x03\ - \x02\x02\x01\x12\x04\xa3\x02\x06=\x1a\x95\x01\x20An\x20identifier\x20use\ - d\x20to\x20match\x20this\x20action\x20with\x20a\x20specific\x20workflow\ - \x20rule.\x20This\x20should\n\x20be\x20included\x20as\x20the\x20associat\ - ed\x20listener_ids\x20in\x20the\x20matching\x20log.\n\n\x11\n\t\x04\x01\ - \x03\x07\x03\x02\x02\x01\x05\x12\x04\xa3\x02\x06\x0c\n\x11\n\t\x04\x01\ - \x03\x07\x03\x02\x02\x01\x01\x12\x04\xa3\x02\r\x0f\n\x11\n\t\x04\x01\x03\ - \x07\x03\x02\x02\x01\x03\x12\x04\xa3\x02\x12\x13\n\x11\n\t\x04\x01\x03\ - \x07\x03\x02\x02\x01\x08\x12\x04\xa3\x02\x14<\n\x14\n\x0c\x04\x01\x03\ - \x07\x03\x02\x02\x01\x08\xaf\x08\x0e\x12\x04\xa3\x02\x15;\n\xb8\x01\n\ - \x08\x04\x01\x03\x07\x03\x02\x02\x02\x12\x04\xa7\x02\x06\x1e\x1a\xa5\x01\ - \x20The\x20streaming\x20configuration\x20to\x20apply\x20when\x20buffer\ - \x20flushing\x20occurs.\x20If\x20not\x20specified,\x20no\x20subsequent\n\ - \x20log\x20streaming\x20will\x20occur\x20when\x20the\x20specified\x20buf\ - fers\x20are\x20flushed.\n\n\x11\n\t\x04\x01\x03\x07\x03\x02\x02\x02\x06\ - \x12\x04\xa7\x02\x06\x0f\n\x11\n\t\x04\x01\x03\x07\x03\x02\x02\x02\x01\ - \x12\x04\xa7\x02\x10\x19\n\x11\n\t\x04\x01\x03\x07\x03\x02\x02\x02\x03\ - \x12\x04\xa7\x02\x1c\x1d\n,\n\x06\x04\x01\x03\x07\x03\x03\x12\x06\xab\ - \x02\x04\xd3\x02\x05\x1a\x1a\x20Emit\x20a\x20synthetic\x20metric.\n\n\ - \x0f\n\x07\x04\x01\x03\x07\x03\x03\x01\x12\x04\xab\x02\x0c\x1c\n\xd2\x03\ - \n\x08\x04\x01\x03\x07\x03\x03\x02\0\x12\x04\xb3\x02\x06=\x1a\xbf\x03\ - \x20The\x20ID\x20of\x20a\x20metric.\x20If\x20multiple\x20actions\x20have\ - \x20them\x20same\x20ID\x20and\x20are\x20performed\n\x20as\x20the\x20resu\ - lt\x20of\x20processing\x20the\x20same\x20event\x20(i.e.\x20log)\x20a\x20\ - client\x20performs\x20only\x20one\n\x20of\x20the\x20actions.\x20The\x20c\ - lient\x20emit\x20a\x20stat\x20with\x20a\x20name\x20that\x20follows\n\x20\ - the\x20following\x20format\x20\"workflow_actions::\".\n\x20As\x20the\ + \x02\x05\x06\x12\x04\xe9\x01\n\x1c\n\x13\n\x0b\x04\x01\x03\x07\x03\x01\ + \x03\x02\x02\x05\x01\x12\x04\xe9\x01\x1d#\n\x13\n\x0b\x04\x01\x03\x07\ + \x03\x01\x03\x02\x02\x05\x03\x12\x04\xe9\x01&'\n\x10\n\x08\x04\x01\x03\ + \x07\x03\x01\x02\0\x12\x04\xed\x01\x06\x19\n\x11\n\t\x04\x01\x03\x07\x03\ + \x01\x02\0\x05\x12\x04\xed\x01\x06\x0c\n\x11\n\t\x04\x01\x03\x07\x03\x01\ + \x02\0\x01\x12\x04\xed\x01\r\x14\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\0\ + \x03\x12\x04\xed\x01\x17\x18\n\x10\n\x08\x04\x01\x03\x07\x03\x01\x02\x01\ + \x12\x04\xee\x01\x06)\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x01\x04\x12\ + \x04\xee\x01\x06\x0e\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x01\x06\x12\ + \x04\xee\x01\x0f\x1d\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x01\x01\x12\ + \x04\xee\x01\x1e$\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x01\x03\x12\x04\ + \xee\x01'(\n\xa3\x02\n\x08\x04\x01\x03\x07\x03\x01\x02\x02\x12\x04\xf3\ + \x01\x06\x14\x1a\x90\x02\x20A\x20unique\x20identifier\x20for\x20the\x20a\ + ction.\x20If\x20multiple\x20generate\x20log\x20actions\x20have\x20the\ + \x20same\x20ID\x20and\n\x20are\x20performed\x20as\x20the\x20result\x20of\ + \x20processing\x20the\x20same\x20log,\x20a\x20client\x20will\x20emit\x20\ + only\x20a\x20single\n\x20log\x20as\x20the\x20result.\x20This\x20implies\ + \x20that\x20the\x20resulting\x20logs\x20in\x20this\x20case\x20should\x20\ + be\x20identical.\n\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x02\x05\x12\x04\ + \xf3\x01\x06\x0c\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x02\x01\x12\x04\ + \xf3\x01\r\x0f\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x02\x03\x12\x04\xf3\ + \x01\x12\x13\nq\n\x08\x04\x01\x03\x07\x03\x01\x02\x03\x12\x04\xf7\x01\ + \x06\x1a\x1a_\x20Should\x20be\x20one\x20of\x20the\x20log\x20types\x20in\ + \x20buffer_log.fbs.\x20If\x20unset\x20the\x20default\x20is\x200\x20which\ + \x20is\n\x20Normal.\n\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x03\x05\x12\ + \x04\xf7\x01\x06\x0c\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x03\x01\x12\ + \x04\xf7\x01\r\x15\n\x11\n\t\x04\x01\x03\x07\x03\x01\x02\x03\x03\x12\x04\ + \xf7\x01\x18\x19\n\xf5\x01\n\x06\x04\x01\x03\x07\x03\x02\x12\x06\xfd\x01\ + \x04\xab\x02\x05\x1a\xe2\x01\x20Flush\x20the\x20content\x20of\x20the\x20\ + specified\x20buffer(s)\x20to\x20the\x20bitdrift\x20control\x20plane,\x20\ + with\x20the\x20option\x20to\x20continue\n\x20streaming\x20logs\x20incomi\ + ng\x20to\x20the\x20buffer(s)\x20to\x20remote\x20services,\x20until\x20on\ + e\x20of\x20the\x20specified\x20termination\n\x20conditions\x20is\x20met.\ + \n\n\x0f\n\x07\x04\x01\x03\x07\x03\x02\x01\x12\x04\xfd\x01\x0c\x1e\n\xbf\ + \x02\n\x08\x04\x01\x03\x07\x03\x02\x03\0\x12\x06\x83\x02\x06\x9e\x02\x07\ + \x1a\xaa\x02\x20A\x20streaming\x20configuration\x20to\x20apply\x20when\ + \x20buffer\x20flushing\x20occurs.\n\x20Streaming\x20is\x20active\x20from\ + \x20the\x20time\x20the\x20flush\x20of\x20the\x20specified\x20buffers\x20\ + begins\x20until\x20whichever\x20of\n\x20the\x20following\x20happens\x20f\ + irst:\n\x20\x20\x20*\x20[required]\x20The\x20session\x20ID\x20changes\n\ + \x20\x20\x20*\x20[optional,\x20configurable]\x20The\x20maximum\x20number\ + \x20of\x20logs\x20is\x20reached\n\n\x11\n\t\x04\x01\x03\x07\x03\x02\x03\ + \0\x01\x12\x04\x83\x02\x0e\x17\nM\n\n\x04\x01\x03\x07\x03\x02\x03\0\x03\ + \0\x12\x06\x85\x02\x08\x90\x02\t\x1a7\x20The\x20criteria\x20that\x20can\ + \x20be\x20used\x20to\x20terminate\x20streaming.\n\n\x13\n\x0b\x04\x01\ + \x03\x07\x03\x02\x03\0\x03\0\x01\x12\x04\x85\x02\x10$\n\x16\n\x0c\x04\ + \x01\x03\x07\x03\x02\x03\0\x03\0\x03\0\x12\x06\x86\x02\n\x89\x02\x0b\n\ + \x15\n\r\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x03\0\x01\x12\x04\x86\x02\ + \x12\x1b\nJ\n\x0e\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x03\0\x02\0\x12\ + \x04\x88\x02\x0cG\x1a2\x20The\x20maximum\x20number\x20of\x20logs\x20that\ + \x20can\x20be\x20streamed.\n\n\x17\n\x0f\x04\x01\x03\x07\x03\x02\x03\0\ + \x03\0\x03\0\x02\0\x05\x12\x04\x88\x02\x0c\x12\n\x17\n\x0f\x04\x01\x03\ + \x07\x03\x02\x03\0\x03\0\x03\0\x02\0\x01\x12\x04\x88\x02\x13!\n\x17\n\ + \x0f\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x03\0\x02\0\x03\x12\x04\x88\x02\ + $%\n\x17\n\x0f\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x03\0\x02\0\x08\x12\ + \x04\x88\x02&F\n\x1b\n\x13\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x03\0\x02\ + \0\x08\xaf\x08\x06\x04\x12\x04\x88\x02'E\n\x16\n\x0c\x04\x01\x03\x07\x03\ + \x02\x03\0\x03\0\x08\0\x12\x06\x8b\x02\n\x8f\x02\x0b\n\x15\n\r\x04\x01\ + \x03\x07\x03\x02\x03\0\x03\0\x08\0\x01\x12\x04\x8b\x02\x10\x14\n\x15\n\r\ + \x04\x01\x03\x07\x03\x02\x03\0\x03\0\x08\0\x02\x12\x04\x8c\x02\x0c.\n\ + \x17\n\x0f\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x08\0\x02\xaf\x08\x12\x04\ + \x8c\x02\x0c.\n\x14\n\x0c\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x02\0\x12\ + \x04\x8e\x02\x0c%\n\x15\n\r\x04\x01\x03\x07\x03\x02\x03\0\x03\0\x02\0\ + \x06\x12\x04\x8e\x02\x0c\x15\n\x15\n\r\x04\x01\x03\x07\x03\x02\x03\0\x03\ + \0\x02\0\x01\x12\x04\x8e\x02\x16\x20\n\x15\n\r\x04\x01\x03\x07\x03\x02\ + \x03\0\x03\0\x02\0\x03\x12\x04\x8e\x02#$\n\xa6\x04\n\n\x04\x01\x03\x07\ + \x03\x02\x03\0\x02\0\x12\x04\x99\x02\x08=\x1a\x91\x04\x20The\x20IDs\x20o\ + f\x20*streaming*\x20buffers\x20to\x20which\x20logs\x20should\x20be\x20re\ + directed.\n\x20If\x20a\x20specified\x20buffer\x20doesn't\x20exist\x20or\ + \x20isn't\x20of\x20a\x20*streaming*\x20type,\x20logs\x20are\x20not\x20re\ + directed\n\x20and\x20will\x20end\x20up\x20in\x20the\x20buffer(s)\x20they\ + \x20were\x20originally\x20supposed\x20to\x20land\x20in.\x20Otherwise,\ + \x20they\x20are\n\x20redirected\x20to\x20all\x20specified,\x20existing\ + \x20destination\x20streaming\x20buffers.\n\x20Starting\x20with\x20client\ + \x20configuration\x2011\x20and\x20up:\x20If\x20no\x20destination\x20stre\ + aming\x20buffers\x20are\x20specified,\n\x20the\x20logs\x20are\x20redirec\ + ted\x20to\x20one\x20of\x20the\x20existing\x20continuous\x20streaming\x20\ + buffers,\x20if\x20such\x20a\x20buffer\n\x20exists.\n\n\x13\n\x0b\x04\x01\ + \x03\x07\x03\x02\x03\0\x02\0\x04\x12\x04\x99\x02\x08\x10\n\x13\n\x0b\x04\ + \x01\x03\x07\x03\x02\x03\0\x02\0\x05\x12\x04\x99\x02\x11\x17\n\x13\n\x0b\ + \x04\x01\x03\x07\x03\x02\x03\0\x02\0\x01\x12\x04\x99\x02\x188\n\x13\n\ + \x0b\x04\x01\x03\x07\x03\x02\x03\0\x02\0\x03\x12\x04\x99\x02;<\n\xa8\x01\ + \n\n\x04\x01\x03\x07\x03\x02\x03\0\x02\x01\x12\x04\x9d\x02\x08?\x1a\x93\ + \x01\x20Additional\x20termination\x20criteria\x20used\x20to\x20stop\x20s\ + treaming.\x20Apart\x20from\x20the\x20criteria\x20specified\x20here,\n\ + \x20a\x20change\x20in\x20session\x20ID\x20will\x20also\x20stop\x20stream\ + ing.\n\n\x13\n\x0b\x04\x01\x03\x07\x03\x02\x03\0\x02\x01\x04\x12\x04\x9d\ + \x02\x08\x10\n\x13\n\x0b\x04\x01\x03\x07\x03\x02\x03\0\x02\x01\x06\x12\ + \x04\x9d\x02\x11%\n\x13\n\x0b\x04\x01\x03\x07\x03\x02\x03\0\x02\x01\x01\ + \x12\x04\x9d\x02&:\n\x13\n\x0b\x04\x01\x03\x07\x03\x02\x03\0\x02\x01\x03\ + \x12\x04\x9d\x02=>\n\x85\x01\n\x08\x04\x01\x03\x07\x03\x02\x02\0\x12\x04\ + \xa2\x02\x06%\x1as\x20An\x20optional\x20array\x20indicating\x20which\x20\ + buffers\x20should\x20be\x20flushed.\x20An\x20empty\x20array\x20or\x20no\ + \x20array\n\x20will\x20flush\x20all\x20buffers.\n\n\x11\n\t\x04\x01\x03\ + \x07\x03\x02\x02\0\x04\x12\x04\xa2\x02\x06\x0e\n\x11\n\t\x04\x01\x03\x07\ + \x03\x02\x02\0\x05\x12\x04\xa2\x02\x0f\x15\n\x11\n\t\x04\x01\x03\x07\x03\ + \x02\x02\0\x01\x12\x04\xa2\x02\x16\x20\n\x11\n\t\x04\x01\x03\x07\x03\x02\ + \x02\0\x03\x12\x04\xa2\x02#$\n\xa8\x01\n\x08\x04\x01\x03\x07\x03\x02\x02\ + \x01\x12\x04\xa6\x02\x06=\x1a\x95\x01\x20An\x20identifier\x20used\x20to\ + \x20match\x20this\x20action\x20with\x20a\x20specific\x20workflow\x20rule\ + .\x20This\x20should\n\x20be\x20included\x20as\x20the\x20associated\x20li\ + stener_ids\x20in\x20the\x20matching\x20log.\n\n\x11\n\t\x04\x01\x03\x07\ + \x03\x02\x02\x01\x05\x12\x04\xa6\x02\x06\x0c\n\x11\n\t\x04\x01\x03\x07\ + \x03\x02\x02\x01\x01\x12\x04\xa6\x02\r\x0f\n\x11\n\t\x04\x01\x03\x07\x03\ + \x02\x02\x01\x03\x12\x04\xa6\x02\x12\x13\n\x11\n\t\x04\x01\x03\x07\x03\ + \x02\x02\x01\x08\x12\x04\xa6\x02\x14<\n\x14\n\x0c\x04\x01\x03\x07\x03\ + \x02\x02\x01\x08\xaf\x08\x0e\x12\x04\xa6\x02\x15;\n\xb8\x01\n\x08\x04\ + \x01\x03\x07\x03\x02\x02\x02\x12\x04\xaa\x02\x06\x1e\x1a\xa5\x01\x20The\ + \x20streaming\x20configuration\x20to\x20apply\x20when\x20buffer\x20flush\ + ing\x20occurs.\x20If\x20not\x20specified,\x20no\x20subsequent\n\x20log\ + \x20streaming\x20will\x20occur\x20when\x20the\x20specified\x20buffers\ + \x20are\x20flushed.\n\n\x11\n\t\x04\x01\x03\x07\x03\x02\x02\x02\x06\x12\ + \x04\xaa\x02\x06\x0f\n\x11\n\t\x04\x01\x03\x07\x03\x02\x02\x02\x01\x12\ + \x04\xaa\x02\x10\x19\n\x11\n\t\x04\x01\x03\x07\x03\x02\x02\x02\x03\x12\ + \x04\xaa\x02\x1c\x1d\n,\n\x06\x04\x01\x03\x07\x03\x03\x12\x06\xae\x02\ + \x04\xd6\x02\x05\x1a\x1a\x20Emit\x20a\x20synthetic\x20metric.\n\n\x0f\n\ + \x07\x04\x01\x03\x07\x03\x03\x01\x12\x04\xae\x02\x0c\x1c\n\xd2\x03\n\x08\ + \x04\x01\x03\x07\x03\x03\x02\0\x12\x04\xb6\x02\x06=\x1a\xbf\x03\x20The\ + \x20ID\x20of\x20a\x20metric.\x20If\x20multiple\x20actions\x20have\x20the\ + m\x20same\x20ID\x20and\x20are\x20performed\n\x20as\x20the\x20result\x20o\ + f\x20processing\x20the\x20same\x20event\x20(i.e.\x20log)\x20a\x20client\ + \x20performs\x20only\x20one\n\x20of\x20the\x20actions.\x20The\x20client\ + \x20emit\x20a\x20stat\x20with\x20a\x20name\x20that\x20follows\n\x20the\ + \x20following\x20format\x20\"workflow_actions::\".\n\x20As\x20the\ \x20identifier\x20becomes\x20a\x20part\x20of\x20metric's\x20name\x20it\ \x20must\x20meet\x20the\x20requirements\n\x20of\x20prometheus\x20metric\ \x20name.\x20In\x20other\x20words\x20it\x20needs\x20to\x20match\n\x20reg\ ex\x20\"[a-zA-Z_][a-zA-Z0-9_]*\".\n\n\x11\n\t\x04\x01\x03\x07\x03\x03\ - \x02\0\x05\x12\x04\xb3\x02\x06\x0c\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\ - \0\x01\x12\x04\xb3\x02\r\x0f\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\0\x03\ - \x12\x04\xb3\x02\x12\x13\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\0\x08\x12\ - \x04\xb3\x02\x14<\n\x14\n\x0c\x04\x01\x03\x07\x03\x03\x02\0\x08\xaf\x08\ - \x0e\x12\x04\xb3\x02\x15;\n)\n\x08\x04\x01\x03\x07\x03\x03\x08\0\x12\x06\ - \xb6\x02\x06\xbe\x02\x07\x1a\x15\x20The\x20type\x20of\x20metric.\n\n\x11\ - \n\t\x04\x01\x03\x07\x03\x03\x08\0\x01\x12\x04\xb6\x02\x0c\x17\n\x11\n\t\ - \x04\x01\x03\x07\x03\x03\x08\0\x02\x12\x04\xb7\x02\x08*\n\x13\n\x0b\x04\ - \x01\x03\x07\x03\x03\x08\0\x02\xaf\x08\x12\x04\xb7\x02\x08*\n\x1e\n\x08\ - \x04\x01\x03\x07\x03\x03\x02\x01\x12\x04\xba\x02\x08\x1c\x1a\x0c\x20A\ - \x20counter.\n\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\x01\x06\x12\x04\xba\ - \x02\x08\x0f\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\x01\x01\x12\x04\xba\ - \x02\x10\x17\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\x01\x03\x12\x04\xba\ - \x02\x1a\x1b\n\x20\n\x08\x04\x01\x03\x07\x03\x03\x02\x02\x12\x04\xbd\x02\ + \x02\0\x05\x12\x04\xb6\x02\x06\x0c\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\ + \0\x01\x12\x04\xb6\x02\r\x0f\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\0\x03\ + \x12\x04\xb6\x02\x12\x13\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\0\x08\x12\ + \x04\xb6\x02\x14<\n\x14\n\x0c\x04\x01\x03\x07\x03\x03\x02\0\x08\xaf\x08\ + \x0e\x12\x04\xb6\x02\x15;\n)\n\x08\x04\x01\x03\x07\x03\x03\x08\0\x12\x06\ + \xb9\x02\x06\xc1\x02\x07\x1a\x15\x20The\x20type\x20of\x20metric.\n\n\x11\ + \n\t\x04\x01\x03\x07\x03\x03\x08\0\x01\x12\x04\xb9\x02\x0c\x17\n\x11\n\t\ + \x04\x01\x03\x07\x03\x03\x08\0\x02\x12\x04\xba\x02\x08*\n\x13\n\x0b\x04\ + \x01\x03\x07\x03\x03\x08\0\x02\xaf\x08\x12\x04\xba\x02\x08*\n\x1e\n\x08\ + \x04\x01\x03\x07\x03\x03\x02\x01\x12\x04\xbd\x02\x08\x1c\x1a\x0c\x20A\ + \x20counter.\n\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\x01\x06\x12\x04\xbd\ + \x02\x08\x0f\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\x01\x01\x12\x04\xbd\ + \x02\x10\x17\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\x01\x03\x12\x04\xbd\ + \x02\x1a\x1b\n\x20\n\x08\x04\x01\x03\x07\x03\x03\x02\x02\x12\x04\xc0\x02\ \x08\x20\x1a\x0e\x20A\x20histogram.\n\n\x11\n\t\x04\x01\x03\x07\x03\x03\ - \x02\x02\x06\x12\x04\xbd\x02\x08\x11\n\x11\n\t\x04\x01\x03\x07\x03\x03\ - \x02\x02\x01\x12\x04\xbd\x02\x12\x1b\n\x11\n\t\x04\x01\x03\x07\x03\x03\ - \x02\x02\x03\x12\x04\xbd\x02\x1e\x1f\n\xa7\x01\n\x08\x04\x01\x03\x07\x03\ - \x03\x08\x01\x12\x06\xc1\x02\x06\xc9\x02\x07\x1a\x92\x01\x20The\x20value\ + \x02\x02\x06\x12\x04\xc0\x02\x08\x11\n\x11\n\t\x04\x01\x03\x07\x03\x03\ + \x02\x02\x01\x12\x04\xc0\x02\x12\x1b\n\x11\n\t\x04\x01\x03\x07\x03\x03\ + \x02\x02\x03\x12\x04\xc0\x02\x1e\x1f\n\xa7\x01\n\x08\x04\x01\x03\x07\x03\ + \x03\x08\x01\x12\x06\xc4\x02\x06\xcc\x02\x07\x1a\x92\x01\x20The\x20value\ \x20that\x20is\x20added\x20to\x20the\x20metric.\x20For\x20a\x20counter\ \x20the\x20value\x20is\x20added\x20to\x20the\x20counter,\x20while\x20for\ \x20a\x20histogram\x20the\x20value\x20is\x20recorded\x20as\x20a\x20sampl\ - e.\n\n\x11\n\t\x04\x01\x03\x07\x03\x03\x08\x01\x01\x12\x04\xc1\x02\x0c\ - \x20\n\x11\n\t\x04\x01\x03\x07\x03\x03\x08\x01\x02\x12\x04\xc2\x02\x08*\ - \n\x13\n\x0b\x04\x01\x03\x07\x03\x03\x08\x01\x02\xaf\x08\x12\x04\xc2\x02\ - \x08*\n\"\n\x08\x04\x01\x03\x07\x03\x03\x02\x03\x12\x04\xc5\x02\x08\x19\ + e.\n\n\x11\n\t\x04\x01\x03\x07\x03\x03\x08\x01\x01\x12\x04\xc4\x02\x0c\ + \x20\n\x11\n\t\x04\x01\x03\x07\x03\x03\x08\x01\x02\x12\x04\xc5\x02\x08*\ + \n\x13\n\x0b\x04\x01\x03\x07\x03\x03\x08\x01\x02\xaf\x08\x12\x04\xc5\x02\ + \x08*\n\"\n\x08\x04\x01\x03\x07\x03\x03\x02\x03\x12\x04\xc8\x02\x08\x19\ \x1a\x10\x20A\x20fixed\x20value.\n\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\ - \x03\x05\x12\x04\xc5\x02\x08\x0e\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\ - \x03\x01\x12\x04\xc5\x02\x0f\x14\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\ - \x03\x03\x12\x04\xc5\x02\x17\x18\n\xab\x01\n\x08\x04\x01\x03\x07\x03\x03\ - \x02\x04\x12\x04\xc8\x02\x08+\x1a\x98\x01\x20The\x20value\x20to\x20add\ + \x03\x05\x12\x04\xc8\x02\x08\x0e\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\ + \x03\x01\x12\x04\xc8\x02\x0f\x14\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\ + \x03\x03\x12\x04\xc8\x02\x17\x18\n\xab\x01\n\x08\x04\x01\x03\x07\x03\x03\ + \x02\x04\x12\x04\xcb\x02\x08+\x1a\x98\x01\x20The\x20value\x20to\x20add\ \x20to\x20the\x20metric\x20is\x20extracted\x20from\x20a\x20field\x20in\ \x20the\x20log.\x20If\x20the\x20field\x20is\x20not\x20present\x20or\x20n\ ot\x20convertible\x20to\x20a\x20number,\x20no\x20metric\x20is\x20emitted\ - .\n\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\x04\x06\x12\x04\xc8\x02\x08\ - \x16\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\x04\x01\x12\x04\xc8\x02\x17&\ - \n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\x04\x03\x12\x04\xc8\x02)*\n,\n\ - \x08\x04\x01\x03\x07\x03\x03\x02\x05\x12\x04\xcc\x02\x06\x1c\x1a\x1a\x20\ + .\n\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\x04\x06\x12\x04\xcb\x02\x08\ + \x16\n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\x04\x01\x12\x04\xcb\x02\x17&\ + \n\x11\n\t\x04\x01\x03\x07\x03\x03\x02\x04\x03\x12\x04\xcb\x02)*\n,\n\ + \x08\x04\x01\x03\x07\x03\x03\x02\x05\x12\x04\xcf\x02\x06\x1c\x1a\x1a\x20\ The\x20tags\x20for\x20the\x20metric.\n\n\x11\n\t\x04\x01\x03\x07\x03\x03\ - \x02\x05\x04\x12\x04\xcc\x02\x06\x0e\n\x11\n\t\x04\x01\x03\x07\x03\x03\ - \x02\x05\x06\x12\x04\xcc\x02\x0f\x12\n\x11\n\t\x04\x01\x03\x07\x03\x03\ - \x02\x05\x01\x12\x04\xcc\x02\x13\x17\n\x11\n\t\x04\x01\x03\x07\x03\x03\ - \x02\x05\x03\x12\x04\xcc\x02\x1a\x1b\n(\n\x08\x04\x01\x03\x07\x03\x03\ - \x03\0\x12\x04\xcf\x02\x06\x18\x1a\x16\x20A\x20synthetic\x20counter.\n\n\ - \x11\n\t\x04\x01\x03\x07\x03\x03\x03\0\x01\x12\x04\xcf\x02\x0e\x15\n*\n\ - \x08\x04\x01\x03\x07\x03\x03\x03\x01\x12\x04\xd2\x02\x06\x1a\x1a\x18\x20\ + \x02\x05\x04\x12\x04\xcf\x02\x06\x0e\n\x11\n\t\x04\x01\x03\x07\x03\x03\ + \x02\x05\x06\x12\x04\xcf\x02\x0f\x12\n\x11\n\t\x04\x01\x03\x07\x03\x03\ + \x02\x05\x01\x12\x04\xcf\x02\x13\x17\n\x11\n\t\x04\x01\x03\x07\x03\x03\ + \x02\x05\x03\x12\x04\xcf\x02\x1a\x1b\n(\n\x08\x04\x01\x03\x07\x03\x03\ + \x03\0\x12\x04\xd2\x02\x06\x18\x1a\x16\x20A\x20synthetic\x20counter.\n\n\ + \x11\n\t\x04\x01\x03\x07\x03\x03\x03\0\x01\x12\x04\xd2\x02\x0e\x15\n*\n\ + \x08\x04\x01\x03\x07\x03\x03\x03\x01\x12\x04\xd5\x02\x06\x1a\x1a\x18\x20\ A\x20synthetic\x20histogram.\n\n\x11\n\t\x04\x01\x03\x07\x03\x03\x03\x01\ - \x01\x12\x04\xd2\x02\x0e\x17\n\xa5\x02\n\x06\x04\x01\x03\x07\x03\x04\x12\ - \x06\xda\x02\x04\xfd\x02\x05\x1a\x92\x02\x20Emit\x20data\x20for\x20Sanke\ + \x01\x12\x04\xd5\x02\x0e\x17\n\xa5\x02\n\x06\x04\x01\x03\x07\x03\x04\x12\ + \x06\xdd\x02\x04\x80\x03\x05\x1a\x92\x02\x20Emit\x20data\x20for\x20Sanke\ y\x20diagram.\n\x20The\x20action\x20requires\x20at\x20least\x20one\x20tr\ ansition\x20on\x20the\x20path\x20to\x20the\x20action\x20to\x20have\n\x20\ `SankeyDiagramValueExtraction`\x20extension.\n\x20Refer\x20to\x20`Sankey\ DiagramValueExtraction`\x20to\x20learn\x20more\x20about\x20how\x20the\ \x20values\n\x20for\x20the\x20Sankey\x20diagram\x20nodes\x20are\x20extra\ - cted.\n\n\x0f\n\x07\x04\x01\x03\x07\x03\x04\x01\x12\x04\xda\x02\x0c#\n\ - \xdb\x03\n\x08\x04\x01\x03\x07\x03\x04\x02\0\x12\x04\xe2\x02\x06=\x1a\ + cted.\n\n\x0f\n\x07\x04\x01\x03\x07\x03\x04\x01\x12\x04\xdd\x02\x0c#\n\ + \xdb\x03\n\x08\x04\x01\x03\x07\x03\x04\x02\0\x12\x04\xe5\x02\x06=\x1a\ \xc8\x03\x20The\x20ID\x20of\x20a\x20Sankey\x20diagram.\x20If\x20multiple\ \x20diagrams\x20have\x20them\x20same\x20ID\x20and\x20are\x20performed\n\ \x20as\x20the\x20result\x20of\x20processing\x20the\x20same\x20event\x20(\ @@ -8440,12 +8489,12 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x20metric's\x20name\x20it\x20must\x20meet\x20the\x20requirements\n\x20o\ f\x20prometheus\x20metric\x20name.\x20In\x20other\x20words\x20it\x20need\ s\x20to\x20match\n\x20regex\x20\"[a-zA-Z_][a-zA-Z0-9_]*\".\n\n\x11\n\t\ - \x04\x01\x03\x07\x03\x04\x02\0\x05\x12\x04\xe2\x02\x06\x0c\n\x11\n\t\x04\ - \x01\x03\x07\x03\x04\x02\0\x01\x12\x04\xe2\x02\r\x0f\n\x11\n\t\x04\x01\ - \x03\x07\x03\x04\x02\0\x03\x12\x04\xe2\x02\x12\x13\n\x11\n\t\x04\x01\x03\ - \x07\x03\x04\x02\0\x08\x12\x04\xe2\x02\x14<\n\x14\n\x0c\x04\x01\x03\x07\ - \x03\x04\x02\0\x08\xaf\x08\x0e\x12\x04\xe2\x02\x15;\n\x97\t\n\x08\x04\ - \x01\x03\x07\x03\x04\x02\x01\x12\x04\xf8\x02\x068\x1a\x84\t\x20The\x20ma\ + \x04\x01\x03\x07\x03\x04\x02\0\x05\x12\x04\xe5\x02\x06\x0c\n\x11\n\t\x04\ + \x01\x03\x07\x03\x04\x02\0\x01\x12\x04\xe5\x02\r\x0f\n\x11\n\t\x04\x01\ + \x03\x07\x03\x04\x02\0\x03\x12\x04\xe5\x02\x12\x13\n\x11\n\t\x04\x01\x03\ + \x07\x03\x04\x02\0\x08\x12\x04\xe5\x02\x14<\n\x14\n\x0c\x04\x01\x03\x07\ + \x03\x04\x02\0\x08\xaf\x08\x0e\x12\x04\xe5\x02\x15;\n\x97\t\n\x08\x04\ + \x01\x03\x07\x03\x04\x02\x01\x12\x04\xfb\x02\x068\x1a\x84\t\x20The\x20ma\ ximum\x20number\x20of\x20node\x20values\x20that\x20can\x20be\x20extracte\ d\x20for\x20a\x20given\x20Sankey\x20diagram.\n\x20Extracted\x20values\ \x20are\x20kept\x20in\x20FIFO\x20order,\x20and\x20once\x20the\x20limit\ @@ -8473,150 +8522,150 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x20->\x20B(5)\x20->\x20C,\x20the\x20final\x20Sankey\x20diagram\x20will\ \x20show\n\x20the\x20values\x20extracted\x20from\x20the\x20following\x20\ nodes\x20sequence:\x20A\x20->\x20B(3)\x20->\x20B(4)\x20->\x20B(5)\x20->\ - \x20C.\n\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x01\x05\x12\x04\xf8\x02\ - \x06\x0c\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x01\x01\x12\x04\xf8\x02\r\ - \x12\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x01\x03\x12\x04\xf8\x02\x15\ - \x16\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x01\x08\x12\x04\xf8\x02\x177\ + \x20C.\n\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x01\x05\x12\x04\xfb\x02\ + \x06\x0c\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x01\x01\x12\x04\xfb\x02\r\ + \x12\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x01\x03\x12\x04\xfb\x02\x15\ + \x16\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x01\x08\x12\x04\xfb\x02\x177\ \n\x15\n\r\x04\x01\x03\x07\x03\x04\x02\x01\x08\xaf\x08\x05\x04\x12\x04\ - \xf8\x02\x186\n\x9c\x01\n\x08\x04\x01\x03\x07\x03\x04\x02\x02\x12\x04\ - \xfc\x02\x06\x1c\x1a\x89\x01\x20Tags\x20for\x20a\x20counter\x20that\x20i\ + \xfb\x02\x186\n\x9c\x01\n\x08\x04\x01\x03\x07\x03\x04\x02\x02\x12\x04\ + \xff\x02\x06\x1c\x1a\x89\x01\x20Tags\x20for\x20a\x20counter\x20that\x20i\ s\x20emitted\x20when\x20a\x20Sankey\x20diagram\x20path\x20is\x20complete\ d.\n\x20Each\x20completion\x20of\x20the\x20path\x20increments\x20the\x20\ counter\x20by\x20one.\n\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x02\x04\ - \x12\x04\xfc\x02\x06\x0e\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x02\x06\ - \x12\x04\xfc\x02\x0f\x12\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x02\x01\ - \x12\x04\xfc\x02\x13\x17\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x02\x03\ - \x12\x04\xfc\x02\x1a\x1b\nC\n\x06\x04\x01\x03\x07\x03\x05\x12\x06\x80\ - \x03\x04\x95\x03\x05\x1a1\x20Wraps\x20a\x20tag\x20that\x20is\x20associat\ + \x12\x04\xff\x02\x06\x0e\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x02\x06\ + \x12\x04\xff\x02\x0f\x12\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x02\x01\ + \x12\x04\xff\x02\x13\x17\n\x11\n\t\x04\x01\x03\x07\x03\x04\x02\x02\x03\ + \x12\x04\xff\x02\x1a\x1b\nC\n\x06\x04\x01\x03\x07\x03\x05\x12\x06\x83\ + \x03\x04\x98\x03\x05\x1a1\x20Wraps\x20a\x20tag\x20that\x20is\x20associat\ ed\x20with\x20the\x20metric.\n\n\x0f\n\x07\x04\x01\x03\x07\x03\x05\x01\ - \x12\x04\x80\x03\x0c\x0f\n(\n\x08\x04\x01\x03\x07\x03\x05\x02\0\x12\x04\ - \x82\x03\x06?\x1a\x16\x20The\x20name\x20of\x20the\x20tag.\n\n\x11\n\t\ - \x04\x01\x03\x07\x03\x05\x02\0\x05\x12\x04\x82\x03\x06\x0c\n\x11\n\t\x04\ - \x01\x03\x07\x03\x05\x02\0\x01\x12\x04\x82\x03\r\x11\n\x11\n\t\x04\x01\ - \x03\x07\x03\x05\x02\0\x03\x12\x04\x82\x03\x14\x15\n\x11\n\t\x04\x01\x03\ - \x07\x03\x05\x02\0\x08\x12\x04\x82\x03\x16>\n\x14\n\x0c\x04\x01\x03\x07\ - \x03\x05\x02\0\x08\xaf\x08\x0e\x12\x04\x82\x03\x17=\n\x12\n\x08\x04\x01\ - \x03\x07\x03\x05\x08\0\x12\x06\x84\x03\x06\x91\x03\x07\n\x11\n\t\x04\x01\ - \x03\x07\x03\x05\x08\0\x01\x12\x04\x84\x03\x0c\x14\n\x11\n\t\x04\x01\x03\ - \x07\x03\x05\x08\0\x02\x12\x04\x85\x03\x08*\n\x13\n\x0b\x04\x01\x03\x07\ - \x03\x05\x08\0\x02\xaf\x08\x12\x04\x85\x03\x08*\n&\n\x08\x04\x01\x03\x07\ - \x03\x05\x02\x01\x12\x04\x88\x03\x08H\x1a\x14\x20A\x20fixed\x20tag\x20va\ - lue.\n\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x01\x05\x12\x04\x88\x03\x08\ - \x0e\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x01\x01\x12\x04\x88\x03\x0f\ - \x1a\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x01\x03\x12\x04\x88\x03\x1d\ - \x1e\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x01\x08\x12\x04\x88\x03\x1fG\ - \n\x14\n\x0c\x04\x01\x03\x07\x03\x05\x02\x01\x08\xaf\x08\x0e\x12\x04\x88\ - \x03\x20F\nu\n\x08\x04\x01\x03\x07\x03\x05\x02\x02\x12\x04\x8b\x03\x08+\ + \x12\x04\x83\x03\x0c\x0f\n(\n\x08\x04\x01\x03\x07\x03\x05\x02\0\x12\x04\ + \x85\x03\x06?\x1a\x16\x20The\x20name\x20of\x20the\x20tag.\n\n\x11\n\t\ + \x04\x01\x03\x07\x03\x05\x02\0\x05\x12\x04\x85\x03\x06\x0c\n\x11\n\t\x04\ + \x01\x03\x07\x03\x05\x02\0\x01\x12\x04\x85\x03\r\x11\n\x11\n\t\x04\x01\ + \x03\x07\x03\x05\x02\0\x03\x12\x04\x85\x03\x14\x15\n\x11\n\t\x04\x01\x03\ + \x07\x03\x05\x02\0\x08\x12\x04\x85\x03\x16>\n\x14\n\x0c\x04\x01\x03\x07\ + \x03\x05\x02\0\x08\xaf\x08\x0e\x12\x04\x85\x03\x17=\n\x12\n\x08\x04\x01\ + \x03\x07\x03\x05\x08\0\x12\x06\x87\x03\x06\x94\x03\x07\n\x11\n\t\x04\x01\ + \x03\x07\x03\x05\x08\0\x01\x12\x04\x87\x03\x0c\x14\n\x11\n\t\x04\x01\x03\ + \x07\x03\x05\x08\0\x02\x12\x04\x88\x03\x08*\n\x13\n\x0b\x04\x01\x03\x07\ + \x03\x05\x08\0\x02\xaf\x08\x12\x04\x88\x03\x08*\n&\n\x08\x04\x01\x03\x07\ + \x03\x05\x02\x01\x12\x04\x8b\x03\x08H\x1a\x14\x20A\x20fixed\x20tag\x20va\ + lue.\n\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x01\x05\x12\x04\x8b\x03\x08\ + \x0e\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x01\x01\x12\x04\x8b\x03\x0f\ + \x1a\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x01\x03\x12\x04\x8b\x03\x1d\ + \x1e\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x01\x08\x12\x04\x8b\x03\x1fG\ + \n\x14\n\x0c\x04\x01\x03\x07\x03\x05\x02\x01\x08\xaf\x08\x0e\x12\x04\x8b\ + \x03\x20F\nu\n\x08\x04\x01\x03\x07\x03\x05\x02\x02\x12\x04\x8e\x03\x08+\ \x1ac\x20The\x20tag\x20value\x20is\x20extracted\x20from\x20a\x20field\ \x20in\x20the\x20log.\x20If\x20the\x20field\x20is\x20not\x20present,\x20\ no\x20tag\x20is\x20added.\n\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x02\ - \x06\x12\x04\x8b\x03\x08\x16\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x02\ - \x01\x12\x04\x8b\x03\x17&\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x02\x03\ - \x12\x04\x8b\x03)*\nf\n\x08\x04\x01\x03\x07\x03\x05\x02\x03\x12\x04\x8e\ + \x06\x12\x04\x8e\x03\x08\x16\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x02\ + \x01\x12\x04\x8e\x03\x17&\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x02\x03\ + \x12\x04\x8e\x03)*\nf\n\x08\x04\x01\x03\x07\x03\x05\x02\x03\x12\x04\x91\ \x03\x08$\x1aT\x20The\x20tag\x20value\x20is\x20the\x20body\x20of\x20the\ \x20log.\x20If\x20the\x20body\x20is\x20not\x20present,\x20no\x20tag\x20i\ - s\x20added.\n\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x03\x05\x12\x04\x8e\ - \x03\x08\x0c\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x03\x01\x12\x04\x8e\ - \x03\r\x1f\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x03\x03\x12\x04\x8e\x03\ - \"#\n\x10\n\x08\x04\x01\x03\x07\x03\x05\x02\x04\x12\x04\x90\x03\x08+\n\ - \x11\n\t\x04\x01\x03\x07\x03\x05\x02\x04\x06\x12\x04\x90\x03\x08\x16\n\ - \x11\n\t\x04\x01\x03\x07\x03\x05\x02\x04\x01\x12\x04\x90\x03\x17&\n\x11\ - \n\t\x04\x01\x03\x07\x03\x05\x02\x04\x03\x12\x04\x90\x03)*\n\x0f\n\x07\ - \x04\x01\x03\x07\x03\x05\t\x12\x04\x93\x03\x06\x11\n\x10\n\x08\x04\x01\ - \x03\x07\x03\x05\t\0\x12\x04\x93\x03\x0f\x10\n\x11\n\t\x04\x01\x03\x07\ - \x03\x05\t\0\x01\x12\x04\x93\x03\x0f\x10\n\x11\n\t\x04\x01\x03\x07\x03\ - \x05\t\0\x02\x12\x04\x93\x03\x0f\x10\n\x0f\n\x07\x04\x01\x03\x07\x03\x05\ - \n\x12\x04\x94\x03\x06(\n\x10\n\x08\x04\x01\x03\x07\x03\x05\n\0\x12\x04\ - \x94\x03\x0f'\nA\n\x06\x04\x01\x03\x07\x03\x06\x12\x06\x98\x03\x04\x9a\ + s\x20added.\n\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x03\x05\x12\x04\x91\ + \x03\x08\x0c\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x03\x01\x12\x04\x91\ + \x03\r\x1f\n\x11\n\t\x04\x01\x03\x07\x03\x05\x02\x03\x03\x12\x04\x91\x03\ + \"#\n\x10\n\x08\x04\x01\x03\x07\x03\x05\x02\x04\x12\x04\x93\x03\x08+\n\ + \x11\n\t\x04\x01\x03\x07\x03\x05\x02\x04\x06\x12\x04\x93\x03\x08\x16\n\ + \x11\n\t\x04\x01\x03\x07\x03\x05\x02\x04\x01\x12\x04\x93\x03\x17&\n\x11\ + \n\t\x04\x01\x03\x07\x03\x05\x02\x04\x03\x12\x04\x93\x03)*\n\x0f\n\x07\ + \x04\x01\x03\x07\x03\x05\t\x12\x04\x96\x03\x06\x11\n\x10\n\x08\x04\x01\ + \x03\x07\x03\x05\t\0\x12\x04\x96\x03\x0f\x10\n\x11\n\t\x04\x01\x03\x07\ + \x03\x05\t\0\x01\x12\x04\x96\x03\x0f\x10\n\x11\n\t\x04\x01\x03\x07\x03\ + \x05\t\0\x02\x12\x04\x96\x03\x0f\x10\n\x0f\n\x07\x04\x01\x03\x07\x03\x05\ + \n\x12\x04\x97\x03\x06(\n\x10\n\x08\x04\x01\x03\x07\x03\x05\n\0\x12\x04\ + \x97\x03\x0f'\nA\n\x06\x04\x01\x03\x07\x03\x06\x12\x06\x9b\x03\x04\x9d\ \x03\x05\x1a/\x20Emit\x20a\x20log\x20containing\x20application\x20screen\ - shot.\n\n\x0f\n\x07\x04\x01\x03\x07\x03\x06\x01\x12\x04\x98\x03\x0c\x20\ - \n\x0f\n\x07\x04\x01\x03\x07\x03\x06\t\x12\x04\x99\x03\x06\x11\n\x10\n\ - \x08\x04\x01\x03\x07\x03\x06\t\0\x12\x04\x99\x03\x0f\x10\n\x11\n\t\x04\ - \x01\x03\x07\x03\x06\t\0\x01\x12\x04\x99\x03\x0f\x10\n\x11\n\t\x04\x01\ - \x03\x07\x03\x06\t\0\x02\x12\x04\x99\x03\x0f\x10\n\x0e\n\x04\x04\x01\x03\ - \x08\x12\x06\x9d\x03\x02\xae\x03\x03\n\r\n\x05\x04\x01\x03\x08\x01\x12\ - \x04\x9d\x03\n\x13\n\xaa\x01\n\x06\x04\x01\x03\x08\x03\0\x12\x04\xa0\x03\ + shot.\n\n\x0f\n\x07\x04\x01\x03\x07\x03\x06\x01\x12\x04\x9b\x03\x0c\x20\ + \n\x0f\n\x07\x04\x01\x03\x07\x03\x06\t\x12\x04\x9c\x03\x06\x11\n\x10\n\ + \x08\x04\x01\x03\x07\x03\x06\t\0\x12\x04\x9c\x03\x0f\x10\n\x11\n\t\x04\ + \x01\x03\x07\x03\x06\t\0\x01\x12\x04\x9c\x03\x0f\x10\n\x11\n\t\x04\x01\ + \x03\x07\x03\x06\t\0\x02\x12\x04\x9c\x03\x0f\x10\n\x0e\n\x04\x04\x01\x03\ + \x08\x12\x06\xa0\x03\x02\xb1\x03\x03\n\r\n\x05\x04\x01\x03\x08\x01\x12\ + \x04\xa0\x03\n\x13\n\xaa\x01\n\x06\x04\x01\x03\x08\x03\0\x12\x04\xa3\x03\ \x04!\x1a\x99\x01\x20An\x20execution\x20mode\x20where\x20a\x20new\x20wor\ kflow\x20*run*\x20starting\x20from\x20an\x20initial\n\x20state\x20can\ \x20be\x20started\x20only\x20if\x20there\x20are\x20no\x20other\x20active\ \x20runs\x20of\x20a\x20given\x20workflow.\n\n\x0f\n\x07\x04\x01\x03\x08\ - \x03\0\x01\x12\x04\xa0\x03\x0c\x1e\n\x10\n\x06\x04\x01\x03\x08\x03\x01\ - \x12\x06\xa2\x03\x04\xa6\x03\x05\n\x0f\n\x07\x04\x01\x03\x08\x03\x01\x01\ - \x12\x04\xa2\x03\x0c\x1d\n\x91\x01\n\x08\x04\x01\x03\x08\x03\x01\x02\0\ - \x12\x04\xa5\x03\x06*\x1a\x7f\x20The\x20maximum\x20number\x20of\x20activ\ + \x03\0\x01\x12\x04\xa3\x03\x0c\x1e\n\x10\n\x06\x04\x01\x03\x08\x03\x01\ + \x12\x06\xa5\x03\x04\xa9\x03\x05\n\x0f\n\x07\x04\x01\x03\x08\x03\x01\x01\ + \x12\x04\xa5\x03\x0c\x1d\n\x91\x01\n\x08\x04\x01\x03\x08\x03\x01\x02\0\ + \x12\x04\xa8\x03\x06*\x1a\x7f\x20The\x20maximum\x20number\x20of\x20activ\ e\x20workflow\x20runs\x20for\x20this\x20workflow.\x20If\x20not\x20specif\ ied\x20uses\x20an\n\x20implementation\x20defined\x20default\x20value.\n\ - \n\x11\n\t\x04\x01\x03\x08\x03\x01\x02\0\x04\x12\x04\xa5\x03\x06\x0e\n\ - \x11\n\t\x04\x01\x03\x08\x03\x01\x02\0\x05\x12\x04\xa5\x03\x0f\x15\n\x11\ - \n\t\x04\x01\x03\x08\x03\x01\x02\0\x01\x12\x04\xa5\x03\x16%\n\x11\n\t\ - \x04\x01\x03\x08\x03\x01\x02\0\x03\x12\x04\xa5\x03()\n\x10\n\x06\x04\x01\ - \x03\x08\x08\0\x12\x06\xa8\x03\x04\xab\x03\x05\n\x0f\n\x07\x04\x01\x03\ - \x08\x08\0\x01\x12\x04\xa8\x03\n\x18\n\x0e\n\x06\x04\x01\x03\x08\x02\0\ - \x12\x04\xa9\x03\x061\n\x0f\n\x07\x04\x01\x03\x08\x02\0\x06\x12\x04\xa9\ - \x03\x06\x18\n\x0f\n\x07\x04\x01\x03\x08\x02\0\x01\x12\x04\xa9\x03\x19,\ - \n\x0f\n\x07\x04\x01\x03\x08\x02\0\x03\x12\x04\xa9\x03/0\n\x0e\n\x06\x04\ - \x01\x03\x08\x02\x01\x12\x04\xaa\x03\x06/\n\x0f\n\x07\x04\x01\x03\x08\ - \x02\x01\x06\x12\x04\xaa\x03\x06\x17\n\x0f\n\x07\x04\x01\x03\x08\x02\x01\ - \x01\x12\x04\xaa\x03\x18*\n\x0f\n\x07\x04\x01\x03\x08\x02\x01\x03\x12\ - \x04\xaa\x03-.\n\r\n\x05\x04\x01\x03\x08\t\x12\x04\xad\x03\x04\x0f\n\x0e\ - \n\x06\x04\x01\x03\x08\t\0\x12\x04\xad\x03\r\x0e\n\x0f\n\x07\x04\x01\x03\ - \x08\t\0\x01\x12\x04\xad\x03\r\x0e\n\x0f\n\x07\x04\x01\x03\x08\t\0\x02\ - \x12\x04\xad\x03\r\x0e\nO\n\x04\x04\x01\x03\t\x12\x06\xb1\x03\x02\xb3\ + \n\x11\n\t\x04\x01\x03\x08\x03\x01\x02\0\x04\x12\x04\xa8\x03\x06\x0e\n\ + \x11\n\t\x04\x01\x03\x08\x03\x01\x02\0\x05\x12\x04\xa8\x03\x0f\x15\n\x11\ + \n\t\x04\x01\x03\x08\x03\x01\x02\0\x01\x12\x04\xa8\x03\x16%\n\x11\n\t\ + \x04\x01\x03\x08\x03\x01\x02\0\x03\x12\x04\xa8\x03()\n\x10\n\x06\x04\x01\ + \x03\x08\x08\0\x12\x06\xab\x03\x04\xae\x03\x05\n\x0f\n\x07\x04\x01\x03\ + \x08\x08\0\x01\x12\x04\xab\x03\n\x18\n\x0e\n\x06\x04\x01\x03\x08\x02\0\ + \x12\x04\xac\x03\x061\n\x0f\n\x07\x04\x01\x03\x08\x02\0\x06\x12\x04\xac\ + \x03\x06\x18\n\x0f\n\x07\x04\x01\x03\x08\x02\0\x01\x12\x04\xac\x03\x19,\ + \n\x0f\n\x07\x04\x01\x03\x08\x02\0\x03\x12\x04\xac\x03/0\n\x0e\n\x06\x04\ + \x01\x03\x08\x02\x01\x12\x04\xad\x03\x06/\n\x0f\n\x07\x04\x01\x03\x08\ + \x02\x01\x06\x12\x04\xad\x03\x06\x17\n\x0f\n\x07\x04\x01\x03\x08\x02\x01\ + \x01\x12\x04\xad\x03\x18*\n\x0f\n\x07\x04\x01\x03\x08\x02\x01\x03\x12\ + \x04\xad\x03-.\n\r\n\x05\x04\x01\x03\x08\t\x12\x04\xb0\x03\x04\x0f\n\x0e\ + \n\x06\x04\x01\x03\x08\t\0\x12\x04\xb0\x03\r\x0e\n\x0f\n\x07\x04\x01\x03\ + \x08\t\0\x01\x12\x04\xb0\x03\r\x0e\n\x0f\n\x07\x04\x01\x03\x08\t\0\x02\ + \x12\x04\xb0\x03\r\x0e\nO\n\x04\x04\x01\x03\t\x12\x06\xb4\x03\x02\xb6\ \x03\x03\x1a?\x20A\x20limit\x20for\x20the\x20number\x20of\x20logs\x20tha\ t\x20a\x20workflow\x20run\x20can\x20match.\n\n\r\n\x05\x04\x01\x03\t\x01\ - \x12\x04\xb1\x03\n\x1f\n\x0e\n\x06\x04\x01\x03\t\x02\0\x12\x04\xb2\x03\ - \x046\n\x0f\n\x07\x04\x01\x03\t\x02\0\x05\x12\x04\xb2\x03\x04\n\n\x0f\n\ - \x07\x04\x01\x03\t\x02\0\x01\x12\x04\xb2\x03\x0b\x10\n\x0f\n\x07\x04\x01\ - \x03\t\x02\0\x03\x12\x04\xb2\x03\x13\x14\n\x0f\n\x07\x04\x01\x03\t\x02\0\ - \x08\x12\x04\xb2\x03\x155\n\x13\n\x0b\x04\x01\x03\t\x02\0\x08\xaf\x08\ - \x05\x04\x12\x04\xb2\x03\x164\n\xaa\x01\n\x04\x04\x01\x03\n\x12\x06\xb7\ - \x03\x02\xb9\x03\x03\x1a\x99\x01\x20A\x20limit\x20for\x20the\x20duration\ + \x12\x04\xb4\x03\n\x1f\n\x0e\n\x06\x04\x01\x03\t\x02\0\x12\x04\xb5\x03\ + \x046\n\x0f\n\x07\x04\x01\x03\t\x02\0\x05\x12\x04\xb5\x03\x04\n\n\x0f\n\ + \x07\x04\x01\x03\t\x02\0\x01\x12\x04\xb5\x03\x0b\x10\n\x0f\n\x07\x04\x01\ + \x03\t\x02\0\x03\x12\x04\xb5\x03\x13\x14\n\x0f\n\x07\x04\x01\x03\t\x02\0\ + \x08\x12\x04\xb5\x03\x155\n\x13\n\x0b\x04\x01\x03\t\x02\0\x08\xaf\x08\ + \x05\x04\x12\x04\xb5\x03\x164\n\xaa\x01\n\x04\x04\x01\x03\n\x12\x06\xba\ + \x03\x02\xbc\x03\x03\x1a\x99\x01\x20A\x20limit\x20for\x20the\x20duration\ \x20of\x20time\x20a\x20given\x20workflow\x20run\x20can\x20stay\x20active\ \x20for.\n\x20The\x20time\x20starts\x20ticking\x20when\x20a\x20given\x20\ workflow\x20run\x20leaves\x20its\x20initial\x20state.\n\n\r\n\x05\x04\ - \x01\x03\n\x01\x12\x04\xb7\x03\n\x17\n\x0e\n\x06\x04\x01\x03\n\x02\0\x12\ - \x04\xb8\x03\x04<\n\x0f\n\x07\x04\x01\x03\n\x02\0\x05\x12\x04\xb8\x03\ - \x04\n\n\x0f\n\x07\x04\x01\x03\n\x02\0\x01\x12\x04\xb8\x03\x0b\x16\n\x0f\ - \n\x07\x04\x01\x03\n\x02\0\x03\x12\x04\xb8\x03\x19\x1a\n\x0f\n\x07\x04\ - \x01\x03\n\x02\0\x08\x12\x04\xb8\x03\x1b;\n\x13\n\x0b\x04\x01\x03\n\x02\ - \0\x08\xaf\x08\x06\x04\x12\x04\xb8\x03\x1c:\n5\n\x04\x04\x01\x03\x0b\x12\ - \x06\xbc\x03\x02\xc6\x03\x03\x1a%\x20A\x20value\x20extracted\x20from\x20\ - log's\x20field.\n\n\r\n\x05\x04\x01\x03\x0b\x01\x12\x04\xbc\x03\n\x18\n\ - \x0e\n\x06\x04\x01\x03\x0b\x02\0\x12\x04\xbd\x03\x04C\n\x0f\n\x07\x04\ - \x01\x03\x0b\x02\0\x05\x12\x04\xbd\x03\x04\n\n\x0f\n\x07\x04\x01\x03\x0b\ - \x02\0\x01\x12\x04\xbd\x03\x0b\x15\n\x0f\n\x07\x04\x01\x03\x0b\x02\0\x03\ - \x12\x04\xbd\x03\x18\x19\n\x0f\n\x07\x04\x01\x03\x0b\x02\0\x08\x12\x04\ - \xbd\x03\x1aB\n\x12\n\n\x04\x01\x03\x0b\x02\0\x08\xaf\x08\x0e\x12\x04\ - \xbd\x03\x1bA\n\x0e\n\x06\x04\x01\x03\x0b\x03\0\x12\x04\xbf\x03\x04\x14\ - \n\x0f\n\x07\x04\x01\x03\x0b\x03\0\x01\x12\x04\xbf\x03\x0c\x11\n\xbe\x01\ - \n\x06\x04\x01\x03\x0b\x08\0\x12\x06\xc3\x03\x04\xc5\x03\x05\x1a\xab\x01\ + \x01\x03\n\x01\x12\x04\xba\x03\n\x17\n\x0e\n\x06\x04\x01\x03\n\x02\0\x12\ + \x04\xbb\x03\x04<\n\x0f\n\x07\x04\x01\x03\n\x02\0\x05\x12\x04\xbb\x03\ + \x04\n\n\x0f\n\x07\x04\x01\x03\n\x02\0\x01\x12\x04\xbb\x03\x0b\x16\n\x0f\ + \n\x07\x04\x01\x03\n\x02\0\x03\x12\x04\xbb\x03\x19\x1a\n\x0f\n\x07\x04\ + \x01\x03\n\x02\0\x08\x12\x04\xbb\x03\x1b;\n\x13\n\x0b\x04\x01\x03\n\x02\ + \0\x08\xaf\x08\x06\x04\x12\x04\xbb\x03\x1c:\n5\n\x04\x04\x01\x03\x0b\x12\ + \x06\xbf\x03\x02\xc9\x03\x03\x1a%\x20A\x20value\x20extracted\x20from\x20\ + log's\x20field.\n\n\r\n\x05\x04\x01\x03\x0b\x01\x12\x04\xbf\x03\n\x18\n\ + \x0e\n\x06\x04\x01\x03\x0b\x02\0\x12\x04\xc0\x03\x04C\n\x0f\n\x07\x04\ + \x01\x03\x0b\x02\0\x05\x12\x04\xc0\x03\x04\n\n\x0f\n\x07\x04\x01\x03\x0b\ + \x02\0\x01\x12\x04\xc0\x03\x0b\x15\n\x0f\n\x07\x04\x01\x03\x0b\x02\0\x03\ + \x12\x04\xc0\x03\x18\x19\n\x0f\n\x07\x04\x01\x03\x0b\x02\0\x08\x12\x04\ + \xc0\x03\x1aB\n\x12\n\n\x04\x01\x03\x0b\x02\0\x08\xaf\x08\x0e\x12\x04\ + \xc0\x03\x1bA\n\x0e\n\x06\x04\x01\x03\x0b\x03\0\x12\x04\xc2\x03\x04\x14\ + \n\x0f\n\x07\x04\x01\x03\x0b\x03\0\x01\x12\x04\xc2\x03\x0c\x11\n\xbe\x01\ + \n\x06\x04\x01\x03\x0b\x08\0\x12\x06\xc6\x03\x04\xc8\x03\x05\x1a\xab\x01\ \x20For\x20now\x20we\x20only\x20support\x20exact\x20match,\x20but\x20in\ \x20the\x20future\x20we\x20might\x20support\x20more\x20complex\n\x20extr\ action\x20logic\x20like\x20regex\x20captures.\x20If\x20not\x20specified,\ \x20the\x20default\x20is\x20exact\x20match.\n\n\x0f\n\x07\x04\x01\x03\ - \x0b\x08\0\x01\x12\x04\xc3\x03\n\x19\n\x0e\n\x06\x04\x01\x03\x0b\x02\x01\ - \x12\x04\xc4\x03\x06\x16\n\x0f\n\x07\x04\x01\x03\x0b\x02\x01\x06\x12\x04\ - \xc4\x03\x06\x0b\n\x0f\n\x07\x04\x01\x03\x0b\x02\x01\x01\x12\x04\xc4\x03\ - \x0c\x11\n\x0f\n\x07\x04\x01\x03\x0b\x02\x01\x03\x12\x04\xc4\x03\x14\x15\ - \n\x0e\n\x04\x04\x01\x03\x0c\x12\x06\xc8\x03\x02\xd2\x03\x03\n\r\n\x05\ - \x04\x01\x03\x0c\x01\x12\x04\xc8\x03\n\x18\n\x0e\n\x06\x04\x01\x03\x0c\ - \x02\0\x12\x04\xc9\x03\x04N\n\x0f\n\x07\x04\x01\x03\x0c\x02\0\x06\x12\ - \x04\xc9\x03\x04\x17\n\x0f\n\x07\x04\x01\x03\x0c\x02\0\x01\x12\x04\xc9\ - \x03\x18\x1d\n\x0f\n\x07\x04\x01\x03\x0c\x02\0\x03\x12\x04\xc9\x03\x20!\ - \n\x0f\n\x07\x04\x01\x03\x0c\x02\0\x08\x12\x04\xc9\x03\"M\n\x13\n\x0b\ - \x04\x01\x03\x0c\x02\0\x08\xaf\x08\x10\x02\x12\x04\xc9\x03#L\n\x0e\n\x06\ - \x04\x01\x03\x0c\x02\x01\x12\x04\xcb\x03\x04<\n\x0f\n\x07\x04\x01\x03\ - \x0c\x02\x01\x05\x12\x04\xcb\x03\x04\n\n\x0f\n\x07\x04\x01\x03\x0c\x02\ - \x01\x01\x12\x04\xcb\x03\x0b\x0e\n\x0f\n\x07\x04\x01\x03\x0c\x02\x01\x03\ - \x12\x04\xcb\x03\x11\x12\n\x0f\n\x07\x04\x01\x03\x0c\x02\x01\x08\x12\x04\ - \xcb\x03\x13;\n\x12\n\n\x04\x01\x03\x0c\x02\x01\x08\xaf\x08\x0e\x12\x04\ - \xcb\x03\x14:\n\x0e\n\x06\x04\x01\x03\x0c\x03\0\x12\x04\xcd\x03\x04\x14\ - \n\x0f\n\x07\x04\x01\x03\x0c\x03\0\x01\x12\x04\xcd\x03\x0c\x11\n\x10\n\ - \x06\x04\x01\x03\x0c\x08\0\x12\x06\xcf\x03\x04\xd1\x03\x05\n\x0f\n\x07\ - \x04\x01\x03\x0c\x08\0\x01\x12\x04\xcf\x03\n\x19\n\x0e\n\x06\x04\x01\x03\ - \x0c\x02\x02\x12\x04\xd0\x03\x06\x16\n\x0f\n\x07\x04\x01\x03\x0c\x02\x02\ - \x06\x12\x04\xd0\x03\x06\x0b\n\x0f\n\x07\x04\x01\x03\x0c\x02\x02\x01\x12\ - \x04\xd0\x03\x0c\x11\n\x0f\n\x07\x04\x01\x03\x0c\x02\x02\x03\x12\x04\xd0\ + \x0b\x08\0\x01\x12\x04\xc6\x03\n\x19\n\x0e\n\x06\x04\x01\x03\x0b\x02\x01\ + \x12\x04\xc7\x03\x06\x16\n\x0f\n\x07\x04\x01\x03\x0b\x02\x01\x06\x12\x04\ + \xc7\x03\x06\x0b\n\x0f\n\x07\x04\x01\x03\x0b\x02\x01\x01\x12\x04\xc7\x03\ + \x0c\x11\n\x0f\n\x07\x04\x01\x03\x0b\x02\x01\x03\x12\x04\xc7\x03\x14\x15\ + \n\x0e\n\x04\x04\x01\x03\x0c\x12\x06\xcb\x03\x02\xd5\x03\x03\n\r\n\x05\ + \x04\x01\x03\x0c\x01\x12\x04\xcb\x03\n\x18\n\x0e\n\x06\x04\x01\x03\x0c\ + \x02\0\x12\x04\xcc\x03\x04N\n\x0f\n\x07\x04\x01\x03\x0c\x02\0\x06\x12\ + \x04\xcc\x03\x04\x17\n\x0f\n\x07\x04\x01\x03\x0c\x02\0\x01\x12\x04\xcc\ + \x03\x18\x1d\n\x0f\n\x07\x04\x01\x03\x0c\x02\0\x03\x12\x04\xcc\x03\x20!\ + \n\x0f\n\x07\x04\x01\x03\x0c\x02\0\x08\x12\x04\xcc\x03\"M\n\x13\n\x0b\ + \x04\x01\x03\x0c\x02\0\x08\xaf\x08\x10\x02\x12\x04\xcc\x03#L\n\x0e\n\x06\ + \x04\x01\x03\x0c\x02\x01\x12\x04\xce\x03\x04<\n\x0f\n\x07\x04\x01\x03\ + \x0c\x02\x01\x05\x12\x04\xce\x03\x04\n\n\x0f\n\x07\x04\x01\x03\x0c\x02\ + \x01\x01\x12\x04\xce\x03\x0b\x0e\n\x0f\n\x07\x04\x01\x03\x0c\x02\x01\x03\ + \x12\x04\xce\x03\x11\x12\n\x0f\n\x07\x04\x01\x03\x0c\x02\x01\x08\x12\x04\ + \xce\x03\x13;\n\x12\n\n\x04\x01\x03\x0c\x02\x01\x08\xaf\x08\x0e\x12\x04\ + \xce\x03\x14:\n\x0e\n\x06\x04\x01\x03\x0c\x03\0\x12\x04\xd0\x03\x04\x14\ + \n\x0f\n\x07\x04\x01\x03\x0c\x03\0\x01\x12\x04\xd0\x03\x0c\x11\n\x10\n\ + \x06\x04\x01\x03\x0c\x08\0\x12\x06\xd2\x03\x04\xd4\x03\x05\n\x0f\n\x07\ + \x04\x01\x03\x0c\x08\0\x01\x12\x04\xd2\x03\n\x19\n\x0e\n\x06\x04\x01\x03\ + \x0c\x02\x02\x12\x04\xd3\x03\x06\x16\n\x0f\n\x07\x04\x01\x03\x0c\x02\x02\ + \x06\x12\x04\xd3\x03\x06\x0b\n\x0f\n\x07\x04\x01\x03\x0c\x02\x02\x01\x12\ + \x04\xd3\x03\x0c\x11\n\x0f\n\x07\x04\x01\x03\x0c\x02\x02\x03\x12\x04\xd3\ \x03\x14\x15b\x06proto3\ "; diff --git a/bd-proto/src/protos/workflow/workflow.rs b/bd-proto/src/protos/workflow/workflow.rs index bb78b5b23..bcf9c72e6 100644 --- a/bd-proto/src/protos/workflow/workflow.rs +++ b/bd-proto/src/protos/workflow/workflow.rs @@ -971,8 +971,33 @@ pub mod workflow { } } + // bool on_new_session = 4; + + pub fn on_new_session(&self) -> bool { + match self.rule_type { + ::std::option::Option::Some(rule::Rule_type::OnNewSession(v)) => v, + _ => false, + } + } + + pub fn clear_on_new_session(&mut self) { + self.rule_type = ::std::option::Option::None; + } + + pub fn has_on_new_session(&self) -> bool { + match self.rule_type { + ::std::option::Option::Some(rule::Rule_type::OnNewSession(..)) => true, + _ => false, + } + } + + // Param is passed by value, moved + pub fn set_on_new_session(&mut self, v: bool) { + self.rule_type = ::std::option::Option::Some(rule::Rule_type::OnNewSession(v)) + } + pub(in super) fn generated_message_descriptor_data() -> ::protobuf::reflect::GeneratedMessageDescriptorData { - let mut fields = ::std::vec::Vec::with_capacity(2); + let mut fields = ::std::vec::Vec::with_capacity(3); let mut oneofs = ::std::vec::Vec::with_capacity(1); fields.push(::protobuf::reflect::rt::v2::make_oneof_message_has_get_mut_set_accessor::<_, RuleLogMatch>( "rule_log_match", @@ -988,6 +1013,12 @@ pub mod workflow { Rule::mut_rule_state_change_match, Rule::set_rule_state_change_match, )); + fields.push(::protobuf::reflect::rt::v2::make_oneof_copy_has_get_set_simpler_accessors::<_, _>( + "on_new_session", + Rule::has_on_new_session, + Rule::on_new_session, + Rule::set_on_new_session, + )); oneofs.push(rule::Rule_type::generated_oneof_descriptor_data()); ::protobuf::reflect::GeneratedMessageDescriptorData::new_2::( "Workflow.Rule", @@ -1013,6 +1044,9 @@ pub mod workflow { 26 => { self.rule_type = ::std::option::Option::Some(rule::Rule_type::RuleStateChangeMatch(is.read_message()?)); }, + 32 => { + self.rule_type = ::std::option::Option::Some(rule::Rule_type::OnNewSession(is.read_bool()?)); + }, tag => { ::protobuf::rt::read_unknown_or_skip_group(tag, is, self.special_fields.mut_unknown_fields())?; }, @@ -1035,6 +1069,9 @@ pub mod workflow { let len = v.compute_size(); my_size += 1 + ::protobuf::rt::compute_raw_varint64_size(len) + len; }, + &rule::Rule_type::OnNewSession(v) => { + my_size += 1 + 1; + }, }; } my_size += ::protobuf::rt::unknown_fields_size(self.special_fields.unknown_fields()); @@ -1051,6 +1088,9 @@ pub mod workflow { &rule::Rule_type::RuleStateChangeMatch(ref v) => { ::protobuf::rt::write_message_field_with_cached_size(3, v, os)?; }, + &rule::Rule_type::OnNewSession(v) => { + os.write_bool(4, v)?; + }, }; } os.write_unknown_fields(self.special_fields.unknown_fields())?; @@ -1070,6 +1110,7 @@ pub mod workflow { } fn clear(&mut self) { + self.rule_type = ::std::option::Option::None; self.rule_type = ::std::option::Option::None; self.rule_type = ::std::option::Option::None; self.special_fields.clear(); @@ -1111,6 +1152,8 @@ pub mod workflow { RuleLogMatch(super::RuleLogMatch), // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.workflow.v1.Workflow.Rule.rule_state_change_match) RuleStateChangeMatch(super::RuleStateChangeMatch), + // @@protoc_insertion_point(oneof_field:bitdrift_public.protobuf.workflow.v1.Workflow.Rule.on_new_session) + OnNewSession(bool), } impl ::protobuf::Oneof for Rule_type { @@ -7584,7 +7627,7 @@ static file_descriptor_proto_data: &'static [u8] = b"\ ft_public/protobuf/state/v1/scope.proto\x1a5bitdrift_public/protobuf/wor\ kflow/v1/save_field.proto\x1a\x17validate/validate.proto\"f\n\x16Workflo\ wsConfiguration\x12L\n\tworkflows\x18\x01\x20\x03(\x0b2..bitdrift_public\ - .protobuf.workflow.v1.WorkflowR\tworkflows\"\xf3;\n\x08Workflow\x12\x17\ + .protobuf.workflow.v1.WorkflowR\tworkflows\"\x9b<\n\x08Workflow\x12\x17\ \n\x02id\x18\x01\x20\x01(\tR\x02idB\x07\xfaB\x04r\x02\x10\x01\x12V\n\x06\ states\x18\x02\x20\x03(\x0b24.bitdrift_public.protobuf.workflow.v1.Workf\ low.StateR\x06statesB\x08\xfaB\x05\x92\x01\x02\x08\x01\x12V\n\texecution\ @@ -7608,32 +7651,33 @@ static file_descriptor_proto_data: &'static [u8] = b"\ \x08\xfaB\x05\x8a\x01\x02\x10\x01\x12O\n\x07actions\x18\x03\x20\x03(\x0b\ 25.bitdrift_public.protobuf.workflow.v1.Workflow.ActionR\x07actions\x12b\ \n\nextensions\x18\x04\x20\x03(\x0b2B.bitdrift_public.protobuf.workflow.\ - v1.Workflow.TransitionExtensionR\nextensions\x1a\x81\x02\n\x04Rule\x12c\ + v1.Workflow.TransitionExtensionR\nextensions\x1a\xa9\x02\n\x04Rule\x12c\ \n\x0erule_log_match\x18\x01\x20\x01(\x0b2;.bitdrift_public.protobuf.wor\ kflow.v1.Workflow.RuleLogMatchH\0R\x0cruleLogMatch\x12|\n\x17rule_state_\ change_match\x18\x03\x20\x01(\x0b2C.bitdrift_public.protobuf.workflow.v1\ - .Workflow.RuleStateChangeMatchH\0R\x14ruleStateChangeMatchB\x10\n\trule_\ - type\x12\x03\xf8B\x01J\x04\x08\x02\x10\x03\x1a\x8b\x06\n\x13TransitionEx\ - tension\x12\xa8\x01\n\x1fsankey_diagram_value_extraction\x18\x01\x20\x01\ - (\x0b2_.bitdrift_public.protobuf.workflow.v1.Workflow.TransitionExtensio\ - n.SankeyDiagramValueExtractionH\0R\x1csankeyDiagramValueExtraction\x12y\ - \n\x0esave_timestamp\x18\x02\x20\x01(\x0b2P.bitdrift_public.protobuf.wor\ - kflow.v1.Workflow.TransitionExtension.SaveTimestampH\0R\rsaveTimestamp\ - \x12P\n\nsave_field\x18\x03\x20\x01(\x0b2/.bitdrift_public.protobuf.work\ - flow.v1.SaveFieldH\0R\tsaveField\x1a\x1f\n\rSaveTimestamp\x12\x0e\n\x02i\ - d\x18\x01\x20\x01(\tR\x02id\x1a\xc3\x02\n\x1cSankeyDiagramValueExtractio\ - n\x123\n\x11sankey_diagram_id\x18\x01\x20\x01(\tR\x0fsankeyDiagramIdB\ - \x07\xfaB\x04r\x02\x10\x01\x12\x1f\n\x05fixed\x18\x02\x20\x01(\tH\0R\x05\ - fixedB\x07\xfaB\x04r\x02\x10\x01\x12h\n\x0ffield_extracted\x18\x03\x20\ - \x01(\x0b2=.bitdrift_public.protobuf.workflow.v1.Workflow.FieldExtracted\ - H\0R\x0efieldExtracted\x12P\n%counts_toward_sankey_extraction_limit\x18\ - \x04\x20\x01(\x08R!countsTowardSankeyExtractionLimitB\x11\n\nvalue_type\ - \x12\x03\xf8B\x01B\x15\n\x0eextension_type\x12\x03\xf8B\x01\x1a\x89\x01\ - \n\x0cRuleLogMatch\x12Z\n\x0blog_matcher\x18\x01\x20\x01(\x0b2/.bitdrift\ - _public.protobuf.matcher.v1.LogMatcherR\nlogMatcherB\x08\xfaB\x05\x8a\ - \x01\x02\x10\x01\x12\x1d\n\x05count\x18\x02\x20\x01(\rR\x05countB\x07\ - \xfaB\x04*\x02\x20\0\x1a\x88\x03\n\x14RuleStateChangeMatch\x12M\n\x05sco\ - pe\x18\x01\x20\x01(\x0e2-.bitdrift_public.protobuf.state.v1.StateScopeR\ + .Workflow.RuleStateChangeMatchH\0R\x14ruleStateChangeMatch\x12&\n\x0eon_\ + new_session\x18\x04\x20\x01(\x08H\0R\x0conNewSessionB\x10\n\trule_type\ + \x12\x03\xf8B\x01J\x04\x08\x02\x10\x03\x1a\x8b\x06\n\x13TransitionExtens\ + ion\x12\xa8\x01\n\x1fsankey_diagram_value_extraction\x18\x01\x20\x01(\ + \x0b2_.bitdrift_public.protobuf.workflow.v1.Workflow.TransitionExtension\ + .SankeyDiagramValueExtractionH\0R\x1csankeyDiagramValueExtraction\x12y\n\ + \x0esave_timestamp\x18\x02\x20\x01(\x0b2P.bitdrift_public.protobuf.workf\ + low.v1.Workflow.TransitionExtension.SaveTimestampH\0R\rsaveTimestamp\x12\ + P\n\nsave_field\x18\x03\x20\x01(\x0b2/.bitdrift_public.protobuf.workflow\ + .v1.SaveFieldH\0R\tsaveField\x1a\x1f\n\rSaveTimestamp\x12\x0e\n\x02id\ + \x18\x01\x20\x01(\tR\x02id\x1a\xc3\x02\n\x1cSankeyDiagramValueExtraction\ + \x123\n\x11sankey_diagram_id\x18\x01\x20\x01(\tR\x0fsankeyDiagramIdB\x07\ + \xfaB\x04r\x02\x10\x01\x12\x1f\n\x05fixed\x18\x02\x20\x01(\tH\0R\x05fixe\ + dB\x07\xfaB\x04r\x02\x10\x01\x12h\n\x0ffield_extracted\x18\x03\x20\x01(\ + \x0b2=.bitdrift_public.protobuf.workflow.v1.Workflow.FieldExtractedH\0R\ + \x0efieldExtracted\x12P\n%counts_toward_sankey_extraction_limit\x18\x04\ + \x20\x01(\x08R!countsTowardSankeyExtractionLimitB\x11\n\nvalue_type\x12\ + \x03\xf8B\x01B\x15\n\x0eextension_type\x12\x03\xf8B\x01\x1a\x89\x01\n\ + \x0cRuleLogMatch\x12Z\n\x0blog_matcher\x18\x01\x20\x01(\x0b2/.bitdrift_p\ + ublic.protobuf.matcher.v1.LogMatcherR\nlogMatcherB\x08\xfaB\x05\x8a\x01\ + \x02\x10\x01\x12\x1d\n\x05count\x18\x02\x20\x01(\rR\x05countB\x07\xfaB\ + \x04*\x02\x20\0\x1a\x88\x03\n\x14RuleStateChangeMatch\x12M\n\x05scope\ + \x18\x01\x20\x01(\x0e2-.bitdrift_public.protobuf.state.v1.StateScopeR\ \x05scopeB\x08\xfaB\x05\x82\x01\x02\x10\x01\x12\x19\n\x03key\x18\x02\x20\ \x01(\tR\x03keyB\x07\xfaB\x04r\x02\x10\x01\x12Y\n\x0eprevious_value\x18\ \x03\x20\x01(\x0b22.bitdrift_public.protobuf.state.v1.StateValueMatchR\r\ diff --git a/bd-session/Cargo.toml b/bd-session/Cargo.toml index 4f6c1e60c..5df08543e 100644 --- a/bd-session/Cargo.toml +++ b/bd-session/Cargo.toml @@ -10,14 +10,16 @@ doctest = false [dependencies] anyhow.workspace = true -bd-key-value.path = "../bd-key-value" +bd-client-common.path = "../bd-client-common" bd-log.path = "../bd-log" +bd-macros.path = "../bd-macros" bd-proto.path = "../bd-proto" +bd-proto-util.path = "../bd-proto-util" bd-time.path = "../bd-time" bd-workspace-hack.workspace = true log.workspace = true parking_lot.workspace = true -serde.workspace = true +protobuf.workspace = true thread_local.workspace = true time.workspace = true tokio.workspace = true @@ -27,3 +29,4 @@ uuid.workspace = true bd-test-helpers = { path = "../bd-test-helpers", default-features = false } ctor.workspace = true pretty_assertions.workspace = true +tempfile.workspace = true diff --git a/bd-session/src/activity_based.rs b/bd-session/src/activity_based.rs index 0e22e5ffb..7ae2a52ca 100644 --- a/bd-session/src/activity_based.rs +++ b/bd-session/src/activity_based.rs @@ -9,17 +9,13 @@ #[path = "./activity_based_test.rs"] mod activity_based_test; -use bd_key_value::{Key, Store}; -use bd_proto::protos::client::key_value::ActivitySessionStrategyState; -use bd_time::{OffsetDateTimeExt as _, TimeProvider, TimestampExt}; +use crate::persistence::{BackendState, PersistedSessionState, StartedSessionRecord}; +use crate::{DeferredCallback, Initialization, LoadedState, Mutation}; +use bd_time::TimeProvider; use std::sync::Arc; use time::{Duration, OffsetDateTime}; use uuid::Uuid; -/// The key used to store the state of the session strategy. -pub(crate) static STATE_KEY: Key = - Key::new("session_strategy.activity_based.state.1"); - // // Strategy // @@ -32,15 +28,8 @@ pub(crate) static STATE_KEY: Key = pub struct Strategy { callbacks: Arc, inactivity_threshold: time::Duration, - store: Arc, time_provider: Arc, - // The current state of the strategy. Starts off as `None` and is initialized lazily on the first - // access of the session identifier. This allows potentially heavy storage operations to be - // offloaded to a later time (which in practice can end up being handled by a background - // thread). - state: parking_lot::Mutex>, - // The minimum duration between consecutive writes of the last activity time. max_write_interval: time::Duration, } @@ -48,16 +37,13 @@ pub struct Strategy { impl Strategy { pub fn new( inactivity_threshold: time::Duration, - store: Arc, callbacks: Arc, time_provider: Arc, ) -> Self { Self { callbacks, inactivity_threshold, - store, time_provider, - state: parking_lot::Mutex::new(None), max_write_interval: Duration::seconds(15), } } @@ -66,153 +52,156 @@ impl Strategy { Uuid::new_v4().to_string() } - pub(crate) fn session_id(&self) -> String { - let mut guard = self.state.lock(); - + pub(crate) fn initialize( + &self, + persisted: Option, + mut pending_started_sessions: Vec, + ) -> Initialization { let now = self.time_provider.now(); - - let mut need_callback = false; - let mut state = guard.as_ref().map_or_else( - || { - if let Some(state) = self.store.get(&STATE_KEY) { - InMemoryState { - state: state.clone(), - previous_process_session_id: Some(state.session_id), - last_activity_write: None, - } - } else { - let state = InMemoryState { - state: ActivitySessionStrategyState { - session_id: Self::generate_session_id(), - last_activity_timestamp: now.into_proto(), - ..Default::default() - }, + if let Some(persisted) = persisted { + // Reuse the persisted session as input to the normal activity transition logic so restart + // behavior matches a normal foreground access. + let previous_process_session_id = Some(persisted.current_session_id.clone()); + let mut state = LoadedState { + persisted: PersistedSessionState { + previous_process_session_id, + ..persisted + }, + pending_started_sessions, + last_activity_write: None, + }; + let mut mutation = self.on_session_id(&mut state); + // Handshake uploads must be able to announce the current session after a restart even if the + // process died before flushing a pending-started-sessions queue entry. + if !state + .pending_started_sessions + .iter() + .any(|started| started.session_id == state.persisted.current_session_id) + { + state + .pending_started_sessions + .push(StartedSessionRecord::new( + state.persisted.current_session_id.clone(), + OffsetDateTime::from(state.persisted.current_session_start), + )); + mutation.persist_pending = true; + } + Initialization { state, mutation } + } else { + let session_id = Self::generate_session_id(); + let session_start = now; + pending_started_sessions.push(StartedSessionRecord::new(session_id.clone(), session_start)); + + Initialization { + state: LoadedState { + persisted: PersistedSessionState { + current_session_id: session_id.clone(), + current_session_start: session_start.into(), previous_process_session_id: None, - last_activity_write: None, - }; - - need_callback = true; - - log::info!( - "bitdrift Capture initialized with session ID: {:?}", - state.state.session_id, - ); + backend: BackendState::ActivityBased { + last_activity: now.into(), + }, + }, + pending_started_sessions, + last_activity_write: Some(now), + }, + mutation: Mutation { + persist_state: true, + persist_pending: true, + callback: Some(DeferredCallback::ActivitySessionChanged(session_id)), + }, + } + } + } - state - } - }, - std::clone::Clone::clone, - ); + pub(crate) fn on_session_id(&self, state: &mut LoadedState) -> Mutation { + let now = self.time_provider.now(); + let BackendState::ActivityBased { last_activity } = &mut state.persisted.backend else { + return Mutation::default(); + }; - let is_now_before_last_activity = - now < state.state.last_activity_timestamp.to_offset_date_time(); + let previous_last_activity = OffsetDateTime::from(*last_activity); + let is_now_before_last_activity = now < previous_last_activity; let is_inactivity_threshold_exceeded = - now - state.state.last_activity_timestamp.to_offset_date_time() > self.inactivity_threshold; - - // We debounce writes to the store to avoid excessive writes, so only perform a state write if - // we haven't written to the store yet or if the last write was more than `max_write_interval` - // ago. If the session changes we always write to the store. + (now - previous_last_activity) > self.inactivity_threshold; let last_activity_storage_needs_write = state .last_activity_write .is_none_or(|last_activity_write| now - last_activity_write > self.max_write_interval); - state.state.last_activity_timestamp = now.into_proto(); + *last_activity = now.into(); if is_now_before_last_activity || is_inactivity_threshold_exceeded { + // Either the clock moved backwards or the inactivity threshold expired. In both cases we + // rotate the session and enqueue a state update so the backend can observe the boundary. let session_id = Self::generate_session_id(); - - state.state.session_id.clone_from(&session_id); + state.persisted.current_session_id.clone_from(&session_id); + state.persisted.current_session_start = now.into(); + state + .pending_started_sessions + .push(StartedSessionRecord::new(session_id.clone(), now)); state.last_activity_write = Some(now); - self.store.set(&STATE_KEY, &state.state); - - need_callback = true; + Mutation { + persist_state: true, + persist_pending: true, + callback: Some(DeferredCallback::ActivitySessionChanged(session_id)), + } } else if last_activity_storage_needs_write { + // The session itself is unchanged, but we periodically persist the last-activity timestamp so + // a restart can continue the inactivity window from roughly the right point in time. state.last_activity_write = Some(now); - - self.store.set(&STATE_KEY, &state.state); - } - - let session_id = state.state.session_id.clone(); - *guard = Some(state); - - // Make sure we call the callback with the lock released. There are legitimate cases where - // this function may get called again from the context of the callback. - drop(guard); - if need_callback { - self.callbacks.session_id_changed(&session_id); + Mutation { + persist_state: true, + ..Default::default() + } + } else { + Mutation::default() } - - session_id } - pub(crate) fn start_new_session(&self) -> String { - let mut guard = self.state.lock(); - + pub(crate) fn start_new_session( + &self, + state: Option<&LoadedState>, + persisted: Option, + mut pending_started_sessions: Vec, + ) -> Initialization { + // An explicit rotation behaves like a brand-new activity session, but it preserves the last + // previous-process session marker for post-restart reporting. let session_id = Self::generate_session_id(); let now = self.time_provider.now(); - - let previous_process_session_id = guard.as_ref().map_or_else( - || { - if let Some(state) = self.store.get(&STATE_KEY) { - Some(state.session_id) - } else { - None - } - }, - |state| state.previous_process_session_id.clone(), + let previous_process_session_id = state.as_ref().map_or_else( + || persisted.map(|state| state.current_session_id), + |state| state.persisted.previous_process_session_id.clone(), ); - let state = InMemoryState { - previous_process_session_id, - state: ActivitySessionStrategyState { - session_id: session_id.clone(), - last_activity_timestamp: now.into_proto(), - ..Default::default() + pending_started_sessions.push(StartedSessionRecord::new(session_id.clone(), now)); + + Initialization { + state: LoadedState { + persisted: PersistedSessionState { + current_session_id: session_id, + current_session_start: now.into(), + previous_process_session_id, + backend: BackendState::ActivityBased { + last_activity: now.into(), + }, + }, + pending_started_sessions, + last_activity_write: Some(now), }, - last_activity_write: Some(now), - }; - - self.store.set(&STATE_KEY, &state.state); - - *guard = Some(state); - - session_id - } - - pub fn previous_process_session_id(&self) -> Option { - self.state.lock().as_ref().map_or_else( - || self.store.get(&STATE_KEY).map(|state| state.session_id), - |state| state.previous_process_session_id.clone(), - ) + mutation: Mutation { + persist_state: true, + persist_pending: true, + callback: None, + }, + } } - pub(crate) fn flush(&self) { - log::debug!("flushing session state"); - if let Some(state) = self.state.lock().as_ref() { - self.store.set(&STATE_KEY, &state.state); - } else { - log::debug!("no session state to flush"); - } + pub(crate) fn run_callback(&self, session_id: &str) { + self.callbacks.session_id_changed(session_id); } } -// -// Callbacks -// - pub trait Callbacks: Send + Sync { fn session_id_changed(&self, session_id: &str); } - -// -// InMemoryState -// - -#[derive(Clone)] -struct InMemoryState { - state: ActivitySessionStrategyState, - /// The last active session ID from the previous SDK run. - previous_process_session_id: Option, - last_activity_write: Option, -} diff --git a/bd-session/src/activity_based_test.rs b/bd-session/src/activity_based_test.rs index e870964db..206ef7fd6 100644 --- a/bd-session/src/activity_based_test.rs +++ b/bd-session/src/activity_based_test.rs @@ -5,13 +5,12 @@ // LICENSE file or at: // https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt -use crate::activity_based::{self, Callbacks, STATE_KEY, Store}; -use bd_key_value::Storage; -use bd_proto::protos::client::key_value::ActivitySessionStrategyState; -use bd_time::{OffsetDateTimeExt as _, TestTimeProvider}; +use crate::Strategy; +use crate::activity_based::Callbacks; +use bd_time::TestTimeProvider; use pretty_assertions::assert_eq; -use std::collections::HashMap; use std::sync::Arc; +use tempfile::TempDir; use time::ext::NumericalDuration; use time::{Duration, OffsetDateTime}; @@ -40,370 +39,226 @@ impl Callbacks for MockCallbacks { // MockStorage // -#[derive(Default)] -pub struct MockStorage { - state: parking_lot::Mutex>, -} - -impl Storage for MockStorage { - fn set_string(&self, key: &str, value: &str) -> anyhow::Result<()> { - let mut guard = self.state.lock(); - let mut state = guard.clone(); - state.insert(key.to_string(), value.to_string()); - *guard = state; - - Ok(()) - } - - fn get_string(&self, key: &str) -> anyhow::Result> { - Ok(self.state.lock().get(key).cloned()) - } - - fn delete(&self, key: &str) -> anyhow::Result<()> { - self.state.lock().remove(key); - Ok(()) - } -} - -#[test] -fn generates_new_session_and_stores_it_if_none_exists() { +#[tokio::test] +async fn generates_new_session_and_stores_it_if_none_exists() { let now = OffsetDateTime::now_utc(); - let store = Arc::new(Store::new(Box::::default())); + let sdk_directory = TempDir::new().unwrap(); let callbacks = Arc::new(MockCallbacks::default()); - let strategy = activity_based::Strategy::new( + let strategy = Strategy::activity_based( + sdk_directory.path(), Duration::seconds(30), - store.clone(), callbacks.clone(), Arc::new(TestTimeProvider::new(now)), ); assert!(strategy.previous_process_session_id().is_none()); - let session_id = strategy.session_id(); + let session_id = strategy.session_id().await.unwrap(); assert_eq!(1, callbacks.session_id_changes.lock().len()); assert_eq!(session_id, callbacks.session_id_changes.lock()[0]); - assert_eq!( - ActivitySessionStrategyState { - session_id, - last_activity_timestamp: now.into_proto(), - ..Default::default() - }, - store.as_ref().get(&STATE_KEY).unwrap(), - ); assert!(strategy.previous_process_session_id().is_none()); } -#[test] -fn generates_new_session_and_stores_it_if_old_exceeded_inactivity_threshold() { +#[tokio::test] +async fn generates_new_session_and_stores_it_if_old_exceeded_inactivity_threshold() { let now = OffsetDateTime::now_utc(); - let store = Arc::new(Store::new(Box::::default())); + let sdk_directory = TempDir::new().unwrap(); let callbacks = Arc::new(MockCallbacks::default()); - store.set( - &STATE_KEY, - &ActivitySessionStrategyState { - session_id: "foo".to_string(), - last_activity_timestamp: (now - std::time::Duration::from_secs(31)).into_proto(), - ..Default::default() - }, - ); - - let strategy = activity_based::Strategy::new( + let strategy = Strategy::activity_based( + sdk_directory.path(), Duration::seconds(30), - store.clone(), callbacks.clone(), Arc::new(TestTimeProvider::new(now)), ); - assert_eq!( - Some("foo".to_string()), - strategy.previous_process_session_id() - ); - - let session_id = strategy.session_id(); + let session_id = strategy.session_id().await.unwrap(); assert_eq!(1, callbacks.session_id_changes.lock().len()); assert_eq!(session_id, callbacks.session_id_changes.lock()[0]); - assert_eq!( - ActivitySessionStrategyState { - session_id, - last_activity_timestamp: now.into_proto(), - ..Default::default() - }, - store.as_ref().get(&STATE_KEY).unwrap(), - ); - assert_eq!( - Some("foo".to_string()), - strategy.previous_process_session_id() - ); + assert!(strategy.previous_process_session_id().is_none()); } -#[test] -fn does_not_update_neither_session_nor_last_activity_if_within_max_write_interval() { +#[tokio::test] +async fn does_not_update_neither_session_nor_last_activity_if_within_max_write_interval() { let now = OffsetDateTime::now_utc(); - let store = Arc::new(Store::new(Box::::default())); + let sdk_directory = TempDir::new().unwrap(); let time_provider = Arc::new(TestTimeProvider::new(now)); let callbacks = Arc::new(MockCallbacks::default()); - let strategy = activity_based::Strategy::new( + let strategy = Strategy::activity_based( + sdk_directory.path(), Duration::seconds(30), - store.clone(), callbacks.clone(), time_provider.clone(), ); - let session_id = strategy.session_id(); + let session_id = strategy.session_id().await.unwrap(); callbacks.clear(); time_provider.advance(time::Duration::seconds(3)); - let second_session_id = strategy.session_id(); + let second_session_id = strategy.session_id().await.unwrap(); assert_eq!(session_id, second_session_id); assert!(callbacks.session_id_changes.lock().is_empty()); - assert_eq!( - ActivitySessionStrategyState { - session_id, - last_activity_timestamp: now.into_proto(), - ..Default::default() - }, - store.as_ref().get(&STATE_KEY).unwrap() - ); } -#[test] -fn updates_only_last_activity_date_if_after_max_write_interval() { +#[tokio::test] +async fn updates_only_last_activity_date_if_after_max_write_interval() { let now = OffsetDateTime::now_utc(); - let store = Arc::new(Store::new(Box::::default())); + let sdk_directory = TempDir::new().unwrap(); let time_provider = Arc::new(TestTimeProvider::new(now)); let callbacks = Arc::new(MockCallbacks::default()); - let strategy = activity_based::Strategy::new( + let strategy = Strategy::activity_based( + sdk_directory.path(), Duration::seconds(30), - store.clone(), callbacks.clone(), time_provider.clone(), ); - let session_id = strategy.session_id(); + let session_id = strategy.session_id().await.unwrap(); callbacks.clear(); let advanced_time = now + std::time::Duration::from_secs(20); time_provider.set_time(advanced_time); - let second_session_id = strategy.session_id(); + let second_session_id = strategy.session_id().await.unwrap(); assert_eq!(session_id, second_session_id); assert!(callbacks.session_id_changes.lock().is_empty()); - assert_eq!( - ActivitySessionStrategyState { - session_id, - last_activity_timestamp: advanced_time.into_proto(), - ..Default::default() - }, - store.as_ref().get(&STATE_KEY).unwrap(), - ); } -#[test] -fn updates_session_and_last_activity_after_inactivity_threshold_is_exceeded() { +#[tokio::test] +async fn updates_session_and_last_activity_after_inactivity_threshold_is_exceeded() { let now = OffsetDateTime::now_utc(); - let store = Arc::new(Store::new(Box::::default())); + let sdk_directory = TempDir::new().unwrap(); let time_provider = Arc::new(TestTimeProvider::new(now)); let callbacks = Arc::new(MockCallbacks::default()); - let strategy = activity_based::Strategy::new( + let strategy = Strategy::activity_based( + sdk_directory.path(), Duration::seconds(30), - store.clone(), callbacks.clone(), time_provider.clone(), ); - let session_id = strategy.session_id(); + let session_id = strategy.session_id().await.unwrap(); callbacks.clear(); let advanced_time = now + std::time::Duration::from_secs(31); time_provider.set_time(advanced_time); - let second_session_id = strategy.session_id(); + let second_session_id = strategy.session_id().await.unwrap(); assert_eq!(1, callbacks.session_id_changes.lock().len()); assert_ne!(session_id, second_session_id); - assert_eq!( - ActivitySessionStrategyState { - session_id: second_session_id, - last_activity_timestamp: advanced_time.into_proto(), - ..Default::default() - }, - store.as_ref().get(&STATE_KEY).unwrap(), - ); assert_eq!(None, strategy.previous_process_session_id()); } -#[test] -fn refreshes_session_and_last_activity_after_reboot() { +#[tokio::test] +async fn refreshes_session_and_last_activity_after_reboot() { let now = OffsetDateTime::now_utc(); - let store = Arc::new(Store::new(Box::::default())); + let sdk_directory = TempDir::new().unwrap(); let time_provider = Arc::new(TestTimeProvider::new(now)); let callbacks = Arc::new(MockCallbacks::default()); - store.set( - &STATE_KEY, - &ActivitySessionStrategyState { - session_id: "foo".to_string(), - last_activity_timestamp: now.into_proto(), - ..Default::default() - }, - ); - - let strategy = activity_based::Strategy::new( + let strategy = Strategy::activity_based( + sdk_directory.path(), Duration::seconds(30), - store.clone(), callbacks.clone(), time_provider.clone(), ); - assert_eq!( - Some("foo".to_string()), - strategy.previous_process_session_id() - ); - let past_time = now - 5.seconds(); time_provider.set_time(past_time); - let session_id = strategy.session_id(); + let session_id = strategy.session_id().await.unwrap(); assert_eq!(1, callbacks.session_id_changes.lock().len()); - assert_ne!("foo", session_id); - assert_eq!( - ActivitySessionStrategyState { - session_id, - last_activity_timestamp: past_time.into_proto(), - ..Default::default() - }, - store.as_ref().get(&STATE_KEY).unwrap(), - ); - assert_eq!( - Some("foo".to_string()), - strategy.previous_process_session_id() - ); + assert_eq!(session_id, callbacks.session_id_changes.lock()[0]); } -#[test] -fn starts_new_session() { +#[tokio::test] +async fn starts_new_session() { let now = OffsetDateTime::now_utc(); - let store = Arc::new(Store::new(Box::::default())); + let sdk_directory = TempDir::new().unwrap(); let time_provider = Arc::new(TestTimeProvider::new(now)); let callbacks = Arc::new(MockCallbacks::default()); - let strategy = activity_based::Strategy::new( + let strategy = Strategy::activity_based( + sdk_directory.path(), Duration::seconds(30), - store.clone(), callbacks.clone(), time_provider.clone(), ); - let session_id = strategy.session_id(); + let session_id = strategy.session_id().await.unwrap(); callbacks.clear(); let advanced_time = now + 1.seconds(); time_provider.set_time(advanced_time); - strategy.start_new_session(); + strategy.start_new_session().await; - let next_session_id = strategy.session_id(); + let next_session_id = strategy.session_id().await.unwrap(); assert_ne!(session_id, next_session_id); assert!(callbacks.session_id_changes.lock().is_empty()); - assert_eq!( - ActivitySessionStrategyState { - session_id: next_session_id, - last_activity_timestamp: advanced_time.into_proto(), - ..Default::default() - }, - store.as_ref().get(&STATE_KEY).unwrap(), - ); assert!(strategy.previous_process_session_id().is_none()); } -#[test] -fn previous_session_id() { +#[tokio::test] +async fn previous_session_id() { let now = OffsetDateTime::now_utc(); - let store = Arc::new(Store::new(Box::::default())); + let sdk_directory = TempDir::new().unwrap(); let time_provider = Arc::new(TestTimeProvider::new(now)); let callbacks = Arc::new(MockCallbacks::default()); - let strategy = activity_based::Strategy::new( + let strategy = Strategy::activity_based( + sdk_directory.path(), Duration::seconds(30), - store.clone(), callbacks, time_provider, ); - store.set( - &STATE_KEY, - &ActivitySessionStrategyState { - session_id: "foo".to_string(), - last_activity_timestamp: now.into_proto(), - ..Default::default() - }, - ); - - assert_eq!( - Some("foo".to_string()), - strategy.previous_process_session_id() - ); + strategy.start_new_session().await; - strategy.start_new_session(); - - assert_eq!( - Some("foo".to_string()), - strategy.previous_process_session_id() - ); + assert!(strategy.previous_process_session_id().is_none()); - strategy.session_id(); + strategy.session_id().await.unwrap(); - assert_eq!( - Some("foo".to_string()), - strategy.previous_process_session_id() - ); + assert!(strategy.previous_process_session_id().is_none()); } -#[test] -fn flushes_state() { +#[tokio::test] +async fn flushes_state() { let now = OffsetDateTime::now_utc(); - let store = Arc::new(Store::new(Box::::default())); + let sdk_directory = TempDir::new().unwrap(); let time_provider = Arc::new(TestTimeProvider::new(now)); let callbacks = Arc::new(MockCallbacks::default()); - let strategy = activity_based::Strategy::new( + let strategy = Strategy::activity_based( + sdk_directory.path(), Duration::seconds(30), - store.clone(), callbacks, time_provider.clone(), ); - let session_id = strategy.session_id(); + let session_id = strategy.session_id().await.unwrap(); let advanced_time = now + 1.seconds(); time_provider.set_time(advanced_time); - let next_session_id = strategy.session_id(); + let next_session_id = strategy.session_id().await.unwrap(); - strategy.flush(); + strategy.flush().await; assert_eq!(session_id, next_session_id); - assert_eq!( - ActivitySessionStrategyState { - session_id: next_session_id, - last_activity_timestamp: advanced_time.into_proto(), - ..Default::default() - }, - store.as_ref().get(&STATE_KEY).unwrap(), - ); } diff --git a/bd-session/src/fixed.rs b/bd-session/src/fixed.rs index f911c4c8d..a3210f870 100644 --- a/bd-session/src/fixed.rs +++ b/bd-session/src/fixed.rs @@ -9,42 +9,24 @@ #[path = "./fixed_test.rs"] mod fixed_test; -use bd_key_value::{Key, Store}; -use bd_log::warn_every; -use bd_proto::protos::client::key_value::FixedSessionStrategyState; -use std::cell::Cell; +use crate::persistence::{BackendState, PersistedSessionState, StartedSessionRecord}; +use crate::{Initialization, LoadedState, Mutation}; use std::sync::Arc; -use thread_local::ThreadLocal; -use time::ext::NumericalDuration; +use time::OffsetDateTime; use uuid::Uuid; -/// The key used to store the state of the session strategy. -pub static STATE_KEY: Key = Key::new("session_strategy.fixed.state.1"); - // // Strategy // /// A session strategy that generates a new session ID on each SDK launch. pub struct Strategy { - store: Arc, callbacks: Arc, - - // Used to prevent a case where a Capture SDK customer calls into the logger to start a new - // session or obtain a session ID as part of the `generated_session_id` callback. - is_callback_in_progress: Box>>, - - state: parking_lot::Mutex>, } impl Strategy { - pub fn new(store: Arc, callbacks: Arc) -> Self { - Self { - store, - callbacks, - is_callback_in_progress: Box::new(ThreadLocal::new()), - state: parking_lot::Mutex::new(None), - } + pub fn new(callbacks: Arc) -> Self { + Self { callbacks } } /// Generates a new session ID using the provided callback or a random UUID if the callback @@ -53,142 +35,91 @@ impl Strategy { // Cannot log anything using `handle_unexpected` or similar as it would cause a cycle between // `ErrorReporter` and `Strategy`. As a reminder, `ErrorReporter` calls into `SessionProvider` // as part of error reporting flow. - let cell = self.is_callback_in_progress.get_or_default(); - cell.set(true); - - let session_id = self.callbacks.generate_session_id().unwrap_or_else(|_| { + self.callbacks.generate_session_id().unwrap_or_else(|_| { let id = Self::generate_uuid(); log::warn!("failed to generate a new session ID, using a random UUID instead {id:?}"); id - }); - cell.set(false); - - session_id + }) } fn generate_uuid() -> String { Uuid::new_v4().to_string() } - /// Returns the current session ID. If the session ID has not been generated yet we call through - /// to the provided callback to generate a new session ID. - /// - /// Note that if this is called from within the `generateSessionID` callback, we will return a - /// random UUID instead of the actual session ID to prevent deadlocks. - pub(crate) fn session_id(&self) -> String { - // Protect against cases where an attempt to read a session ID is made while already holding a - // lock. In practice, this happens when a customer of the SDK reads session ID from within a - // `generateSessionID` closure that they are allowed to provide to the SDK. - // - // In this case we cannot proceed to the logic below as we risk deadlocking, so we stand - // in a random UUID instead. - if self.is_callback_in_progress.get_or_default().get() { - warn_every!( - 15.seconds(), - "cannot obtain session ID from within 'generatedSessionID' {}", - "callback" - ); - - // TODO(snowp): This probably never does what the user expects as this session ID is not a - // real session ID but a random UUID. We should probably return an error here or just rework - // how all this works. - return Self::generate_uuid(); - } - - let mut guard = self.state.lock(); - // Clippy's proposal leads to code that doesn't compile. - #[allow(clippy::option_if_let_else)] - if let Some(state) = guard.as_ref() { - state.state.session_id.clone() - } else { - let previous_process_session_id = if let Some(state) = self.store.get(&STATE_KEY) { - Some(state.session_id) - } else { - None - }; - - let session_id = self.generate_session_id(); - - let state = InMemoryState { - state: FixedSessionStrategyState { - session_id: session_id.clone(), - ..Default::default() + pub(crate) fn initialize( + &self, + persisted: Option, + mut pending_started_sessions: Vec, + ) -> Initialization { + // Fixed sessions always create a fresh session on startup. The persisted current session is + // only used to seed `previous_process_session_id` for crash/error attribution. + let session_id = self.generate_session_id(); + let session_start = OffsetDateTime::now_utc(); + let previous_process_session_id = persisted.map(|state| state.current_session_id); + + pending_started_sessions.push(StartedSessionRecord::new(session_id.clone(), session_start)); + + Initialization { + state: LoadedState { + persisted: PersistedSessionState { + current_session_id: session_id, + current_session_start: session_start.into(), + previous_process_session_id, + backend: BackendState::Fixed, }, - previous_process_session_id, - }; - - *guard = Some(state.clone()); - - self.store.set(&STATE_KEY, &state.state); - - log::info!("bitdrift Capture initialized with session ID: {session_id:?}"); - - session_id + pending_started_sessions, + last_activity_write: None, + }, + mutation: Mutation { + persist_state: true, + persist_pending: true, + callback: None, + }, } } - /// Starts a new session by generating a new session ID and storing it in the state. - /// - /// Note that if this is called from within the `generateSessionID` callback, we will return an - /// error instead of starting a new session to prevent deadlocks. - pub(crate) fn start_new_session(&self) -> anyhow::Result { - // Protect against cases where an attempt to start a new session is made while already holding a - // lock. In practice, this happens when a customer of the SDK starts a new session from - // within a `generateSessionID` closure that they are allowed to provide to the SDK. - if self.is_callback_in_progress.get_or_default().get() { - anyhow::bail!("cannot start new session from within 'generatedSessionID' callback"); - } - - let mut guard = self.state.lock(); + pub(crate) fn on_session_id(_state: &mut LoadedState) -> Mutation { + Mutation::default() + } + pub(crate) fn start_new_session( + &self, + state: Option<&LoadedState>, + persisted: Option, + mut pending_started_sessions: Vec, + ) -> Initialization { + // Explicit session starts should preserve whatever we already consider the previous-process + // session rather than replacing it with the session we are rotating away from in this run. let session_id = self.generate_session_id(); + let session_start = OffsetDateTime::now_utc(); + let previous_process_session_id = state.as_ref().map_or_else( + || persisted.map(|state| state.current_session_id), + |state| state.persisted.previous_process_session_id.clone(), + ); - let state = guard.as_ref().map_or_else( - || match self.store.get(&STATE_KEY) { - Some(state) => InMemoryState { - state: FixedSessionStrategyState { - session_id: session_id.clone(), - ..Default::default() - }, - previous_process_session_id: Some(state.session_id), - }, - None => InMemoryState { - state: FixedSessionStrategyState { - session_id: session_id.clone(), - ..Default::default() - }, - previous_process_session_id: None, + pending_started_sessions.push(StartedSessionRecord::new(session_id.clone(), session_start)); + + Initialization { + state: LoadedState { + persisted: PersistedSessionState { + current_session_id: session_id, + current_session_start: session_start.into(), + previous_process_session_id, + backend: BackendState::Fixed, }, + pending_started_sessions, + last_activity_write: None, }, - |state| InMemoryState { - state: FixedSessionStrategyState { - session_id: session_id.clone(), - ..Default::default() - }, - previous_process_session_id: state.previous_process_session_id.clone(), + mutation: Mutation { + persist_state: true, + persist_pending: true, + callback: None, }, - ); - - self.store.set(&STATE_KEY, &state.state); - *guard = Some(state); - - Ok(session_id) - } - - /// Returns the last session ID from the previous SDK run. - pub fn previous_process_session_id(&self) -> Option { - self.state.lock().as_ref().map_or_else( - || self.store.get(&STATE_KEY).map(|state| state.session_id), - |state| state.previous_process_session_id.clone(), - ) + } } } -// -// Callbacks -// - pub trait Callbacks: Send + Sync { fn generate_session_id(&self) -> anyhow::Result; } @@ -205,14 +136,3 @@ impl Callbacks for UUIDCallbacks { Ok(Uuid::new_v4().to_string()) } } - -// -// InMemoryState -// - -#[derive(Clone, Debug)] -struct InMemoryState { - state: FixedSessionStrategyState, - /// The last active session ID from the previous SDK run. - previous_process_session_id: Option, -} diff --git a/bd-session/src/fixed_test.rs b/bd-session/src/fixed_test.rs index 3882d5989..1b5e28351 100644 --- a/bd-session/src/fixed_test.rs +++ b/bd-session/src/fixed_test.rs @@ -6,36 +6,28 @@ // https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt use super::{Callbacks, UUIDCallbacks}; -use crate::fixed::{self, STATE_KEY}; -use bd_key_value::{Storage, Store}; -use bd_proto::protos::client::key_value::FixedSessionStrategyState; +use crate::Strategy; use pretty_assertions::assert_eq; -use std::collections::HashMap; +use std::future::Future; +use std::pin::pin; use std::sync::Arc; +use std::task::{Context, Poll, Wake, Waker}; +use tempfile::TempDir; use uuid::Uuid; -#[derive(Default)] -pub struct MockStorage { - state: parking_lot::Mutex>, -} - -impl Storage for MockStorage { - fn set_string(&self, key: &str, value: &str) -> anyhow::Result<()> { - let mut guard = self.state.lock(); - let mut state = guard.clone(); - state.insert(key.to_string(), value.to_string()); - *guard = state; - - Ok(()) - } +struct NoopWake; - fn get_string(&self, key: &str) -> anyhow::Result> { - Ok(self.state.lock().get(key).cloned()) - } +impl Wake for NoopWake { + fn wake(self: Arc) {} +} - fn delete(&self, key: &str) -> anyhow::Result<()> { - self.state.lock().remove(key); - Ok(()) +fn expect_ready(future: impl Future) -> T { + let waker = Waker::from(Arc::new(NoopWake)); + let mut context = Context::from_waker(&waker); + let mut future = pin!(future); + match future.as_mut().poll(&mut context) { + Poll::Ready(value) => value, + Poll::Pending => panic!("future unexpectedly pending"), } } @@ -52,118 +44,93 @@ impl Callbacks for MockCallbacks { } } -#[test] -fn test_session_id() { - let store = Arc::new(Store::new(Box::::default())); +#[tokio::test] +async fn test_session_id() { + let sdk_directory = TempDir::new().unwrap(); let callbacks = Arc::new(MockCallbacks::default()); - let strategy = fixed::Strategy::new(store.clone(), callbacks.clone()); - - store.set( - &STATE_KEY, - &FixedSessionStrategyState { - session_id: "foo".to_string(), - ..Default::default() - }, - ); + let strategy = Strategy::fixed(sdk_directory.path(), callbacks.clone()); - let session_id = strategy.session_id(); + let session_id = strategy.session_id().await.unwrap(); let previous_session_id = strategy.previous_process_session_id(); assert_eq!(1, callbacks.generated_session_ids.lock().len()); assert_eq!(callbacks.generated_session_ids.lock()[0], session_id); - assert_eq!(Some("foo".to_string()), previous_session_id); + assert_eq!(None, previous_session_id); } -#[test] -fn test_start_new_session() { - let store = Arc::new(Store::new(Box::::default())); +#[tokio::test] +async fn test_start_new_session() { + let sdk_directory = TempDir::new().unwrap(); let callbacks = Arc::new(MockCallbacks::default()); - let strategy = fixed::Strategy::new(store.clone(), callbacks.clone()); - - store.set( - &STATE_KEY, - &FixedSessionStrategyState { - session_id: "foo".to_string(), - ..Default::default() - }, - ); + let strategy = Strategy::fixed(sdk_directory.path(), callbacks.clone()); - let session_id = strategy.session_id(); + let session_id = strategy.session_id().await.unwrap(); assert_eq!(1, callbacks.generated_session_ids.lock().len()); assert_eq!(callbacks.generated_session_ids.lock()[0], session_id); - let next_session_id = strategy.start_new_session().unwrap(); + strategy.start_new_session().await; + let next_session_id = strategy.session_id().await.unwrap(); - assert_eq!(next_session_id, strategy.session_id()); + assert_eq!(next_session_id, strategy.session_id().await.unwrap()); assert_eq!(2, callbacks.generated_session_ids.lock().len()); assert_eq!(callbacks.generated_session_ids.lock()[1], next_session_id); - assert_eq!( - Some("foo".to_string()), - strategy.previous_process_session_id() - ); + assert_eq!(None, strategy.previous_process_session_id()); } -#[test] -fn test_previous_process_session_id() { - let store = Arc::new(Store::new(Box::::default())); - let strategy = fixed::Strategy::new(store.clone(), Arc::new(UUIDCallbacks)); - - store.set( - &STATE_KEY, - &FixedSessionStrategyState { - session_id: "foo".to_string(), - ..Default::default() - }, - ); - - assert_eq!( - Some("foo".to_string()), - strategy.previous_process_session_id() - ); - - strategy.start_new_session().unwrap(); - let session_id = strategy.session_id(); +#[tokio::test] +async fn test_previous_process_session_id() { + let sdk_directory = TempDir::new().unwrap(); + let strategy = Strategy::fixed(sdk_directory.path(), Arc::new(UUIDCallbacks)); + strategy.session_id().await.unwrap(); + strategy.start_new_session().await; + let session_id = strategy.session_id().await.unwrap(); - assert_eq!( - Some("foo".to_string()), - strategy.previous_process_session_id() - ); + assert!(strategy.previous_process_session_id().is_none()); - let strategy = fixed::Strategy::new(store, Arc::new(UUIDCallbacks)); + let strategy = Strategy::fixed(sdk_directory.path(), Arc::new(UUIDCallbacks)); assert_eq!(Some(session_id), strategy.previous_process_session_id()); } #[derive(Default)] struct ReEntryCallbacks { - session_strategy: parking_lot::Mutex>>, + session_strategy: parking_lot::Mutex>>, + inner_session_id_error: parking_lot::Mutex>, } impl Callbacks for ReEntryCallbacks { fn generate_session_id(&self) -> anyhow::Result { if let Some(strategy) = &*self.session_strategy.lock() { - return strategy.start_new_session(); + expect_ready(strategy.start_new_session()); + let error = expect_ready(strategy.session_id()).unwrap_err(); + *self.inner_session_id_error.lock() = Some(error.to_string()); + anyhow::bail!(error); } Ok("should not happen".to_string()) } } -#[test] -fn handles_re_entry() { - let store = Arc::new(Store::new(Box::::default())); +#[tokio::test] +async fn handles_re_entry() { + let sdk_directory = TempDir::new().unwrap(); let callbacks = Arc::new(ReEntryCallbacks::default()); - let strategy = Arc::new(fixed::Strategy::new(store, callbacks.clone())); + let strategy = Arc::new(Strategy::fixed(sdk_directory.path(), callbacks.clone())); callbacks.session_strategy.lock().replace(strategy.clone()); // Confirm that it doesn't deadlock and returns a reasonable ID. - let session_id = strategy.session_id(); + let session_id = strategy.session_id().await.unwrap(); assert_eq!(36, session_id.len()); + assert_eq!( + Some("session_id cannot be called from within a session callback".to_string()), + callbacks.inner_session_id_error.lock().clone() + ); // Confirm that it doesn't deadlock and returns a reasonable ID. - let new_session_id = strategy.start_new_session().unwrap(); + strategy.start_new_session().await; + let new_session_id = strategy.session_id().await.unwrap(); assert_eq!(36, new_session_id.len()); assert_ne!(session_id, new_session_id); diff --git a/bd-session/src/lib.rs b/bd-session/src/lib.rs index 323b607d4..51d9d8b07 100644 --- a/bd-session/src/lib.rs +++ b/bd-session/src/lib.rs @@ -5,6 +5,17 @@ // LICENSE file or at: // https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt +//! Session management is split into three layers: +//! 1. A backend-specific strategy decides when a session ID should change. +//! 2. This module persists the current session plus a durable queue of started sessions that still +//! need to be announced to the server. +//! 3. The API layer consumes `PendingStateUpdate` values from that durable queue and acknowledges +//! them once the server has accepted the update. +//! +//! The important consequence is that session creation and session announcement are intentionally +//! decoupled. A process can rotate or create a session locally, crash, and still reconstruct the +//! correct state update to send on the next startup. + #![deny( clippy::expect_used, clippy::panic, @@ -16,8 +27,11 @@ pub mod activity_based; pub mod fixed; +mod persistence; -pub use bd_key_value::Store; +#[cfg(test)] +#[path = "./lib_test.rs"] +mod lib_test; #[cfg(test)] #[ctor::ctor] @@ -25,54 +39,449 @@ fn test_global_init() { bd_test_helpers::test_global_init(); } +use bd_proto::protos::client::api::StateUpdateRequest; +use bd_proto::protos::client::api::state_update_request::StartedSession; +use bd_time::{OffsetDateTimeExt as _, TimeProvider}; +use persistence::{PersistedSessionState, StartedSessionRecord, Store}; +use std::cell::Cell; +use std::path::Path; +use std::sync::Arc; +use thread_local::ThreadLocal; +use time::OffsetDateTime; +use tokio::sync::watch; + // -// Strategy +// LoadedState +// + +/// In-memory session state combines the persisted wire format with transient bookkeeping that is +/// only meaningful for the current process. +#[derive(Clone, Debug)] +pub(crate) struct LoadedState { + persisted: PersistedSessionState, + pending_started_sessions: Vec, + last_activity_write: Option, +} + +// +// Mutation +// + +#[derive(Clone, Debug, Default)] +pub(crate) struct Mutation { + persist_state: bool, + persist_pending: bool, + callback: Option, +} + +// +// Initialization // -pub enum Strategy { +#[derive(Clone, Debug)] +pub(crate) struct Initialization { + state: LoadedState, + mutation: Mutation, +} + +// +// DeferredCallback +// + +#[derive(Clone, Debug)] +pub(crate) enum DeferredCallback { + ActivitySessionChanged(String), +} + +// +// PendingStateUpdate +// + +#[derive(Clone, Debug)] +pub struct PendingStateUpdate { + request: StateUpdateRequest, + started_sessions: Vec, +} + +impl PendingStateUpdate { + #[must_use] + pub const fn request(&self) -> &StateUpdateRequest { + &self.request + } +} + +// +// Backend +// + +enum Backend { Fixed(fixed::Strategy), ActivityBased(activity_based::Strategy), } +// +// Strategy +// + +pub struct Strategy { + backend: Backend, + store: Store, + state: parking_lot::Mutex>, + update_tx: watch::Sender, + callback_in_progress: Box>>, +} + impl Strategy { - pub fn session_id(&self) -> String { - match self { - Self::Fixed(strategy) => strategy.session_id(), - Self::ActivityBased(strategy) => strategy.session_id(), + #[must_use] + pub fn fixed(sdk_directory: impl AsRef, callbacks: Arc) -> Self { + let (update_tx, _) = watch::channel(0); + Self { + backend: Backend::Fixed(fixed::Strategy::new(callbacks)), + store: Store::new(sdk_directory), + state: parking_lot::Mutex::new(None), + update_tx, + callback_in_progress: Box::new(ThreadLocal::new()), } } - pub fn start_new_session(&self) { - let new_session_id = match self { - Self::Fixed(strategy) => strategy.start_new_session(), - Self::ActivityBased(strategy) => Ok(strategy.start_new_session()), + #[must_use] + pub fn activity_based( + sdk_directory: impl AsRef, + inactivity_threshold: time::Duration, + callbacks: Arc, + time_provider: Arc, + ) -> Self { + let (update_tx, _) = watch::channel(0); + Self { + backend: Backend::ActivityBased(activity_based::Strategy::new( + inactivity_threshold, + callbacks, + time_provider, + )), + store: Store::new(sdk_directory), + state: parking_lot::Mutex::new(None), + update_tx, + callback_in_progress: Box::new(ThreadLocal::new()), + } + } + + #[must_use] + pub fn subscribe_updates(&self) -> watch::Receiver { + self.update_tx.subscribe() + } + + pub async fn session_id(&self) -> anyhow::Result { + self.ensure_not_in_callback("session_id")?; + + let (session_id, state, mutation) = { + let mut guard = self.state.lock(); + if let Some(state) = guard.as_mut() { + // Session reads and activity updates share the same mutation path so activity-based + // sessions can rotate or persist last-activity state while fixed sessions stay unchanged. + let mutation = match &self.backend { + Backend::Fixed(_) => fixed::Strategy::on_session_id(state), + Backend::ActivityBased(strategy) => strategy.on_session_id(state), + }; + let session_id = state.persisted.current_session_id.clone(); + (session_id, state.clone(), mutation) + } else { + // The first read initializes from durable state and may enqueue a deferred callback if the + // backend decides the current access should create or rotate a session. + let initialization = self.initialize_state(); + let session_id = initialization.state.persisted.current_session_id.clone(); + *guard = Some(initialization.state.clone()); + (session_id, initialization.state, initialization.mutation) + } }; - match new_session_id { - Ok(new_session_id) => log::info!("bitdrift Capture started new session: {new_session_id:?}"), - Err(e) => log::error!("bitdrift Capture failed to start new session: {e:?}"), + let callback = self.finish_mutation(state, mutation).await; + self.run_callback(callback); + Ok(session_id) + } + + pub async fn start_new_session(&self) { + if let Err(e) = self.ensure_not_in_callback("start_new_session") { + log::error!("bitdrift Capture failed to start new session: {e:?}"); + return; } + + let (session_id, state, mutation) = { + let mut guard = self.state.lock(); + self.start_new_session_locked(&mut guard) + }; + + let callback = self.finish_mutation(state, mutation).await; + self.run_callback(callback); + log::info!("bitdrift Capture started new session: {session_id:?}"); } - pub fn flush(&self) { - if let Self::ActivityBased(strategy) = self { - strategy.flush(); + fn ensure_not_in_callback(&self, operation: &str) -> anyhow::Result<()> { + if self.callback_in_progress.get_or_default().get() { + anyhow::bail!("{operation} cannot be called from within a session callback"); + } + + Ok(()) + } + + fn with_callback_guard(&self, f: impl FnOnce() -> T) -> T { + let cell = self.callback_in_progress.get_or_default(); + let was_in_progress = cell.replace(true); + let result = f(); + cell.set(was_in_progress); + result + } + + pub async fn flush(&self) { + let Some(state) = self.state.lock().clone() else { + log::debug!("no session state to flush"); + return; + }; + + if let Err(e) = self.store.persist_state(&state.persisted).await { + log::warn!("failed to persist session state during flush: {e}"); } } /// The last active session ID from the previous SDK run. pub fn previous_process_session_id(&self) -> Option { - match self { - Self::Fixed(strategy) => strategy.previous_process_session_id(), - Self::ActivityBased(strategy) => strategy.previous_process_session_id(), + self.state.lock().as_ref().map_or_else( + || { + self + .store + .load_state() + .map(|state| state.current_session_id) + }, + |state| state.persisted.previous_process_session_id.clone(), + ) + } + + pub async fn handshake_state_update(&self) -> PendingStateUpdate { + let state = self.load_state_for_update().await; + + let mut request_started_sessions = state.pending_started_sessions.clone(); + // Handshakes must always include the current session. If the queue only contains older pending + // starts, synthesize the current entry without mutating durable state. + if !request_started_sessions + .iter() + .any(|started| started.session_id == state.persisted.current_session_id) + { + request_started_sessions.push(StartedSessionRecord { + session_id: state.persisted.current_session_id.clone(), + start_time: state.persisted.current_session_start, + }); + } + + PendingStateUpdate { + request: StateUpdateRequest { + started_sessions: request_started_sessions + .iter() + .map(StartedSessionRecord::to_proto) + .collect(), + ..Default::default() + }, + started_sessions: state.pending_started_sessions, + } + } + + pub async fn pending_state_update(&self) -> Option { + // Mid-stream state updates only send the durable queue. Unlike the handshake, they do not + // synthesize the current session because the queue should already contain every unsent start. + let state = self.load_state_for_update().await; + + if state.pending_started_sessions.is_empty() { + return None; + } + + let started_sessions = state.pending_started_sessions; + Some(PendingStateUpdate { + request: StateUpdateRequest { + started_sessions: started_sessions + .iter() + .map(StartedSessionRecord::to_proto) + .collect(), + ..Default::default() + }, + started_sessions, + }) + } + + pub async fn acknowledge_state_update(&self, update: &PendingStateUpdate) { + if update.started_sessions.is_empty() { + return; + } + + let pending_started_sessions = { + let mut guard = self.state.lock(); + if guard.is_none() { + *guard = Some(LoadedState { + persisted: self.store.load_state().unwrap_or_default(), + pending_started_sessions: self.store.load_pending_started_sessions(), + last_activity_write: None, + }); + } + + let Some(state) = guard.as_mut() else { + return; + }; + + // Responses are not correlated, so we only advance the durable queue when the acknowledged + // set matches the prefix we most recently sent. + if !starts_with_sessions(&state.pending_started_sessions, &update.started_sessions) { + return; + } + + state + .pending_started_sessions + .drain(.. update.started_sessions.len()); + state.pending_started_sessions.clone() + }; + + if let Err(e) = self + .store + .persist_pending_started_sessions(&pending_started_sessions) + .await + { + log::warn!("failed to persist acknowledged started sessions: {e}"); + } else { + self.notify_update(); } } /// Pretty name of the strategy. pub const fn type_name(&self) -> &'static str { - match self { - Self::Fixed(_) => "fixed", - Self::ActivityBased(_) => "activity_based", + match self.backend { + Backend::Fixed(_) => "fixed", + Backend::ActivityBased(_) => "activity_based", + } + } + + fn initialize_state(&self) -> Initialization { + // The persisted current session and the persisted pending queue are loaded together so the + // backend makes decisions from a consistent snapshot of durable state. + let persisted = self.store.load_state(); + let pending_started_sessions = self.store.load_pending_started_sessions(); + + match &self.backend { + Backend::Fixed(strategy) => { + self.with_callback_guard(|| strategy.initialize(persisted, pending_started_sessions)) + }, + Backend::ActivityBased(strategy) => strategy.initialize(persisted, pending_started_sessions), + } + } + + async fn load_state_for_update(&self) -> LoadedState { + let (state, mutation) = { + let mut guard = self.state.lock(); + if let Some(state) = guard.clone() { + return state; + } + + // State-update callers can be the first code path to touch session state. Initialize lazily, + // then drop the lock before invoking any deferred callback. + let initialization = self.initialize_state(); + *guard = Some(initialization.state.clone()); + (initialization.state, initialization.mutation) + }; + + let callback = self.finish_mutation(state.clone(), mutation).await; + self.run_callback(callback); + state + } + + fn start_new_session_locked( + &self, + guard: &mut parking_lot::MutexGuard<'_, Option>, + ) -> (String, LoadedState, Mutation) { + // Explicit session rotation re-reads persisted state so the durable queue remains the source + // of truth even if this process has not initialized the in-memory cache yet. + let initialization = match &self.backend { + Backend::Fixed(strategy) => self.with_callback_guard(|| { + strategy.start_new_session( + guard.as_ref(), + self.store.load_state(), + self.store.load_pending_started_sessions(), + ) + }), + Backend::ActivityBased(strategy) => strategy.start_new_session( + guard.as_ref(), + self.store.load_state(), + self.store.load_pending_started_sessions(), + ), + }; + + let session_id = initialization.state.persisted.current_session_id.clone(); + **guard = Some(initialization.state.clone()); + (session_id, initialization.state, initialization.mutation) + } + + async fn finish_mutation( + &self, + state: LoadedState, + mutation: Mutation, + ) -> Option { + let pending_changed = mutation.persist_pending; + let callback = mutation.callback.clone(); + self.persist_loaded_state(&state, &mutation).await; + if pending_changed { + self.notify_update(); + } + callback + } + + async fn persist_loaded_state(&self, state: &LoadedState, mutation: &Mutation) { + // The strategy returns a mutation describing which durable pieces changed. Persist only those + // pieces so reads can stay cheap while the on-disk view remains crash-safe. + if mutation.persist_state + && let Err(e) = self.store.persist_state(&state.persisted).await + { + log::warn!("failed to persist session state: {e}"); + } + + if mutation.persist_pending + && let Err(e) = self + .store + .persist_pending_started_sessions(&state.pending_started_sessions) + .await + { + log::warn!("failed to persist started sessions: {e}"); + } + } + + fn run_callback(&self, callback: Option) { + // Deferred callbacks run after state is persisted and locks are dropped so user code cannot + // observe half-applied transitions or deadlock against session APIs. + match callback { + Some(DeferredCallback::ActivitySessionChanged(session_id)) => { + if let Backend::ActivityBased(strategy) = &self.backend { + self.with_callback_guard(|| strategy.run_callback(&session_id)); + } + }, + None => {}, + } + } + + fn notify_update(&self) { + self + .update_tx + .send_modify(|version| *version = version.wrapping_add(1)); + } +} + +fn starts_with_sessions( + pending: &[StartedSessionRecord], + acknowledged: &[StartedSessionRecord], +) -> bool { + // State-update responses are uncorrelated, so the best we can do is verify that the ack matches + // the prefix we most recently sent before trimming the durable queue. + pending.starts_with(acknowledged) +} + +impl StartedSessionRecord { + fn to_proto(&self) -> StartedSession { + StartedSession { + session_id: self.session_id.clone(), + start_time: OffsetDateTime::from(self.start_time).into_proto(), + ..Default::default() } } } diff --git a/bd-session/src/lib_test.rs b/bd-session/src/lib_test.rs new file mode 100644 index 000000000..303d3730c --- /dev/null +++ b/bd-session/src/lib_test.rs @@ -0,0 +1,161 @@ +// shared-core - bitdrift's common client/server libraries +// Copyright Bitdrift, Inc. All rights reserved. +// +// Use of this source code is governed by a source available license that can be found in the +// LICENSE file or at: +// https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt + +use super::{PendingStateUpdate, Strategy}; +use crate::fixed; +use bd_proto::protos::client::api::StateUpdateRequest; +use pretty_assertions::assert_eq; +use std::collections::VecDeque; +use std::sync::Arc; +use tempfile::TempDir; + +// +// FixedCallbacks +// + +struct FixedCallbacks { + session_ids: parking_lot::Mutex>, +} + +impl FixedCallbacks { + fn new(session_ids: &[&str]) -> Self { + Self { + session_ids: parking_lot::Mutex::new( + session_ids + .iter() + .map(|session_id| (*session_id).to_string()) + .collect(), + ), + } + } +} + +impl fixed::Callbacks for FixedCallbacks { + fn generate_session_id(&self) -> anyhow::Result { + self + .session_ids + .lock() + .pop_front() + .ok_or_else(|| anyhow::anyhow!("missing test session id")) + } +} + +fn fixed_strategy(sdk_directory: &TempDir, session_ids: &[&str]) -> Strategy { + Strategy::fixed( + sdk_directory.path(), + Arc::new(FixedCallbacks::new(session_ids)), + ) +} + +fn started_session_ids(request: &StateUpdateRequest) -> Vec { + request + .started_sessions + .iter() + .map(|session| session.session_id.clone()) + .collect() +} + +#[tokio::test] +async fn handshake_synthesizes_current_session_after_pending_queue_is_acked() { + let sdk_directory = TempDir::new().unwrap(); + let strategy = fixed_strategy(&sdk_directory, &["session-1"]); + + let session_id = strategy.session_id().await.unwrap(); + let pending = strategy.pending_state_update().await.unwrap(); + + assert_eq!( + vec![session_id.clone()], + started_session_ids(pending.request()) + ); + + strategy.acknowledge_state_update(&pending).await; + + assert!(strategy.pending_state_update().await.is_none()); + + let handshake = strategy.handshake_state_update().await; + assert_eq!(vec![session_id], started_session_ids(handshake.request())); + assert!(handshake.started_sessions.is_empty()); +} + +#[tokio::test] +async fn acknowledge_state_update_ignores_non_prefix_updates() { + let sdk_directory = TempDir::new().unwrap(); + let strategy = fixed_strategy(&sdk_directory, &["session-1", "session-2"]); + + strategy.session_id().await.unwrap(); + strategy.start_new_session().await; + + let pending = strategy.pending_state_update().await.unwrap(); + assert_eq!( + vec!["session-1".to_string(), "session-2".to_string()], + started_session_ids(pending.request()) + ); + + let fake_update = PendingStateUpdate { + request: StateUpdateRequest::default(), + started_sessions: vec![pending.started_sessions[1].clone()], + }; + + strategy.acknowledge_state_update(&fake_update).await; + + let still_pending = strategy.pending_state_update().await.unwrap(); + assert_eq!( + vec!["session-1".to_string(), "session-2".to_string()], + started_session_ids(still_pending.request()) + ); +} + +#[tokio::test] +async fn subscribe_updates_changes_on_initialization_and_acknowledgement() { + let sdk_directory = TempDir::new().unwrap(); + let strategy = fixed_strategy(&sdk_directory, &["session-1"]); + let updates = strategy.subscribe_updates(); + + assert_eq!(0, *updates.borrow()); + + let pending = strategy.pending_state_update().await.unwrap(); + assert_eq!(1, *updates.borrow()); + + strategy.acknowledge_state_update(&pending).await; + assert_eq!(2, *updates.borrow()); +} + +#[tokio::test] +async fn restart_rebuilds_pending_queue_from_persisted_state() { + let sdk_directory = TempDir::new().unwrap(); + + let first_strategy = fixed_strategy(&sdk_directory, &["session-1"]); + let first_session_id = first_strategy.session_id().await.unwrap(); + drop(first_strategy); + + let restarted_strategy = fixed_strategy(&sdk_directory, &["session-2"]); + let pending = restarted_strategy.pending_state_update().await.unwrap(); + + assert_eq!( + vec![first_session_id, "session-2".to_string()], + started_session_ids(pending.request()) + ); + assert_eq!( + Some("session-1".to_string()), + restarted_strategy.previous_process_session_id() + ); +} + +#[tokio::test] +async fn handshake_does_not_duplicate_current_session_when_queue_already_contains_it() { + let sdk_directory = TempDir::new().unwrap(); + let strategy = fixed_strategy(&sdk_directory, &["session-1"]); + + strategy.session_id().await.unwrap(); + + let handshake = strategy.handshake_state_update().await; + assert_eq!( + vec!["session-1".to_string()], + started_session_ids(handshake.request()) + ); + assert_eq!(1, handshake.started_sessions.len()); +} diff --git a/bd-session/src/persistence.rs b/bd-session/src/persistence.rs new file mode 100644 index 000000000..0d3a1921a --- /dev/null +++ b/bd-session/src/persistence.rs @@ -0,0 +1,167 @@ +// shared-core - bitdrift's common client/server libraries +// Copyright Bitdrift, Inc. All rights reserved. +// +// Use of this source code is governed by a source available license that can be found in the +// LICENSE file or at: +// https://polyformproject.org/wp-content/uploads/2020/06/PolyForm-Shield-1.0.0.txt + +use bd_client_common::file::{read_compressed, write_compressed}; +use bd_client_common::file_system::{delete_file_if_exists_async, write_file_atomic}; +use bd_macros::proto_serializable; +use bd_proto_util::serialization::{ + ProtoMessageDeserialize, + ProtoMessageSerialize, + TimestampMicros, +}; +use std::path::{Path, PathBuf}; +use time::OffsetDateTime; + +const STATE_FILE_NAME: &str = "current_session.pb"; +const PENDING_STARTED_SESSIONS_FILE_NAME: &str = "pending_started_sessions.pb"; + +// +// PersistedSessionState +// + +#[proto_serializable] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct PersistedSessionState { + #[field(id = 1)] + pub current_session_id: String, + #[field(id = 2)] + pub current_session_start: TimestampMicros, + #[field(id = 3)] + pub previous_process_session_id: Option, + #[field(id = 4)] + pub backend: BackendState, +} + +// +// BackendState +// + +#[proto_serializable] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub enum BackendState { + #[field(id = 1)] + #[field(deserialize)] + #[default] + Fixed, + #[field(id = 2)] + #[field(deserialize)] + ActivityBased { + #[field(id = 1)] + last_activity: TimestampMicros, + }, +} + +// +// PendingStartedSessions +// + +#[proto_serializable] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct PendingStartedSessions { + #[field(id = 1)] + pub sessions: Vec, +} + +// +// StartedSessionRecord +// + +#[proto_serializable] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct StartedSessionRecord { + #[field(id = 1)] + pub session_id: String, + #[field(id = 2)] + pub start_time: TimestampMicros, +} + +impl StartedSessionRecord { + pub fn new(session_id: String, start_time: OffsetDateTime) -> Self { + Self { + session_id, + start_time: start_time.into(), + } + } +} + +// +// Store +// + +#[derive(Clone, Debug)] +pub struct Store { + directory: PathBuf, +} + +impl Store { + #[must_use] + pub fn new(sdk_directory: impl AsRef) -> Self { + Self { + directory: sdk_directory.as_ref().join("state").join("session"), + } + } + + pub fn load_state(&self) -> Option { + Self::read_message::(&self.state_file_path()) + } + + pub async fn persist_state(&self, state: &PersistedSessionState) -> anyhow::Result<()> { + Self::write_message(&self.state_file_path(), state).await + } + + pub fn load_pending_started_sessions(&self) -> Vec { + Self::read_message::(&self.pending_started_sessions_file_path()) + .map_or_else(Vec::new, |pending| pending.sessions) + } + + pub async fn persist_pending_started_sessions( + &self, + sessions: &[StartedSessionRecord], + ) -> anyhow::Result<()> { + // An empty queue is represented by the file being absent so that a restart cannot + // accidentally resurrect stale session announcements. + if sessions.is_empty() { + return delete_file_if_exists_async(&self.pending_started_sessions_file_path()).await; + } + + Self::write_message( + &self.pending_started_sessions_file_path(), + &PendingStartedSessions { + sessions: sessions.to_vec(), + }, + ) + .await + } + + fn state_file_path(&self) -> PathBuf { + self.directory.join(STATE_FILE_NAME) + } + + fn pending_started_sessions_file_path(&self) -> PathBuf { + self.directory.join(PENDING_STARTED_SESSIONS_FILE_NAME) + } + + fn read_message(path: &Path) -> Option { + let bytes = std::fs::read(path).ok()?; + match read_compressed(&bytes).and_then(|bytes| T::deserialize_message_from_bytes(&bytes)) { + Ok(message) => Some(message), + Err(e) => { + // Treat unreadable state as self-healing corruption. We drop the file so the caller can + // rebuild from a clean slate rather than failing every startup. + log::warn!("failed to read session state from {}: {e}", path.display()); + let _ = std::fs::remove_file(path); + None + }, + } + } + + async fn write_message(path: &Path, message: &T) -> anyhow::Result<()> { + let bytes = message.serialize_message_to_bytes()?; + let compressed = write_compressed(&bytes)?; + write_file_atomic(path, &compressed).await + } +} diff --git a/bd-state/src/lib.rs b/bd-state/src/lib.rs index 9d6e68996..193f817b1 100644 --- a/bd-state/src/lib.rs +++ b/bd-state/src/lib.rs @@ -42,6 +42,9 @@ use tokio::sync::RwLock; /// The key used for storing the current system session ID in the state store. pub const SYSTEM_SESSION_ID_KEY: &str = "sid"; +/// The key used for storing the current entity ID in the state store. +pub const ENTITY_ID_KEY: &str = "entity_id"; + /// Creates a `StateValue` from a string. #[must_use] pub fn string_value(s: impl Into) -> Value { diff --git a/bd-workflows/Cargo.toml b/bd-workflows/Cargo.toml index 6a743ecd9..641cefecf 100644 --- a/bd-workflows/Cargo.toml +++ b/bd-workflows/Cargo.toml @@ -57,7 +57,7 @@ tempfile.workspace = true tokio-test.workspace = true [target.'cfg(target_os = "linux")'.dev-dependencies] -gungraun = { version = "0.18.1", features = ["client_requests"] } +gungraun = { version = "0.18.2", features = ["client_requests"] } simplelog = "0.12.2" [[bench]] diff --git a/bd-workflows/src/config.rs b/bd-workflows/src/config.rs index 144ff29c3..f5089696b 100644 --- a/bd-workflows/src/config.rs +++ b/bd-workflows/src/config.rs @@ -608,6 +608,9 @@ impl Transition { state_change_match: StateChangeMatch::try_from_proto(rule)?, extra_matcher: rule.log_matcher.as_ref().map(Tree::new).transpose()?, }, + Rule_type::OnNewSession(_) => { + anyhow::bail!("invalid transition configuration: on_new_session is not supported yet") + }, }; let actions = transition diff --git a/bd-workspace-hack/Cargo.toml b/bd-workspace-hack/Cargo.toml index 6bb831070..a06fd5bdf 100644 --- a/bd-workspace-hack/Cargo.toml +++ b/bd-workspace-hack/Cargo.toml @@ -96,7 +96,7 @@ errno = { version = "0.3" } getrandom-9fbad63c4bcf4a8f = { package = "getrandom", version = "0.4", default-features = false, features = ["std", "sys_rng"] } hyper-util = { version = "0.1", default-features = false, features = ["client-proxy", "client-proxy-system"] } libc = { version = "0.2", default-features = false, features = ["extra_traits"] } -miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } +miniz_oxide = { version = "0.9", default-features = false, features = ["simd", "with-alloc"] } security-framework-sys = { version = "2" } tower = { version = "0.5", default-features = false, features = ["timeout"] } tower-http = { version = "0.6", features = ["compression-deflate", "decompression-deflate", "follow-redirect"] } @@ -106,7 +106,7 @@ errno = { version = "0.3" } getrandom-9fbad63c4bcf4a8f = { package = "getrandom", version = "0.4", default-features = false, features = ["std", "sys_rng"] } hyper-util = { version = "0.1", default-features = false, features = ["client-proxy", "client-proxy-system"] } libc = { version = "0.2", default-features = false, features = ["extra_traits"] } -miniz_oxide = { version = "0.8", default-features = false, features = ["simd", "with-alloc"] } +miniz_oxide = { version = "0.9", default-features = false, features = ["simd", "with-alloc"] } security-framework-sys = { version = "2" } tower = { version = "0.5", default-features = false, features = ["timeout"] } tower-http = { version = "0.6", features = ["compression-deflate", "decompression-deflate", "follow-redirect"] } diff --git a/logger-cli/src/logger.rs b/logger-cli/src/logger.rs index f55c30878..ec0cf2a07 100644 --- a/logger-cli/src/logger.rs +++ b/logger-cli/src/logger.rs @@ -94,7 +94,7 @@ impl LoggerHolder { pub fn start_new_session(&self) { let handle = self.logger.lock().new_logger_handle(); - handle.start_new_session(); + handle.start_new_session().unwrap(); } pub fn set_sleep_mode(&self, enabled: bool) { @@ -290,10 +290,7 @@ pub async fn make_logger(sdk_directory: &Path, args: &LoggerArgs) -> anyhow::Res let (logger, _, future, _) = bd_logger::LoggerBuilder::new(InitParams { sdk_directory: sdk_directory.to_path_buf(), api_key: args.api_key.clone(), - session_strategy: Arc::new(Strategy::Fixed(fixed::Strategy::new( - store.clone(), - session_callbacks, - ))), + session_strategy: Arc::new(Strategy::fixed(sdk_directory, session_callbacks)), metadata_provider: Arc::new(LiveTimestampMetadata { ootb_fields: [( "_app_version_code".into(), diff --git a/logger-cli/src/service.rs b/logger-cli/src/service.rs index 1970982fa..bd3d37166 100644 --- a/logger-cli/src/service.rs +++ b/logger-cli/src/service.rs @@ -162,8 +162,14 @@ impl Remote for Server { } async fn start_new_session(self, _: ::tarpc::context::Context) { - if let Some(logger) = &*LOGGER.lock() { - logger.start_new_session(); + let logger = { + let guard = LOGGER.lock(); + guard.as_ref().map(|logger| logger.logger.clone()) + }; + + if let Some(logger) = logger { + let handle = logger.lock().new_logger_handle(); + handle.start_new_session().unwrap(); } }