mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 09:58:04 +08:00
feat: implement transport abstractions for virtual environments and add E2B environment provider
This commit is contained in:
@ -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)
|
||||
|
||||
66
api/core/virtual_environment/channel/queue_transport.py
Normal file
66
api/core/virtual_environment/channel/queue_transport.py
Normal 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)
|
||||
@ -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()
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user