so_4: Версия 4.4.0. Новые типы параметров в send_msg

Внимание:
Данная модификация вносит некоторые несовместимости с ранее написанным кодом. Подробнее см. Несовместимость send_msg.
В предшествующих версиях SObjectizer существовало несколько вариантов функции so_4::api::send_msg() -- часть из них получали строковые аргументы в виде const char *, другая часть -- в виде const std::string. В любом из вариантов в конце-концов задействовалась функция so_4::api::send_msg(), которая использовала std::string.

Большинство обращений к so_4::api::send_msg() в SObjectizer-приложениях выполнялось с использованием одного или нескольких строковых литералов. Наверное, одним из самых распространенных сценариев использования so_4::api::send_msg() был следующий:

so_4::api::send_msg_safely(
    so_query_name(),
    "msg_some_action",
    new msg_some_action( ... ) );
Узким местом здесь являлось конструирование объекта std::string для строкового литерала. В случае, если реализация std::string не предоставляла оптимизации с внутренним буфером для маленьких строк, либо если имена сообщений/агентов оказывались слишком большими, каждое такое конструирование приводило к динамическому выделению памяти. Но даже если std::string оптимизировало работу с маленькими строками, то все равно выполнялось копирование строкового литерала во временный объект std::string. Все это выливалось в серьезные накладные расходы при большом количестве обращений к so_4::api::send_msg().

В версии 4.4.0-beta6 аргументы типа std::string и const char * были заменены аргументами специального типа string_piece_t. Особенностью класса string_piece_t является то, что является всего лишь маленькой структурой, которая хранит указатель на начало строки и длину строки. Поэтому ни в случае std::string, ни в случае строкового литерала не происходит выделения динамической памяти или копирования строкового значения. Максимальные затраты в случае строкового литерала -- это обращение к std::strlen() для определения длины строки.

За счет этого в версии 4.4.0-beta6 удалость существенно поднять скорость выполнения операции so_4::api::send_msg().

Несовместимость send_msg

Переход к string_piece_t вместо std::string и const char * порождает несовместимость между ранее написанным кодом и версией 4.4.0-beta6 только в одном случае -- когда send_msg() передается 0 в качестве указателя на имя агента-получателя. Например, в случае:
so_4::api::send_msg(
    so_query_name(),
    "msg_some_delayed_signal",
    0, // Нет данных для сообщения.
    0, // Нет получателя сообщения.
    1000 // Есть задержка.
);
Для такого кода компилятор будет выдавать предупреждение о том, что нет конструктора string_piece_t, принимающего значение int. Это происходит из-за того, что компилятор не может сделать неявного преобразования значения 0 (имеющего тип int) к string_piece_t.

Поэтому, начиная с версии 4.4.0-beta6 для указания широковещательной отсылки (т.е. отсутствия имени получателя сообщения) нужно использовать функцию so_4::api::receiver_unknown(). А приведенный выше фрагмент будет выглядеть как:

so_4::api::send_msg(
    so_query_name(),
    "msg_some_delayed_signal",
    0, // Нет данных для сообщения.
    so_4::api::receiver_unknown(), // Нет получателя сообщения.
    1000 // Есть задержка.
);

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