Further work on streams and multiprocessing
This commit is contained in:
parent
2da89cf138
commit
f9e56cffc4
|
@ -1,3 +1,5 @@
|
||||||
|
import io
|
||||||
|
import os
|
||||||
from abc import abstractmethod, ABC
|
from abc import abstractmethod, ABC
|
||||||
from structio.core.task import Task
|
from structio.core.task import Task
|
||||||
from structio.exceptions import StructIOException
|
from structio.exceptions import StructIOException
|
||||||
|
@ -65,26 +67,7 @@ class StreamWriter(AsyncResource, ABC):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def write_all(self, data: bytes):
|
async def write(self, data):
|
||||||
"""
|
|
||||||
Write the given data onto the stream,
|
|
||||||
possibly blocking
|
|
||||||
"""
|
|
||||||
|
|
||||||
return NotImplemented
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def wait_for_write(self):
|
|
||||||
"""
|
|
||||||
Wait until the underlying resource is
|
|
||||||
ready to be written on. Implementations
|
|
||||||
of this method should try their best not
|
|
||||||
to return until the underlying resource is
|
|
||||||
known to be ready, but it's not guaranteed
|
|
||||||
that a call to write_all() will not block
|
|
||||||
after calling this method
|
|
||||||
"""
|
|
||||||
|
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,34 +80,7 @@ class StreamReader(AsyncResource, ABC):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def read_some(self, max_size: int | None = None) -> bytes:
|
async def _read(self, size: int = -1):
|
||||||
"""
|
|
||||||
Read up to max_size bytes from the underlying
|
|
||||||
resource and return it. When max_size is None,
|
|
||||||
implementors should pick a reasonable default.
|
|
||||||
Returns b"" iff the stream has reached end-of-file
|
|
||||||
"""
|
|
||||||
|
|
||||||
async def __aiter__(self):
|
|
||||||
return self
|
|
||||||
|
|
||||||
async def __anext__(self):
|
|
||||||
if not (data := await self.read_some()):
|
|
||||||
raise StopAsyncIteration()
|
|
||||||
return data
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def wait_for_read(self):
|
|
||||||
"""
|
|
||||||
Wait until the underlying resource is
|
|
||||||
ready to be read from. Implementations
|
|
||||||
of this method should try their best not
|
|
||||||
to return until the underlying resource is
|
|
||||||
known to be ready, but it's not guaranteed
|
|
||||||
that a call to read_some() will not block
|
|
||||||
after calling this method
|
|
||||||
"""
|
|
||||||
|
|
||||||
return NotImplemented
|
return NotImplemented
|
||||||
|
|
||||||
|
|
||||||
|
@ -133,6 +89,13 @@ class Stream(StreamReader, StreamWriter, ABC):
|
||||||
A generic, asynchronous, readable/writable binary stream
|
A generic, asynchronous, readable/writable binary stream
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(self, f):
|
||||||
|
if isinstance(f, io.TextIOBase):
|
||||||
|
raise TypeError("only binary files can be streamed")
|
||||||
|
self.fileobj = f
|
||||||
|
self.buf = bytearray()
|
||||||
|
os.set_blocking(self.fileobj.fileno(), False)
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
async def flush(self):
|
async def flush(self):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
import io
|
import io
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
import structio
|
import structio
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from structio.abc import AsyncResource
|
from structio.abc import AsyncResource, Stream
|
||||||
from structio.core.syscalls import check_cancelled
|
from structio.core.syscalls import check_cancelled, wait_writable, wait_readable, checkpoint
|
||||||
|
from structio.io import WantRead, WantWrite
|
||||||
|
from structio.exceptions import ResourceClosed
|
||||||
|
|
||||||
# Stolen from Trio
|
# Stolen from Trio
|
||||||
_FILE_SYNC_ATTRS = {
|
_FILE_SYNC_ATTRS = {
|
||||||
|
|
|
@ -32,6 +32,8 @@ class Popen:
|
||||||
os.set_blocking(stdin.fileno(), True)
|
os.set_blocking(stdin.fileno(), True)
|
||||||
# Delegate to Popen's constructor
|
# Delegate to Popen's constructor
|
||||||
self._process = subprocess.Popen(*args, **kwargs)
|
self._process = subprocess.Popen(*args, **kwargs)
|
||||||
|
if self._process.stdin:
|
||||||
|
self.stdin = None
|
||||||
|
|
||||||
def __getattr__(self, item):
|
def __getattr__(self, item):
|
||||||
# Delegate to internal process object
|
# Delegate to internal process object
|
||||||
|
|
Loading…
Reference in New Issue