feat: implement transport abstractions for virtual environments and add E2B environment provider

This commit is contained in:
Yeuoly
2025-12-31 17:51:38 +08:00
parent 29dc083d8d
commit c9610e9949
10 changed files with 518 additions and 41 deletions

View File

@ -1,6 +1,6 @@
import os
from core.virtual_environment.channel.transport import Transport
from core.virtual_environment.channel.transport import Transport, TransportReadCloser, TransportWriteCloser
class PipeTransport(Transport):
@ -26,3 +26,33 @@ class PipeTransport(Transport):
def close(self) -> None:
os.close(self.r_fd)
os.close(self.w_fd)
class PipeReadCloser(TransportReadCloser):
"""
A Transport implementation using OS pipe for reading.
"""
def __init__(self, r_fd: int):
self.r_fd = r_fd
def read(self, n: int) -> bytes:
return os.read(self.r_fd, n)
def close(self) -> None:
os.close(self.r_fd)
class PipeWriteCloser(TransportWriteCloser):
"""
A Transport implementation using OS pipe for writing.
"""
def __init__(self, w_fd: int):
self.w_fd = w_fd
def write(self, data: bytes) -> None:
os.write(self.w_fd, data)
def close(self) -> None:
os.close(self.w_fd)

View File

@ -0,0 +1,66 @@
from queue import Queue
from core.virtual_environment.channel.transport import TransportReadCloser
class QueueTransportReadCloser(TransportReadCloser):
"""
Transport implementation using queues for inter-thread communication.
Usage:
q_transport = QueueTransportReadCloser()
write_handler = q_transport.get_write_handler()
# In writer thread
write_handler.write(b"data")
# In reader thread
data = q_transport.read(1024)
# Close transport when done
q_transport.close()
"""
class WriteHandler:
"""
A write handler that writes data to a queue.
"""
def __init__(self, queue: Queue[bytes | None]) -> None:
self.queue = queue
def write(self, data: bytes) -> None:
self.queue.put(data)
def __init__(
self,
) -> None:
"""
Initialize the QueueTransportReadCloser with write function.
"""
self.q = Queue[bytes | None]()
def get_write_handler(self) -> WriteHandler:
"""
Get a write handler that writes to the internal queue.
"""
return QueueTransportReadCloser.WriteHandler(self.q)
def close(self) -> None:
"""
Close the transport by putting a sentinel value in the queue.
"""
self.q.put(None)
def read(self, n: int) -> bytes:
"""
Read up to n bytes from the queue.
"""
data = bytearray()
while len(data) < n:
chunk = self.q.get()
if chunk is None:
break
data.extend(chunk)
return bytes(data)

View File

@ -1,6 +1,6 @@
import socket
from core.virtual_environment.channel.transport import Transport
from core.virtual_environment.channel.transport import Transport, TransportReadCloser, TransportWriteCloser
class SocketTransport(Transport):
@ -19,3 +19,33 @@ class SocketTransport(Transport):
def close(self) -> None:
self.sock.close()
class SocketReadCloser(TransportReadCloser):
"""
A Transport implementation using a socket for reading.
"""
def __init__(self, sock: socket.SocketIO):
self.sock = sock
def read(self, n: int) -> bytes:
return self.sock.read(n)
def close(self) -> None:
self.sock.close()
class SocketWriteCloser(TransportWriteCloser):
"""
A Transport implementation using a socket for writing.
"""
def __init__(self, sock: socket.SocketIO):
self.sock = sock
def write(self, data: bytes) -> None:
self.sock.write(data)
def close(self) -> None:
self.sock.close()

View File

@ -2,24 +2,75 @@ from abc import abstractmethod
from typing import Protocol
class Transport(Protocol):
@abstractmethod
def write(self, data: bytes) -> None:
"""
Write data to the transport.
"""
pass
@abstractmethod
def read(self, n: int) -> bytes:
"""
Read up to n bytes from the transport.
"""
pass
class TransportCloser(Protocol):
"""
Transport that can be closed.
"""
@abstractmethod
def close(self) -> None:
"""
Close the transport.
"""
class TransportWriter(Protocol):
"""
Transport that can be written to.
"""
@abstractmethod
def write(self, data: bytes) -> None:
"""
Write data to the transport.
"""
class TransportReader(Protocol):
"""
Transport that can be read from.
"""
@abstractmethod
def read(self, n: int) -> bytes:
"""
Read up to n bytes from the transport.
"""
class TransportReadCloser(TransportReader, TransportCloser):
"""
Transport that can be read from and closed.
"""
class TransportWriteCloser(TransportWriter, TransportCloser):
"""
Transport that can be written to and closed.
"""
class Transport(TransportReader, TransportWriter, TransportCloser):
"""
Transport that can be read from, written to, and closed.
"""
class NopTransportWriteCloser(TransportWriteCloser):
"""
A no-operation TransportWriteCloser implementation.
This transport does nothing on write and close operations.
"""
def write(self, data: bytes) -> None:
"""
No-operation write method.
"""
pass
def close(self) -> None:
"""
No-operation close method.
"""
pass