runtime: avoid ticket backend blocking panic
This commit is contained in:
parent
2b0901eb62
commit
18d9b96cac
|
|
@ -313,7 +313,6 @@ impl FeatureModule for TicketFeature {
|
||||||
struct WorkspaceHttpTicketBackend {
|
struct WorkspaceHttpTicketBackend {
|
||||||
workspace_id: String,
|
workspace_id: String,
|
||||||
base_url: String,
|
base_url: String,
|
||||||
client: reqwest::blocking::Client,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WorkspaceHttpTicketBackend {
|
impl WorkspaceHttpTicketBackend {
|
||||||
|
|
@ -321,7 +320,6 @@ impl WorkspaceHttpTicketBackend {
|
||||||
Self {
|
Self {
|
||||||
workspace_id,
|
workspace_id,
|
||||||
base_url: base_url.trim_end_matches('/').to_string(),
|
base_url: base_url.trim_end_matches('/').to_string(),
|
||||||
client: reqwest::blocking::Client::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -335,13 +333,27 @@ impl WorkspaceHttpTicketBackend {
|
||||||
fn invoke(
|
fn invoke(
|
||||||
&self,
|
&self,
|
||||||
operation: TicketBackendOperation,
|
operation: TicketBackendOperation,
|
||||||
|
) -> TicketResult<TicketBackendOperationResult> {
|
||||||
|
let endpoint = self.endpoint();
|
||||||
|
if tokio::runtime::Handle::try_current().is_ok() {
|
||||||
|
return std::thread::spawn(move || Self::invoke_http(endpoint, operation))
|
||||||
|
.join()
|
||||||
|
.map_err(|_| {
|
||||||
|
TicketError::Conflict("ticket backend request thread panicked".to_string())
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
Self::invoke_http(endpoint, operation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn invoke_http(
|
||||||
|
endpoint: String,
|
||||||
|
operation: TicketBackendOperation,
|
||||||
) -> TicketResult<TicketBackendOperationResult> {
|
) -> TicketResult<TicketBackendOperationResult> {
|
||||||
let body = serde_json::to_string(&operation).map_err(|error| {
|
let body = serde_json::to_string(&operation).map_err(|error| {
|
||||||
TicketError::Conflict(format!("serialize ticket operation: {error}"))
|
TicketError::Conflict(format!("serialize ticket operation: {error}"))
|
||||||
})?;
|
})?;
|
||||||
let response = self
|
let response = reqwest::blocking::Client::new()
|
||||||
.client
|
.post(endpoint)
|
||||||
.post(self.endpoint())
|
|
||||||
.header(reqwest::header::CONTENT_TYPE, "application/json")
|
.header(reqwest::header::CONTENT_TYPE, "application/json")
|
||||||
.body(body)
|
.body(body)
|
||||||
.send()
|
.send()
|
||||||
|
|
@ -981,6 +993,20 @@ provider = "github"
|
||||||
assert!(!root.join("closed").exists());
|
assert!(!root.join("closed").exists());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test(flavor = "multi_thread")]
|
||||||
|
async fn workspace_http_backend_invoke_is_safe_inside_async_context() {
|
||||||
|
let backend =
|
||||||
|
WorkspaceHttpTicketBackend::new("workspace-a".to_string(), "not-a-url".to_string());
|
||||||
|
|
||||||
|
let error = backend
|
||||||
|
.invoke(TicketBackendOperation::DefaultIntakeReadyStateChangeBody {
|
||||||
|
from: "planning".to_string(),
|
||||||
|
})
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
|
assert!(error.to_string().contains("ticket backend request failed"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn workspace_http_backend_executes_ticket_create_operation() {
|
fn workspace_http_backend_executes_ticket_create_operation() {
|
||||||
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
let listener = TcpListener::bind("127.0.0.1:0").unwrap();
|
||||||
|
|
|
||||||
|
|
@ -318,7 +318,7 @@ start_runtime() {
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
start_service runtime "$ROOT_DIR" "$port" \
|
start_service runtime "$ROOT_DIR" "$port" \
|
||||||
"$runtime_bin" --bind "$RUNTIME_BIND"
|
env RUST_BACKTRACE="${RUST_BACKTRACE:-1}" "$runtime_bin" --bind "$RUNTIME_BIND"
|
||||||
}
|
}
|
||||||
|
|
||||||
start_backend() {
|
start_backend() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user