Иногда при разработке той или иной системы возникает такая ситуация, как синхронизация вполне себе асинхронного получения данных и вывода таких данных на экран (в приложение, если быть более скурпулёзным). Такая проблема часто встречается при разработке сетевых приложений с графическим интерфейсом и «заширменной частью».
Такие приложения очень часто разводятся по следующим частям:- сервис, который отвечает за мониторинг информации в сети
- монитор сервиса, который будет по мере прихода данных в специальный буффер получать их оттуда и отдавать пользовательскому интерфейсу
- пользовательский интерфейс, который будет принимать необходимые данные и выводить их пользователю
В самом простом случае каждой части соответствует отдельный поток выполнения и они выполняются параллельно. Сегодня мы постараемся рассмотреть самый простой способ синхронизации входящих и исходящих данных — использование промежуточного буффера для приёма и отдачи набора величин.
Все примеры сегодня будут написаны на Ruby, чтобы не быть очень уж односторонним в плане выбора языков программирования для своих статей, да и пример будет достаточно классическим и даже учебным.
Для начала создадим базовый класс для всех наших операций:
Теперь сделаем конструктор нашего класса:
Для начала мы сымитируем непостоянный и разбросанный приход данных от сервера (работаем в метода server):
Теперь можно приступать к созданию клиента для нашего несложного сервера. Он, клиент, будет через определённый интервал времени выводить содержимое буффера. Также, он обязан очищать буффер, так как данные в буффере больше не нужны.
После тестирования подобного приложения появляются некоторые вопросы: какими установить интервалы ожидания клиента и/или сервера, как генерировать сообщения и как их принимать.
В данной реализации мы столкнулись с временным буффером, так как без него обойтись было бы достаточно трудно: два разных потока в абсолютно разное время добавляют/считывают информацию из одной и той же переменной. Если бы в буффере были какие-либо ограничения на размер входящих данных, то могли бы возникнуть так называемые «deadlocks», то есть ситуации, когда и клиент не может работать с данными, так и сервер не может обработать потом исходящих величин.
Но вернёмся к вопросу о таймингах. Чем меньше тайминг проверки входящих данных на стороне клиента, тем чаще мы будем получать их отсутствие. С другой стороны, если тайминг будет достаточно большим, то входящих данных будет очень уж много для их одновременной обработки. Поэтому нужно стараться максимально нормализовать данную величину, так как от неё зависит и производительность программы и удобство пользователя (нужно сохранить равновесие, стоя на канате).