Publish Clusterflux 45bbc21
This commit is contained in:
parent
eb1077f380
commit
3f88254c70
28 changed files with 896 additions and 167 deletions
|
|
@ -240,6 +240,7 @@ pub(crate) fn run_adapter() -> Result<()> {
|
|||
}
|
||||
Err(message) => {
|
||||
state.breakpoints_installed = false;
|
||||
emit_unverified_breakpoints(&mut writer, &state, &message)?;
|
||||
writer.output("stderr", format!("{message}\n"))?;
|
||||
}
|
||||
}
|
||||
|
|
@ -1025,6 +1026,28 @@ fn emit_verified_breakpoints(writer: &mut DapWriter, state: &AdapterState) -> Re
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn emit_unverified_breakpoints(
|
||||
writer: &mut DapWriter,
|
||||
state: &AdapterState,
|
||||
coordinator_error: &str,
|
||||
) -> Result<()> {
|
||||
for (index, line) in state.breakpoints.iter().enumerate() {
|
||||
writer.event(
|
||||
"breakpoint",
|
||||
json!({
|
||||
"reason": "changed",
|
||||
"breakpoint": {
|
||||
"id": index + 1,
|
||||
"verified": false,
|
||||
"line": line,
|
||||
"message": format!("Coordinator breakpoint installation failed: {coordinator_error}"),
|
||||
}
|
||||
}),
|
||||
)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn emit_thread_lifecycle(
|
||||
writer: &mut DapWriter,
|
||||
previous: &BTreeMap<i64, VirtualThread>,
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use debug_protocol::{
|
|||
};
|
||||
use local_tools::{child_stderr_suffix, local_tool_command};
|
||||
pub(crate) use transport::client_user_request;
|
||||
use transport::{coordinator_request, CoordinatorSession};
|
||||
use transport::{coordinator_request, coordinator_request_allow_error, CoordinatorSession};
|
||||
|
||||
pub(crate) struct LocalRuntimeSession {
|
||||
coordinator: Option<Child>,
|
||||
|
|
@ -300,7 +300,8 @@ fn launch_services_debug_entrypoint(
|
|||
) -> Result<RuntimeLaunchRecord> {
|
||||
let bundle = build_debug_bundle(state, repo)?;
|
||||
validate_inline_bundle_size(bundle.module_size_bytes)?;
|
||||
let started = match coordinator_request(
|
||||
let launch_attempt = new_launch_attempt_id();
|
||||
let started = match coordinator_request_allow_error(
|
||||
coordinator,
|
||||
client_user_request(
|
||||
state,
|
||||
|
|
@ -310,25 +311,56 @@ fn launch_services_debug_entrypoint(
|
|||
"project": state.project_id,
|
||||
"actor_user": state.actor_user,
|
||||
"process": state.process.as_str(),
|
||||
"launch_attempt": launch_attempt,
|
||||
"restart": state.restart_existing,
|
||||
}),
|
||||
),
|
||||
) {
|
||||
Ok(started) => started,
|
||||
Err(error) => return Err(debug_launch_error_with_rollback(coordinator, state, error)),
|
||||
Err(error) => {
|
||||
return Err(debug_launch_error_with_rollback(
|
||||
coordinator,
|
||||
state,
|
||||
&launch_attempt,
|
||||
error,
|
||||
));
|
||||
}
|
||||
};
|
||||
if started.get("type").and_then(Value::as_str) == Some("error") {
|
||||
return Err(anyhow!(
|
||||
"{}",
|
||||
started
|
||||
.get("message")
|
||||
.and_then(Value::as_str)
|
||||
.unwrap_or("coordinator rejected the debug launch")
|
||||
));
|
||||
}
|
||||
if started.get("launch_attempt").and_then(Value::as_str) != Some(launch_attempt.as_str()) {
|
||||
return Err(debug_launch_error_with_rollback(
|
||||
coordinator,
|
||||
state,
|
||||
&launch_attempt,
|
||||
anyhow!("coordinator returned a debug launch owned by a different attempt"),
|
||||
));
|
||||
}
|
||||
let epoch = match started.get("epoch").and_then(Value::as_u64) {
|
||||
Some(epoch) => epoch,
|
||||
None => {
|
||||
return Err(debug_launch_error_with_rollback(
|
||||
coordinator,
|
||||
state,
|
||||
&launch_attempt,
|
||||
anyhow!("coordinator did not report a process epoch"),
|
||||
));
|
||||
}
|
||||
};
|
||||
if let Err(error) = set_services_debug_breakpoints_at(coordinator, state) {
|
||||
return Err(debug_launch_error_with_rollback(coordinator, state, error));
|
||||
return Err(debug_launch_error_with_rollback(
|
||||
coordinator,
|
||||
state,
|
||||
&launch_attempt,
|
||||
error,
|
||||
));
|
||||
}
|
||||
let launch = match coordinator_request(
|
||||
coordinator,
|
||||
|
|
@ -368,12 +400,20 @@ fn launch_services_debug_entrypoint(
|
|||
),
|
||||
) {
|
||||
Ok(launch) => launch,
|
||||
Err(error) => return Err(debug_launch_error_with_rollback(coordinator, state, error)),
|
||||
Err(error) => {
|
||||
return Err(debug_launch_error_with_rollback(
|
||||
coordinator,
|
||||
state,
|
||||
&launch_attempt,
|
||||
error,
|
||||
));
|
||||
}
|
||||
};
|
||||
if launch.get("type").and_then(Value::as_str) != Some("main_launched") {
|
||||
return Err(debug_launch_error_with_rollback(
|
||||
coordinator,
|
||||
state,
|
||||
&launch_attempt,
|
||||
anyhow!(
|
||||
"coordinator did not start the capless main runtime: {}",
|
||||
serde_json::to_string(&launch)?
|
||||
|
|
@ -432,6 +472,7 @@ fn validate_inline_bundle_size(module_size_bytes: usize) -> Result<()> {
|
|||
fn debug_launch_error_with_rollback(
|
||||
coordinator: &str,
|
||||
state: &AdapterState,
|
||||
launch_attempt: &str,
|
||||
launch_error: anyhow::Error,
|
||||
) -> anyhow::Error {
|
||||
let rollback = coordinator_request(
|
||||
|
|
@ -444,6 +485,7 @@ fn debug_launch_error_with_rollback(
|
|||
"project": state.project_id,
|
||||
"actor_user": state.actor_user,
|
||||
"process": state.process.as_str(),
|
||||
"launch_attempt": launch_attempt,
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
|
@ -460,7 +502,27 @@ fn debug_launch_error_with_rollback(
|
|||
}
|
||||
}
|
||||
|
||||
static NEXT_LAUNCH_ATTEMPT: std::sync::atomic::AtomicU64 = std::sync::atomic::AtomicU64::new(1);
|
||||
|
||||
fn new_launch_attempt_id() -> String {
|
||||
let sequence = NEXT_LAUNCH_ATTEMPT.fetch_add(1, Ordering::Relaxed);
|
||||
let nanos = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap_or_default()
|
||||
.as_nanos();
|
||||
format!("dap-launch-{}-{nanos}-{sequence}", std::process::id())
|
||||
}
|
||||
|
||||
fn set_services_debug_breakpoints_at(coordinator: &str, state: &AdapterState) -> Result<()> {
|
||||
static INJECTED_INSTALL_FAILURE: AtomicBool = AtomicBool::new(false);
|
||||
if std::env::var_os("CLUSTERFLUX_TEST_DAP_BREAKPOINT_INSTALLATION_FAILURE").is_some()
|
||||
&& !state.breakpoints.is_empty()
|
||||
&& !INJECTED_INSTALL_FAILURE.swap(true, Ordering::SeqCst)
|
||||
{
|
||||
return Err(anyhow!(
|
||||
"coordinator breakpoint installation failed: injected live-install failure"
|
||||
));
|
||||
}
|
||||
coordinator_request(
|
||||
coordinator,
|
||||
client_user_request(
|
||||
|
|
@ -1267,7 +1329,7 @@ pub(crate) fn observe_services_runtime(
|
|||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
poll_delay = (poll_delay * 2).min(Duration::from_secs(1));
|
||||
poll_delay = (poll_delay * 2).min(Duration::from_secs(5));
|
||||
}
|
||||
std::thread::sleep(poll_delay);
|
||||
}
|
||||
|
|
@ -1449,6 +1511,7 @@ mod transactional_launch_tests {
|
|||
let error = debug_launch_error_with_rollback(
|
||||
&address,
|
||||
&state,
|
||||
"launch-test",
|
||||
anyhow!("launch acknowledgement was lost"),
|
||||
);
|
||||
assert!(error
|
||||
|
|
|
|||
|
|
@ -33,8 +33,7 @@ impl CoordinatorSession {
|
|||
}
|
||||
|
||||
pub(super) fn request(&mut self, request: Value) -> Result<Value> {
|
||||
let wire_request = coordinator_wire_request("dap-1", request);
|
||||
let response = self.session.request(&wire_request)?;
|
||||
let response = self.request_allow_error(request)?;
|
||||
if response.get("type").and_then(Value::as_str) == Some("error") {
|
||||
return Err(anyhow!(
|
||||
"{}",
|
||||
|
|
@ -46,8 +45,17 @@ impl CoordinatorSession {
|
|||
}
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
pub(super) fn request_allow_error(&mut self, request: Value) -> Result<Value> {
|
||||
let wire_request = coordinator_wire_request("dap-1", request);
|
||||
Ok(self.session.request(&wire_request)?)
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn coordinator_request(addr: &str, request: Value) -> Result<Value> {
|
||||
CoordinatorSession::connect(addr)?.request(request)
|
||||
}
|
||||
|
||||
pub(super) fn coordinator_request_allow_error(addr: &str, request: Value) -> Result<Value> {
|
||||
CoordinatorSession::connect(addr)?.request_allow_error(request)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue