Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.
Жизненный цикл
FileBroker::new записывает путь, connect открывает файл, каждая подписка открывает читателя,
а завершение работы закрывает запись. StdioBroker подключает каналы процесса при первом
использовании.
Схема текстом
- Брокер: FileBroker::new (path); ConnectedFileBroker; Closed = () сообщать нечего
- Транспорт: файл: Записывает путь и настройки, без I/O; Открывает файл или создаёт его; в пустой пишет служебное; Каждая подписка: консьюмер или читатель для воспроизведения; Каждая публикация: дозапись и сброс; Ждёт публикаций, пишет метку конца, если задана, сбрасывает и синхронизирует с устройством
- FileBroker::new (path) → ConnectedFileBroker: connect(self)
- ConnectedFileBroker → Closed = () сообщать нечего: shutdown(self)
- Записывает путь и настройки, без I/O → Открывает файл или создаёт его; в пустой пишет служебное
- Открывает файл или создаёт его; в пустой пишет служебное → Каждая подписка: консьюмер или читатель для воспроизведения
- Каждая подписка: консьюмер или читатель для воспроизведения → Каждая публикация: дозапись и сброс
- Каждая публикация: дозапись и сброс → Ждёт публикаций, пишет метку конца, если задана, сбрасывает и синхронизирует с устройством
- Издатель, переживший соединение, отвечает NotConnected, а перемотка через старый дескриптор получает отказ
new не выполняет ввода-вывода, поэтому билдер сервиса остаётся синхронным. Рантайм подключает
брокер при старте приложения. Подключение создаёт файл, если его нет, или возвращает ошибку под
existing_only. Оно проверяет интервал маяков, открывает
стример клиента и один продюсер, а в файл, в котором пока ничего нет, записывает служебное
сообщение.
Каждая подписка открывает читателя на рантайме, на котором выполнился connect: консьюмер на конце
файла для живой подписки или читатель всего файла для воспроизведения. Публикация дописывает
сообщение и сбрасывает его в файл, как показывает страница Запись.
Завершение работы сначала помечает соединение закрытым, поэтому публикация, начатая после этого, возвращает ошибку. Затем оно ждёт публикаций, которые ещё выполняются, и забирает продюсер. Клиент закрывает запись файла: пишет метку конца потока, если она задана, сбрасывает буфер и синхронизирует файл с устройством. Только после этого крейт удаляет свой продюсер и ещё раз обращается к клиенту. Иначе поздно удалённый дескриптор закрыл бы запись следующего соединения с тем же файлом.
После завершения работы издатель, переживший соединение,
возвращает NotConnected, а перемотка через дескриптор перемотки, переживший соединение, получает
отказ. Ни тот, ни другая не сообщают об успехе на закрытом файле.
Брокер stdio
Схема текстом
- Брокер: StdioBroker::new(); ConnectedStdioBroker; Closed = () сообщать нечего
- Транспорт: каналы: Записывает loopback, каналы не трогает; Первая подписка: поток stdin; Первая публикация: поток stdout; Завершает все потоки stdio процесса
- StdioBroker::new() → ConnectedStdioBroker: connect(self)
- ConnectedStdioBroker → Closed = () сообщать нечего: shutdown(self)
- Записывает loopback, каналы не трогает → Первая подписка: поток stdin
- Первая подписка: поток stdin → Первая публикация: поток stdout
- Первая публикация: поток stdout → Завершает все потоки stdio процесса
- Издатель, переживший соединение, отвечает NotConnected
Подключение записывает, замкнут ли брокер на себя (loopback), и не трогает каналов. Первая
подписка в процессе запускает поток stdin клиента, а первая публикация - его поток stdout, как
показывает страница Канал. Оба потока обслуживают весь процесс. Поэтому
завершение работы закрывает в нём каждый консьюмер и продюсер stdio, включая принадлежащие другим
брокерам.