diff --git a/core/Cargo.toml b/core/Cargo.toml index 6e9af4669..9609b54b7 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -18,6 +18,7 @@ otel = ["dep:opentelemetry", "dep:opentelemetry_sdk", "dep:opentelemetry-otlp", "dep:opentelemetry-prometheus", "dep:hyper", "dep:hyper-util", "dep:http-body-util"] tokio-console = ["console-subscriber"] ephemeral-server = ["dep:flate2", "dep:reqwest", "dep:tar", "dep:zip"] +debug-plugin = ["dep:reqwest"] [dependencies] anyhow = "1.0" diff --git a/core/src/debug_client.rs b/core/src/debug_client.rs new file mode 100644 index 000000000..ca5f21d55 --- /dev/null +++ b/core/src/debug_client.rs @@ -0,0 +1,78 @@ +//! Defines an http client that is used for the VSCode debug plugin and any other associated +//! machinery. + +use anyhow::Context; +use hyper::http::HeaderValue; +use prost::Message; +use reqwest::{self, header::HeaderMap}; +use std::time::Duration; +use temporal_sdk_core_protos::temporal::api::history::v1::History; +use url::Url; + +/// A client for interacting with the VSCode debug plugin +#[derive(Clone)] +pub struct DebugClient { + /// URL for the local instance of the debugger server + debugger_url: Url, + client: reqwest::Client, +} + +#[derive(Clone, serde::Serialize)] +struct WFTStartedMsg { + event_id: i64, +} + +impl DebugClient { + /// Create a new instance of a DebugClient with the specified url and client name/version + /// strings. + pub fn new( + url: String, + client_name: &str, + client_version: &str, + ) -> Result { + let mut client = reqwest::ClientBuilder::new(); + client = client.default_headers({ + let mut hm = HeaderMap::new(); + hm.insert("temporal-client-name", HeaderValue::from_str(client_name)?); + hm.insert( + "temporal-client-version", + HeaderValue::from_str(client_version)?, + ); + hm + }); + let client = client.build()?; + Ok(DebugClient { + debugger_url: Url::parse(&url).context( + "debugger url malformed, is the TEMPORAL_DEBUGGER_PLUGIN_URL env var correct?", + )?, + client, + }) + } + + /// Get the history from the instance of the debug plugin server + pub async fn get_history(&self) -> Result { + let url = self.debugger_url.join("history")?; + let resp = self.client.get(url).send().await?; + + let bytes = resp.bytes().await?; + Ok(History::decode(bytes)?) + } + + /// Post to current-wft-started to tell the debug plugin which event we've most recently made it + /// to + pub async fn post_wft_started( + &self, + event_id: &i64, + ) -> Result { + let url = self.debugger_url.join("current-wft-started")?; + Ok(self + .client + .get(url) + .timeout(Duration::from_secs(5)) + .json(&WFTStartedMsg { + event_id: *event_id, + }) + .send() + .await?) + } +} diff --git a/core/src/lib.rs b/core/src/lib.rs index 6a2796601..724d84ac2 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -12,6 +12,8 @@ extern crate tracing; extern crate core; mod abstractions; +#[cfg(feature = "debug-plugin")] +pub mod debug_client; #[cfg(feature = "ephemeral-server")] pub mod ephemeral_server; mod internal_flags;