Re[10]: Protoctor - communication protocol constructor
От: Evgeny.Panasyuk Россия  
Дата: 14.05.14 15:45
Оценка:
Здравствуйте, Lazin, Вы писали:

EP>>Capacity циклического буфера можно изменять в соответствии с необходимыми условиями (например, это есть в boost::circular_buffer).

L>Придется лочить весь буфер и копировать его содержимое. Не самый оптимальный вариант в случае, если у тебя вдруг резко возросла нагрузка на сервер и потребовалось больше памяти.

Да, но в сценарии small_ring_buffer ---high_load---> large_ring_buffer, эта копия незначительна, так как размер данных которые нужно скопировать мал.

L>Думаю можно придумать гибридный вариант: когда у тебя забивается циклический буфер маленького размера, ты не увеличиваешь его, а создаешь буфер большего размера (х2) и продолжаешь писать в него. Код, который вычерпывает данные из буфера сначала вычерпывает их из маленького буфера а затем удаляет его и принимается за большой.


При необходимости, можно поиграться и в такую "змейку".
Re[11]: Protoctor - communication protocol constructor
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.05.14 16:02
Оценка:
так а чем плох вариант с FIFO буферов?
размер буферов делаем константным, а кол-во буферов — нет.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[12]: Protoctor - communication protocol constructor
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.05.14 16:05
Оценка:
Здравствуйте, niXman, Вы писали:

X>размер буферов делаем константным, а кол-во буферов — нет.

кол-во буферов можно ограничить конфигурацией. можно продумать позднее сокращение буферов, например, если какое-то время еспользуется только часть буферов.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[12]: Protoctor - communication protocol constructor
От: Evgeny.Panasyuk Россия  
Дата: 14.05.14 16:20
Оценка:
Здравствуйте, niXman, Вы писали:

X>так а чем плох вариант с FIFO буферов?

X>размер буферов делаем константным, а кол-во буферов — нет.

Если в одном буфере одно сообщение — то будет перерасход памяти, так как буферы будут заполнятся не полностью. Дырки между буферами также могут снижать производительность, так как снижают КПД использования cache/memory throughput.
Плюс, нужно как-то нарезать сообщения по буферам. То есть, например, если мы начали считывать в буфер не зная размера сообщения, то мы можем получить несколько сообщений в буфере, причём последнее может быть не целым — придётся копировать его в новый буфер.

Если же буфера заполнять плотно, то будут дополнительные условные проверки при пересечении границ, что также снизит производительность.
Re[13]: Protoctor - communication protocol constructor
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.05.14 16:32
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Плюс, нужно как-то нарезать сообщения по буферам.

asio сам это делает: async_read_some()
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[14]: Protoctor - communication protocol constructor
От: Evgeny.Panasyuk Россия  
Дата: 14.05.14 16:37
Оценка:
Здравствуйте, niXman, Вы писали:

EP>>Плюс, нужно как-то нарезать сообщения по буферам.

X>asio сам это делает: async_read_some()

Нарезать сообщения, а не байты.
Например, есть пустой буфер в 1024 байта, размер сообщения неизвестен, но в диапазоне от 32 до 1024 байт. Вызываем async_read_some, и видим что в буфер пришло одно сообщение в 1000 байт, и ещё часть следующего в 24 байта.
Re[15]: Protoctor - communication protocol constructor
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.05.14 17:34
Оценка:
Здравствуйте, 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
От: Evgeny.Panasyuk Россия  
Дата: 14.05.14 21:57
Оценка:
Здравствуйте, niXman, Вы писали:

X>вопрос в том, что если я генерю user_struct в теле client_invoker, то описание этой структуры не будет доступно server_invoker`у. как быть?


Если я правильно понял задачу, то вот несколько вариантов:
1. Должно быть место для описания типов доступных и для клиента и для сервера.
2. Внутри макроса YARMI_CONSTRUCT, первым действием сгенерировать код для всех типов, и для сервера и для клиента.

P.S. А зачем описывать два набора процедур/структур, для клиента/сервера? Нельзя ли просто описать сервисы, а уже клиент и сервер будут выбирать, кому что? Или это заточка под распространённый use-case?
Re[17]: Protoctor - communication protocol constructor
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.05.14 22:31
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>1. Должно быть место для описания типов доступных и для клиента и для сервера.

можно сгенерить уникальный неймспейс из 'нейсмспейса клиентского инвокера' + 'имени клиентского инвокера' + 'неймспейса серверного инвокера' + 'имени серверного инвокера'.

EP>2. Внутри макроса YARMI_CONSTRUCT, первым действием сгенерировать код для всех типов, и для сервера и для клиента.

в таком случае, да.

EP>P.S. А зачем описывать два набора процедур/структур, для клиента/сервера? Нельзя ли просто описать сервисы, а уже клиент и сервер будут выбирать, кому что? Или это заточка под распространённый use-case?

они же парные. если описывать отдельно, — велика вероятность ошибок.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[18]: Protoctor - communication protocol constructor
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.05.14 22:40
Оценка:
Здравствуйте, niXman, Вы писали:

X>можно сгенерить уникальный неймспейс из 'нейсмспейса клиентского инвокера' + 'имени клиентского инвокера' + 'неймспейса серверного инвокера' + 'имени серверного инвокера'.

по приведенному выше примеру, получится так: namespace yarmi__client_invoker__yarmi__server_invoker {}
ну и типы клиента и сервера генерить в этом неймспейсе.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[18]: Protoctor - communication protocol constructor
От: Evgeny.Panasyuk Россия  
Дата: 14.05.14 22:58
Оценка:
Здравствуйте, 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
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.05.14 23:27
Оценка:
не понял %)
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[20]: Protoctor - communication protocol constructor
От: Evgeny.Panasyuk Россия  
Дата: 14.05.14 23:37
Оценка:
Здравствуйте, niXman, Вы писали:

X>не понял %)


Возможно я не так понял что делает yarmi: устанавливается соединение между клиентом и сервером; у сервера есть некоторые методы, которые могут быть вызваны клиентом; и у клиента есть методы, вызов которых может быть инициирован с сервера; YARMI_CONSTRUCT описывает какие методы есть у клиента и у сервера (+ типы). Так?
Re[21]: Protoctor - communication protocol constructor
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.05.14 23:42
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Возможно я не так понял что делает yarmi: устанавливается соединение между клиентом и сервером; у сервера есть некоторые методы, которые могут быть вызваны клиентом; и у клиента есть методы, вызов которых может быть инициирован с сервера; YARMI_CONSTRUCT описывает какие методы есть у клиента и у сервера (+ типы). Так?

да. но описание типов пока в перспективе.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[22]: Protoctor - communication protocol constructor
От: Evgeny.Panasyuk Россия  
Дата: 14.05.14 23:57
Оценка:
Здравствуйте, niXman, Вы писали:

X>да. но описание типов пока в перспективе.


Вот, как один из вариантов, вместо описания каждого метода у клиента и сервера в YARMI_CONSTRUCT, задать какие сервисы поддерживаются клиентом и сервером, где сервис это набор методов описанный ранее.
Это позволит переиспользовать сервисы. Например, у клиента и сервера должны быть методы ping и foo, отдельно описываем сервис PingFoo (в котором эти два метода), а потом указываем что и клиент и сервер реализуют этот сервис.
Может такой вариант и нецелесообразен — зависит от задач.
Re[23]: Protoctor - communication protocol constructor
От: niXman Ниоткуда https://github.com/niXman
Дата: 15.05.14 09:45
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Вот, как один из вариантов, вместо описания каждого метода у клиента и сервера в YARMI_CONSTRUCT, задать какие сервисы поддерживаются клиентом и сервером, где сервис это набор методов описанный ранее.

EP>Это позволит переиспользовать сервисы. Например, у клиента и сервера должны быть методы ping и foo, отдельно описываем сервис PingFoo (в котором эти два метода), а потом указываем что и клиент и сервер реализуют этот сервис.
EP>Может такой вариант и нецелесообразен — зависит от задач.
вроде понял о чем ты. но, признаюсь, не вижу практического смысла в таком подходе.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[24]: Protoctor - communication protocol constructor
От: niXman Ниоткуда https://github.com/niXman
Дата: 16.05.14 16:57
Оценка:
с такими усложнениями препроцессорный вариант получается убогим %)
YARMI_CONSTRUCT(
    client_invoker,                                                   // name of the client invoker class
    (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(myenum1, (e0,=1)(e1)(e2)                                  ))
    (type(mytype1, (i8, a)(u8, b)(i32, c)(double, d)(string, e)     ))
    ,
    server_invoker,                                                   // name of the server invoker class
    (enum(myenum2, (e0)(e1,=2)(e2,=3)                              ))
    (type(mytype2, (i8, a)(u8, b)(i32, c)(double, d)(string, e)(array(i8), f)(map(i8, string), g)    )) <<<<<<<<<<<<<<<<<<<<<<<<<<<
    (proc(registration , on_registration, (string, 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
);

к тому же, не могу решить некоторую проблему с препроцессором. полагаю, в виду того, что он однопроходный.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[25]: Protoctor - communication protocol constructor
От: Lazin Россия http://evgeny-lazin.blogspot.com
Дата: 25.05.14 12:30
Оценка: +1
Здравствуйте, niXman, Вы писали:

X>с такими усложнениями препроцессорный вариант получается убогим %)

X>
X>    (type(mytype2, (i8, a)(u8, b)(i32, c)(double, d)(string, e)(array(i8), f)(map(i8, string), g)    )) <<<<<<<<<<<<<<<<<<<<<<<<<<<
X>


Я думаю никто не станет пользоваться RPC с таким сложным IDL. Посмотри на то, как это реализовано в Thrift и Protobuf (можно еще на cap'n'proto, очень интересный проект) и начни писать спеку по своему RPC. В процессе написания все станет намного яснее.

X>к тому же, не могу решить некоторую проблему с препроцессором. полагаю, в виду того, что он однопроходный.


В виду того, что препроцессор убог. Ты зря не хочешь делать внешний IDL, для описания интерфейса между клиентом и сервером. Недостаток у этого подхода только один — он требует доп. шага компиляции при изменении в описаниях интерфейсов и типов данных. Зато можно сделать нормальный синтаксис. Если лень писать парсер, можно для начала описать все с помощью json или yaml.

{
    "Endpoint": {
        "type": "struct",
        "fields": [
            { "name": "IP", "type": "string" },
            { "name": "Port", "type": "uint" }
        ]
    },
    "Callback": {
        "type": "interface",
        "doc": "manages connection from server to client",
        "methods": [
            { "name": "addConnection", "args": [ { "name": "my_endpoint", "type": "Endpoint" } ], "async": true }
        ]
    }
}


Это описание может быть использовано для того, чтобы сгенерировать структуру Endpoint, описания базового виртуального класса для сервера — Callback и код клиента, причем для разных языков (если есть хорошая спека с описанием форматов). И я все таки за то, чтобы использовать фикс. набор примитивных типов на уровне IDL, а не типы из стд библиотеки С++. Вариант с препроцессором слишком ограничен.
Re[26]: Protoctor - communication protocol constructor
От: niXman Ниоткуда https://github.com/niXman
Дата: 27.05.14 11:07
Оценка:
Здравствуйте, Lazin, Вы писали:

L>Ты зря не хочешь делать внешний IDL

уже хочу. уже пишу.
вот такой синтаксис будет:
// only CPP style comments allowed
proto(api) { // maybe one of 'api' or 'service'
    namespace yarmi;      // client invoker namespace
    class client_invoker; // name of the client invoker

    enum myenum1{}; e1,e2,e3=2}; // enum declaration
    struct mystruct1 { // struct declaration
        u32 a; // member of mystruct1
        string b;
        array<i64> c;
        set<string> d;
        map<u32, string> e; // some member of mystruct1
    };

    using ms = mystruct1; // using/typedef
    const u32 myu32 = 0;
    const myenum1 mye1 = myenum1::e1;

    [registration -> on_registration: (string)                 ] // username
    [activation   -> on_activation  : (string, string, string) ] // registration key : username : password
    [login        -> on_login       : (string, string)         ] // username : password
    [logout       -> on_logout      : ()                       ] // without args
    [users_online -> on_users_online: ()                       ] // without args
    [users_online -> on_users_online: (string)                 ] // substring of username
    ,
    namespace yarmi;      // server invoker namespace
    class server_invoker; // name of the server invoker

    [registration -> on_registration: (string, string)         ] // message : registration key
    [activation   -> on_activation  : (string)                 ] // message
    [login        -> on_login       : (string)                 ] // message
    [logout       -> on_logout      : (string)                 ] // message
    [users_online -> on_users_online: (array<string>)          ] // array of usernames
};


L>И я все таки за то, чтобы использовать фикс. набор примитивных типов на уровне IDL, а не типы из стд библиотеки С++.

ну да, так и планируется.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.