so_4: Версия 4.4.0. Принцип работы коммуникационных каналов

Коммуникационные каналы SObjectizer используют описываемую ниже схему работы. RAW- и SOP-каналы облуживаются по похожим алгоритмам, различия заключаются только в моментах разблокирования канала для чтения очередной порции входящих данных и в использованнии компрессии SOP-трафика.

Обработка входящих данных

Когда SObjectizer обнаруживает, что в канале есть данные, он вычитывает из канала пакет. Максимальный размер этого пакета задается значением input_portion_size и по умолчанию равен 32K. На практике, из канала может быть прочитано и меньше данных -- это определяется уже коммуникационным уровнем ОС. Для входящих данных есть т.н. порог входящих данных (input_threshold). По умолчанию порог равен 1000 пакетов (package_count) или 100Kb трафика (traffic_bulk) -- в зависимости от того, что раньше произойдет. При каждом успешном чтении данных из канала SObjectizer проверяет, не превышен ли порог входящих данных. Если превышен, то канал объявляется блокированными и чтение из него прекращается до тех пор, пока канал не разблокируется.

Для SOP-каналов разблокировка выполняется SObjectizer-ом автоматически по мере разбора прочитанных из канала данных, что определяется общей загрукой приложения.

Для RAW-каналов разблокировка канала должна выполняться прикладным программистом посредством сообщения so_4::rt::comm::msg_unblock_channel.

Время, которое канал может провести в заблокированном состоянии ограничено (праметр max_input_block_timeout, по умолчанию 30 секунд). Если канал находится в заблокированном состоянии слишком долго, то он принудительно закрывается.

Обработка исходящих данных

Для исходящих данных: для каждого канала SObjectizer поддерживает два буфера -- awaiting_buffer и outgoing_buffer. Первый используется для накопления данных, второй -- для записи данных в канал.

В SOP-каналах при появлении очередного исходящего сообщения его двоичный образ помещается сначала в awaiting_buffer, затем, непосредственно перед отправкой -- в outgoing_buffer.

В RAW-каналах данные сразу же записываются в output_buffer.

Запись в канал ведется блоками. Максимальный размер блока определяется параметром output_portion_size. По умолчанию он равен 32K, но может быть и меньше, если в output_buffer/awaiting_buffer готовых к отправке данных меньше.

Изначально размеры awaiting_buffer и output_buffer равны output_portion_size, но могут увеличиваться до величины, заданной параметром max_awaiting_buffer_size/max_output_buffer_size (по умолчанию -- 512Kb). Если исходящие данные формируются в SObjectizer быстрее, чем успевают отсылаться в канал, то один их этих буферов переполняется и канал принудительно закрывается.

SObjectizer выполняет попытки записи в двух случаях: 1) при появлении исходящего сообщения, когда output_buffer пуст. Т.е. SObjectizer ждал исходящих данных, они появились и SObjectizer сразу же записал их в канал; 2) когда ОС говорит, что канал готов к записи.

Во втором случае ситуация следующая: появились исходящие данные, SObjectizer поместил их в outgoing_buffer, записал порцию в канал. И здесь может оказаться, что либо в outgoing_buffer было больше данных, чем output_portion_size, либо же в канал записалось меньше данных (тут уже TCP/IP протокол управляет). Т.е. после записи в канал в output_buffer остались еще исходящие данные. SO-4.4.0-b5 не пытается их сразу же дописывать, т.к. это может привести к перегрузке TCP/IP канала и, возможно, блокировки на некоторое время SObjectizer. Вместо этого SObjectizer средствами ОС начинает контролировать готовность канала к операции записи. Если канал готов -- SObjectizer пишет очередную порцию данных. Если не готов (а это может произойти, если удаленная сторона не успевает вычитывать данные из канала), то SObjectizer ждет готовности.

Максимальное время ожидания задается параметром max_output_block_timeout (по умолчанию 30 секунд). Если канал за это время в состояние готовности не перешел, то он принудительно закрывается.

SObjectizer проверяет время блокированности чтения из канала и время не готовности канала к записи периодически. Период проверки задается параметром time_checking_period (по умолчанию 1 секунда).

Почему используются 2 буфера исходящих данных в SOP-каналах?

В outgoing_buffer сохраняются полностью готовые к отправке данные. В awaiting_awaiting -- еще не готовые.

Если zip-ование трафика не выполняется, то исходящие данные сразу формируются в outgoing_buffer. Но, если используется zip-ование, то сначала данные накапливаются в awaiting_buffer и только затем, по мере освобождения outgoing_buffer, архивируются из awaiting_buffer в outgoing_buffer. Такая схема позволяет при большом количестве исходящих сообщений сначала скопить их в awaiting_buffer, затем заархивировать в outgoing_buffer и отослать одним небольшим пакетом.

Управление параметрами канала

Все вышеописанные параметры называются параметрами канала и задаются структурой so_4::transport_layer::channel_params_t.

Параметры канала задаются при создании транспортного агента одинаковым способом как для RAW-, так и для SOP-каналов:

// Для SOP канала.
so_4::rt::comm::a_sop_outgoing_channel_t a_channel(
  "a_channel",
  so_4::transport_layer::socket::create_connector_controller(
    so_4::transport_layer::socket::connector_params(
    argv[ 1 ] ),
  so_4::transport_layer::channel_params_t().
    // Размер одной порции исходящих данных увеличивается до 100Kb.
    set_output_portion_size( 100 * 1024 ).
    // Размер буфера исходящих данных увеличиывется до 600Kb.
    set_max_output_buffer_size( 600 * 1024 ) ),
  so_4::sop::filter_auto_ptr_t( filter ),
  so_4::rt::comm::create_def_disconnect_handler( 5000, 0 ) );

// Для RAW-канала.
so_4::rt::comm::a_raw_outgoing_channel_t * a_tcp_clnsock =
  new so_4::rt::comm::a_raw_outgoing_channel_t(
    a_main_t::tcp_agent_name(),
    so_4::transport_layer::socket::create_connector_controller(
    so_4::transport_layer::socket::connector_params(
      ip_address ),
      so_4::transport_layer::channel_params_t().
        // Чтение следуюшего буфера должно осуществляться только,
        // после обработки предыдущего пакета.
        set_input_threshold(
          so_4::transport_layer::threshold_t( 1, 1 ) ) ),
    so_4::rt::comm::disconnect_handler_auto_ptr_t() );

Управление параметрами процедуры handshake для SOP-каналов

Когда SOP-клиент подключается к SOP-серверу, он выполняет специальную процедуру handshake, во время которой стороны определяют параметры передачи данных. В настоящее время таким параметром является только компрессия (т.е. zip-ование трафика). Если и клиенту, и серверу разрешено использовать компрессию, то они начинаю zip-овать трафик. Если же хотя бы одному из них компрессия запрещена, то zip-ование не выполняется.

По умолчанию в SO-4.4.0-b4 и SO-4.4.0-b5 компрессия запрещена (более того, в SO-4.4.0-b4 она вообще не поддерживается). В SO-4.4.0-b5 компрессию можно включить управляя параметрами процедуры handshake.

Управление параметрами процедуры handshake называется, соответственно, параметрами процедуры handshake и задаются структурой so_4::rt::comm::handshaking_params_t.

Установить параметры процедуры handshake можно при помощи методов so_4::rt::comm::handshaking_params_holder_t::set_handshaking_params() (все транспортные агенты для SOP-каналов унаследованны от класса handshaking_params_holder_t):

so_4::rt::comm::a_sop_outgoing_channel_t a_channel(
  ... );
a_channel.set_handshaking_params(
    so_4::rt::comm::handshaking_params_t().enable_compression() );

Документация по SObjectizer v.4.4 'Тебуломста'. Последние изменения: Thu Sep 18 10:26:48 2008. Создано системой  doxygen1.5.6 Intervale SourceForge.net Logo