Здравствуйте, Lazin, Вы писали:
EP>>Capacity циклического буфера можно изменять в соответствии с необходимыми условиями (например, это есть в boost::circular_buffer). L>Придется лочить весь буфер и копировать его содержимое. Не самый оптимальный вариант в случае, если у тебя вдруг резко возросла нагрузка на сервер и потребовалось больше памяти.
Да, но в сценарии small_ring_buffer ---high_load---> large_ring_buffer, эта копия незначительна, так как размер данных которые нужно скопировать мал.
L>Думаю можно придумать гибридный вариант: когда у тебя забивается циклический буфер маленького размера, ты не увеличиваешь его, а создаешь буфер большего размера (х2) и продолжаешь писать в него. Код, который вычерпывает данные из буфера сначала вычерпывает их из маленького буфера а затем удаляет его и принимается за большой.
При необходимости, можно поиграться и в такую "змейку".
Re[11]: Protoctor - communication protocol constructor
Здравствуйте, niXman, Вы писали:
X>размер буферов делаем константным, а кол-во буферов — нет.
кол-во буферов можно ограничить конфигурацией. можно продумать позднее сокращение буферов, например, если какое-то время еспользуется только часть буферов.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[12]: Protoctor - communication protocol constructor
Здравствуйте, niXman, Вы писали:
X>так а чем плох вариант с FIFO буферов? X>размер буферов делаем константным, а кол-во буферов — нет.
Если в одном буфере одно сообщение — то будет перерасход памяти, так как буферы будут заполнятся не полностью. Дырки между буферами также могут снижать производительность, так как снижают КПД использования cache/memory throughput.
Плюс, нужно как-то нарезать сообщения по буферам. То есть, например, если мы начали считывать в буфер не зная размера сообщения, то мы можем получить несколько сообщений в буфере, причём последнее может быть не целым — придётся копировать его в новый буфер.
Если же буфера заполнять плотно, то будут дополнительные условные проверки при пересечении границ, что также снизит производительность.
Re[13]: Protoctor - communication protocol constructor
Здравствуйте, niXman, Вы писали:
EP>>Плюс, нужно как-то нарезать сообщения по буферам. X>asio сам это делает: async_read_some()
Нарезать сообщения, а не байты.
Например, есть пустой буфер в 1024 байта, размер сообщения неизвестен, но в диапазоне от 32 до 1024 байт. Вызываем async_read_some, и видим что в буфер пришло одно сообщение в 1000 байт, и ещё часть следующего в 24 байта.
Re[15]: Protoctor - communication protocol constructor
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Нарезать сообщения, а не байты. EP>Например, есть пустой буфер в 1024 байта, размер сообщения неизвестен, но в диапазоне от 32 до 1024 байт. Вызываем async_read_some, и видим что в буфер пришло одно сообщение в 1000 байт, и ещё часть следующего в 24 байта.
понял.
ща посмотрю реализацию circular_buffer...
такой еще вопрос.
в этом примере, мы описываем тип используемый в сообщении:
YARMI_CONSTRUCT(
(yarmi), // client invoker namespace
client_invoker, // name of the client invoker
(proc(registration , on_registration, (string) )) // username
(proc(activation , on_activation , (string, string, string) )) // registration key : username : password
(proc(login , on_login , (string, string) )) // username : password
(proc(logout , on_logout , () )) // without args
(proc(users_online , on_users_online, () )) // without args
(proc(users_online , on_users_online, (string) )) // substring of username
(enum(user_enum , (elem1, elem2, elem3) )) // так можно декларить енум <<<<<<<<<<<<<<<<<<<<<
[1] (type(user_struct, (int, a)(long, b)(float, c) )) // а вот так юзер может описывать структуры. имея эту информацию, я могу сгенерить код сериализации/десериализации даже препроцессором.
[2] (proc(some_proc , on_some_proc , (user_struct)))
,
(yarmi), // server invoker namespace
server_invoker, // name of the server invoker
(proc(registration , on_registration, (string, std::string) )) // message : registration key
(proc(activation , on_activation , (string) )) // message
(proc(login , on_login , (string) )) // message
(proc(logout , on_logout , (string) )) // message
(proc(users_online , on_users_online, (array<string>) )) // vector of usernames
);
тут, в точке 1 мы описывает тип, а в точке 2 — используем его.
таким образом, в client_invoker появится такой метоы: void some_proc(const const user_struct &us);
в тоже время, server_invoker ожидает что будет ему предоставлен класс с таким методом: void on_some_proc(const const user_struct &us);
вопрос в том, что если я генерю user_struct в теле client_invoker, то описание этой структуры не будет доступно server_invoker`у. как быть?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[16]: Protoctor - communication protocol constructor
Здравствуйте, niXman, Вы писали:
X>вопрос в том, что если я генерю user_struct в теле client_invoker, то описание этой структуры не будет доступно server_invoker`у. как быть?
Если я правильно понял задачу, то вот несколько вариантов:
1. Должно быть место для описания типов доступных и для клиента и для сервера.
2. Внутри макроса YARMI_CONSTRUCT, первым действием сгенерировать код для всех типов, и для сервера и для клиента.
P.S. А зачем описывать два набора процедур/структур, для клиента/сервера? Нельзя ли просто описать сервисы, а уже клиент и сервер будут выбирать, кому что? Или это заточка под распространённый use-case?
Re[17]: Protoctor - communication protocol constructor
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>1. Должно быть место для описания типов доступных и для клиента и для сервера.
можно сгенерить уникальный неймспейс из 'нейсмспейса клиентского инвокера' + 'имени клиентского инвокера' + 'неймспейса серверного инвокера' + 'имени серверного инвокера'.
EP>2. Внутри макроса YARMI_CONSTRUCT, первым действием сгенерировать код для всех типов, и для сервера и для клиента.
в таком случае, да.
EP>P.S. А зачем описывать два набора процедур/структур, для клиента/сервера? Нельзя ли просто описать сервисы, а уже клиент и сервер будут выбирать, кому что? Или это заточка под распространённый use-case?
они же парные. если описывать отдельно, — велика вероятность ошибок.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[18]: Protoctor - communication protocol constructor
Здравствуйте, niXman, Вы писали:
X>можно сгенерить уникальный неймспейс из 'нейсмспейса клиентского инвокера' + 'имени клиентского инвокера' + 'неймспейса серверного инвокера' + 'имени серверного инвокера'.
по приведенному выше примеру, получится так: namespace yarmi__client_invoker__yarmi__server_invoker {}
ну и типы клиента и сервера генерить в этом неймспейсе.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[18]: Protoctor - communication protocol constructor
Здравствуйте, niXman, Вы писали:
EP>>P.S. А зачем описывать два набора процедур/структур, для клиента/сервера? Нельзя ли просто описать сервисы, а уже клиент и сервер будут выбирать, кому что? Или это заточка под распространённый use-case? X>>они же парные. если описывать отдельно, — велика вероятность ошибок.
Я предлагаю вместо варианта: описание клиентских типов и функций + описание серверных типов и функций
server
{
struct foo //...
ping(foo x);
}
client
{
struct bar // ...
pong(bar x);
}
рассмотреть вариант: описание типов (отдельно) + описание сервисов + конфигурация указывающая какие из сервисов себе берёт клиент, а какие сервер
types
{
struct foo //...
struct bar // ...
}
service FirstService
{
ping(foo x);
}
service SecondService
{
pong(bar x);
}
// ...
// где-то ниже
connection SomeConn
{
client provides SecondService;
server provides FirstService;
}
(псевдокод логической структуры)
Re[19]: Protoctor - communication protocol constructor
Возможно я не так понял что делает yarmi: устанавливается соединение между клиентом и сервером; у сервера есть некоторые методы, которые могут быть вызваны клиентом; и у клиента есть методы, вызов которых может быть инициирован с сервера; YARMI_CONSTRUCT описывает какие методы есть у клиента и у сервера (+ типы). Так?
Re[21]: Protoctor - communication protocol constructor
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Возможно я не так понял что делает yarmi: устанавливается соединение между клиентом и сервером; у сервера есть некоторые методы, которые могут быть вызваны клиентом; и у клиента есть методы, вызов которых может быть инициирован с сервера; YARMI_CONSTRUCT описывает какие методы есть у клиента и у сервера (+ типы). Так?
да. но описание типов пока в перспективе.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[22]: Protoctor - communication protocol constructor
Здравствуйте, niXman, Вы писали:
X>да. но описание типов пока в перспективе.
Вот, как один из вариантов, вместо описания каждого метода у клиента и сервера в YARMI_CONSTRUCT, задать какие сервисы поддерживаются клиентом и сервером, где сервис это набор методов описанный ранее.
Это позволит переиспользовать сервисы. Например, у клиента и сервера должны быть методы ping и foo, отдельно описываем сервис PingFoo (в котором эти два метода), а потом указываем что и клиент и сервер реализуют этот сервис.
Может такой вариант и нецелесообразен — зависит от задач.
Re[23]: Protoctor - communication protocol constructor
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Вот, как один из вариантов, вместо описания каждого метода у клиента и сервера в YARMI_CONSTRUCT, задать какие сервисы поддерживаются клиентом и сервером, где сервис это набор методов описанный ранее. EP>Это позволит переиспользовать сервисы. Например, у клиента и сервера должны быть методы ping и foo, отдельно описываем сервис PingFoo (в котором эти два метода), а потом указываем что и клиент и сервер реализуют этот сервис. EP>Может такой вариант и нецелесообразен — зависит от задач.
вроде понял о чем ты. но, признаюсь, не вижу практического смысла в таком подходе.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[24]: Protoctor - communication protocol constructor
Я думаю никто не станет пользоваться RPC с таким сложным IDL. Посмотри на то, как это реализовано в Thrift и Protobuf (можно еще на cap'n'proto, очень интересный проект) и начни писать спеку по своему RPC. В процессе написания все станет намного яснее.
X>к тому же, не могу решить некоторую проблему с препроцессором. полагаю, в виду того, что он однопроходный.
В виду того, что препроцессор убог. Ты зря не хочешь делать внешний IDL, для описания интерфейса между клиентом и сервером. Недостаток у этого подхода только один — он требует доп. шага компиляции при изменении в описаниях интерфейсов и типов данных. Зато можно сделать нормальный синтаксис. Если лень писать парсер, можно для начала описать все с помощью json или yaml.
Это описание может быть использовано для того, чтобы сгенерировать структуру Endpoint, описания базового виртуального класса для сервера — Callback и код клиента, причем для разных языков (если есть хорошая спека с описанием форматов). И я все таки за то, чтобы использовать фикс. набор примитивных типов на уровне IDL, а не типы из стд библиотеки С++. Вариант с препроцессором слишком ограничен.
Re[26]: Protoctor - communication protocol constructor