38 lines
1.1 KiB
Python
38 lines
1.1 KiB
Python
import logging
|
|
from collections import deque
|
|
|
|
from funcy import repeatedly, identity
|
|
|
|
from pyinfra.exceptions import NoBufferCapacity
|
|
from pyinfra.server.dispatcher.dispatcher import Nothing
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def bufferize(fn, buffer_size=3, persist_fn=identity, null_value=None):
|
|
def buffered_fn(item):
|
|
|
|
if item is not Nothing:
|
|
buffer.append(persist_fn(item))
|
|
|
|
response_payload = fn(repeatedly(buffer.popleft, n_items_to_pop(buffer, item is Nothing)))
|
|
|
|
return response_payload or null_value
|
|
|
|
def buffer_full(current_buffer_size):
|
|
if current_buffer_size > buffer_size:
|
|
logger.warning(f"Overfull buffer. size: {current_buffer_size}; intended capacity: {buffer_size}")
|
|
|
|
return current_buffer_size == buffer_size
|
|
|
|
def n_items_to_pop(buffer, final):
|
|
current_buffer_size = len(buffer)
|
|
return (final or buffer_full(current_buffer_size)) * current_buffer_size
|
|
|
|
if not buffer_size > 0:
|
|
raise NoBufferCapacity("Buffer size must be greater than zero.")
|
|
|
|
buffer = deque()
|
|
|
|
return buffered_fn
|