Класс-декоратор Python: буфер событий и пакетная запись
Напишите решение на Python и проверьте его на странице.
Другие упражнения по этой теме: Классы-декораторы Python: задачи на call, методы и состояние.
Пакетный буфер событий
Модуль аудита собирает системные события и сохраняет их в удалённый журнал через функцию пакетной записи. Чтобы не открывать отдельную транзакцию на каждую мелкую запись, функцию оборачивают классом-декоратором с накопителем фиксированной вместимости.
При обычном вызове обёртка помещает очередное событие в буфер и возвращает его новую длину, не беспокоя саму функцию. Но как только накопитель заполняется до установленного предела, целевая функция немедленно вызывается со всем списком накопленных событий, буфер опустошается, а вызывающая сторона получает результат работы функции. Если же события больше не поступают, выгрузить остаток помогает метод flush(): при непустом буфере он отправляет накопленный список функции записи, очищает накопитель и возвращает полученный ответ, а при пустом буфере ничего не отправляет и возвращает None.
Если целевая функция завершается ошибкой, отправляемый пакет всё равно безвозвратно удаляется из буфера, а возникшее исключение беспрепятственно пробрасывается наружу. Напишите класс-декоратор, реализующий такую пакетную отправку и гарантированную очистку накопителя при сбое.
Что уже дано
В заготовке кода представлен класс BatchBuffer с заготовками методов __init__, __call__ и flush(), которые вам предстоит реализовать.
Что нужно сделать
Реализуйте класс BatchBuffer со следующей сигнатурой и поведением:
- Конструктор
__init__(self, function, capacity)принимает: function— синхронный вызываемый объект, принимающий один аргумент (список событий). Функция может вернуть произвольный объект или возбудить исключение (включая производные отBaseException);capacity— положительное целое число от 1 до 100, задающее предельную вместимость пакета.- Метод
__call__(self, event)принимает произвольный объект событияevent(включая изменяемые объекты, подклассы и повторные ссылки): - добавляет событие в конец внутреннего накопителя, сохраняя исходный порядок, дубликаты и идентичность переданных объектов;
- если после добавления число событий меньше
capacity, целевая функция не вызывается, а метод возвращает новую длину очереди в виде целого числаint; - если же накопитель достиг ровно
capacityсобытий, накопленный пакет немедленно передаётся в виде списка вfunction(batch). Метод возвращает результат выполнения целевой функции. - Метод
flush(self)выгружает накопленный остаток: - если в накопителе есть хотя бы одно событие, оно передаётся в виде списка в
function(batch)и возвращается результат выполнения функции; - если накопитель пуст, целевая функция не вызывается, а метод возвращает
None.
Правила диспетчеризации и очистки:
- При любой отправке пакета (как при заполнении до
capacity, так и приflush()) отправляемые события должны быть безвозвратно удалены из накопителя независимо от того, завершилась ли целевая функция успешно или выбросила ошибку. - Если целевая функция выбрасывает исключение, то же самое исключение должно беспрепятственно всплыть наружу; повторные попытки отправки делать не нужно.
- Состояние буфера должно быть изолировано для каждого созданного экземпляра: несколько независимых объектов
BatchBufferмогут работать параллельно и чередовать вызовы.
Ввод и вывод
Стандартные потоки ввода stdin и вывода stdout в решении не используются: считывать ввод и вызывать print() не нужно. После выполнения кода учащегося проверяющая система считывает из пространства имён модуля класс верхнего уровня BatchBuffer и вызывает его методы с проверочными аргументами.
Пример использования
def write(events):
return tuple(events)
buffer = BatchBuffer(write, 3)
print(buffer("a"))
print(buffer("b"))
print(buffer.flush())
print(buffer.flush())
Вывод:
1
2
('a', 'b')
None
Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.
Отправьте решение, чтобы увидеть результаты тестов.
Связанные задачи
- Класс-декоратор Python: когда вызывается init
- Класс-декоратор метода Python: почему теряется self
- Класс-декоратор Python: ограничение изменения результата между вызовами
- Класс-декоратор Python: баланс доступных вызовов функции
- Класс-декоратор Python: изменение аргумента первых N вызовов
- Класс-декоратор Python: переключение между основной и резервной репликой
