mirror of
https://github.com/openai/codex.git
synced 2026-10-18 17:18:52 +00:00
Share byte buffers across exec-server output chunks (#49972)
## Why Retaining process output, publishing events, and serving reads cloned the underlying byte buffers. Sharing those buffers avoids copying output bytes when chunks are cloned. ## What changed Store `ByteChunk` bytes in `Arc<Vec<u8>>` and retain `ProcessOutputChunk` values directly. Add borrowed byte access for the MCP process transport while preserving base64 serialization and owned byte extraction through `into_inner()`. ## Testing Add a unit test covering base64 serialization, deserialization, and independent owned bytes extracted from shared chunks. GitOrigin-RevId: 6bba114af48424aa844487aa75163cfc604e0575
This commit is contained in:
@@ -60,19 +60,26 @@ pub const HTTP_REQUEST_BODY_DELTA_METHOD: &str = "http/request/bodyDelta";
|
||||
/// Maximum decoded response-body bytes carried by one streamed HTTP notification.
|
||||
pub const MAX_HTTP_BODY_DELTA_BYTES: usize = 1024 * 1024;
|
||||
|
||||
/// Shared immutable bytes, encoded as a base64 string on the wire.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct ByteChunk(#[serde(with = "base64_bytes")] pub Vec<u8>);
|
||||
pub struct ByteChunk(#[serde(with = "base64_bytes")] pub Arc<Vec<u8>>);
|
||||
|
||||
impl ByteChunk {
|
||||
pub fn into_inner(self) -> Vec<u8> {
|
||||
self.0
|
||||
Arc::unwrap_or_clone(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<u8>> for ByteChunk {
|
||||
fn from(value: Vec<u8>) -> Self {
|
||||
Self(value)
|
||||
Self(Arc::new(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<[u8]> for ByteChunk {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1193,6 +1200,7 @@ mod base64_bytes {
|
||||
use serde::Deserialize;
|
||||
use serde::Deserializer;
|
||||
use serde::Serializer;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub fn serialize<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
@@ -1201,13 +1209,14 @@ mod base64_bytes {
|
||||
serializer.serialize_str(&BASE64_STANDARD.encode(bytes))
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<Arc<Vec<u8>>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let encoded = String::deserialize(deserializer)?;
|
||||
BASE64_STANDARD
|
||||
.decode(encoded)
|
||||
.map(Arc::new)
|
||||
.map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
@@ -1264,6 +1273,24 @@ mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[test]
|
||||
fn shared_byte_chunks_preserve_base64_and_owned_bytes() {
|
||||
let chunk = super::ByteChunk::from(vec![0, 255, 10]);
|
||||
let shared = chunk.clone();
|
||||
assert_eq!(serde_json::to_string(&shared).unwrap(), r#""AP8K""#);
|
||||
assert_eq!(
|
||||
serde_json::from_str::<super::ByteChunk>(r#""AP8K""#).unwrap(),
|
||||
chunk,
|
||||
);
|
||||
|
||||
let mut owned = shared.into_inner();
|
||||
owned[0] = 1;
|
||||
assert_eq!(
|
||||
(owned, chunk.into_inner()),
|
||||
(vec![1, 255, 10], vec![0, 255, 10])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_params_keeps_proxy_launch_separate_from_sandbox_facts() {
|
||||
let cwd =
|
||||
|
||||
Reference in New Issue
Block a user