feat: remove retrieval batch over HTTP

This commit is contained in:
2026-10-02 15:00:50 +09:00
parent 3c4dbf3ad0
commit dc9a7f0dbf
18 changed files with 107 additions and 1232 deletions
+3 -3
View File
@@ -4,7 +4,7 @@
//!
//! - [`wip_protocol`] owns logical requests and responses;
//! - [`wip_host`] owns object publication, validators, and typed dispatch;
//! - [`wip_http`] owns routes, JSON, envelopes, batching, and status mapping;
//! - [`wip_http`] owns routes, JSON, envelopes, and status mapping;
//! - this crate owns the filesystem capability boundary and the real HTTP listener.
//!
//! The built-in HTTP listener is intentionally loopback-only. TLS termination,
@@ -36,7 +36,7 @@ pub enum AccessMode {
/// Bounded resource policy applied by the HTTP adapter and filesystem provider.
#[derive(Debug, Clone, Copy)]
pub struct ResourceLimits {
/// Standard JSON, body-size, nesting, and batch limits.
/// Standard JSON, body-size, and nesting limits.
pub wire: wip_http::Limits,
/// Maximum bytes returned by one file read.
pub max_file_read_bytes: usize,
@@ -59,7 +59,7 @@ pub struct ResourceLimits {
impl Default for ResourceLimits {
fn default() -> Self {
Self {
wire: wip_http::Limits::new(256 * 1024, 2 * 1024 * 1024, 64, 64)
wire: wip_http::Limits::new(256 * 1024, 2 * 1024 * 1024, 64)
.expect("default wire limits are nonzero"),
max_file_read_bytes: 1024 * 1024,
max_file_write_bytes: 1024 * 1024,
+8 -76
View File
@@ -9,11 +9,10 @@ use http::header::ALLOW;
use http::{Request, Response, StatusCode};
use wip_host::{ExecutionContext, ObjectProvider};
use wip_http::{
BatchRequestKind, BatchResponse, BatchResponseItem, BatchSuccess, CodecError, EncodeHttpError,
Endpoint, RequestMetadataError, Route, decode_batch_request, decode_call_operation_metadata,
decode_fetch_interface_request, decode_observe_request, encode_batch_error_response,
encode_batch_response, encode_call_operation_response, encode_fetch_interface_response,
encode_observe_response, encode_protocol_error_response, validate_http_request,
CodecError, EncodeHttpError, Endpoint, RequestMetadataError, Route,
decode_call_operation_metadata, decode_fetch_interface_request, decode_observe_request,
encode_call_operation_response, encode_fetch_interface_response, encode_observe_response,
encode_protocol_error_response, validate_http_request,
};
use wip_protocol::{ProtocolError, ProtocolErrorCode, ProtocolInteraction};
@@ -81,7 +80,6 @@ impl WipFsServer {
Route::Observe => self.observe(request.body(), &context),
Route::FetchInterface => self.fetch_interface(request.body()),
Route::CallOperation => self.call_operation(request.body(), &context),
Route::Batch => self.batch(request.body(), &context),
};
if Instant::now() >= deadline {
empty_response(StatusCode::GATEWAY_TIMEOUT)
@@ -115,14 +113,9 @@ impl WipFsServer {
if uri.query().is_some() {
return None;
}
[
Route::Observe,
Route::FetchInterface,
Route::CallOperation,
Route::Batch,
]
.into_iter()
.find(|route| self.endpoint.route(*route).path() == uri.path())
[Route::Observe, Route::FetchInterface, Route::CallOperation]
.into_iter()
.find(|route| self.endpoint.route(*route).path() == uri.path())
}
fn observe(&self, body: &[u8], context: &ExecutionContext) -> Response<Vec<u8>> {
@@ -221,41 +214,6 @@ impl WipFsServer {
}
}
fn batch(&self, body: &[u8], context: &ExecutionContext) -> Response<Vec<u8>> {
let request = match decode_batch_request(body, self.config.limits.wire) {
Ok(request) => request,
Err(error) => return self.batch_codec_error(error),
};
let responses = request
.requests
.iter()
.map(|item| {
let outcome = match &item.request {
BatchRequestKind::Observe(request) => self
.projection
.observe(context, request)
.map(BatchSuccess::Observe),
BatchRequestKind::FetchInterface(request) => self
.projection
.fetch_interface(request)
.map(BatchSuccess::FetchInterface),
BatchRequestKind::Invalid { error, .. } => Err(error.clone()),
};
BatchResponseItem {
id: item.id.clone(),
outcome,
}
})
.collect();
let response = BatchResponse { responses };
encode_batch_response(&request, &response, self.config.limits.wire).unwrap_or_else(
|error| match error {
EncodeHttpError::Codec(codec) => self.batch_encode_error(&codec),
EncodeHttpError::Http(_) => self.batch_top_error(&internal_error()),
},
)
}
fn metadata_error(&self, error: RequestMetadataError) -> Response<Vec<u8>> {
match error {
RequestMetadataError::NotFound => empty_response(StatusCode::NOT_FOUND),
@@ -294,17 +252,6 @@ impl WipFsServer {
}
}
fn batch_codec_error(&self, error: CodecError) -> Response<Vec<u8>> {
if is_transport_limit(&error) {
empty_response(StatusCode::PAYLOAD_TOO_LARGE)
} else {
self.batch_top_error(&ProtocolError {
code: ProtocolErrorCode::InvalidRequest,
message: "malformed WIP batch request".into(),
})
}
}
fn read_encode_error(
&self,
interaction: ProtocolInteraction,
@@ -318,14 +265,6 @@ impl WipFsServer {
}
}
fn batch_encode_error(&self, error: &CodecError) -> Response<Vec<u8>> {
if is_transport_limit(error) {
empty_response(StatusCode::INTERNAL_SERVER_ERROR)
} else {
self.batch_top_error(&internal_error())
}
}
fn protocol_error(
&self,
interaction: ProtocolInteraction,
@@ -334,11 +273,6 @@ impl WipFsServer {
encode_protocol_error_response(interaction, error, self.config.limits.wire)
.unwrap_or_else(|_| empty_response(StatusCode::INTERNAL_SERVER_ERROR))
}
fn batch_top_error(&self, error: &ProtocolError) -> Response<Vec<u8>> {
encode_batch_error_response(error, self.config.limits.wire)
.unwrap_or_else(|_| empty_response(StatusCode::INTERNAL_SERVER_ERROR))
}
}
/// Bound real HTTP listener for a [`WipFsServer`].
@@ -629,9 +563,7 @@ fn write_all_with_deadline(
fn is_transport_limit(error: &CodecError) -> bool {
matches!(
error,
CodecError::BodyTooLarge { .. }
| CodecError::NestingTooDeep { .. }
| CodecError::TooManyBatchItems { .. }
CodecError::BodyTooLarge { .. } | CodecError::NestingTooDeep { .. }
)
}