Skip to content

my-mail-ru/perl-MR-IProto-XS

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

62 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MR::IProto::XS

Перловая обвязка для libiprotocluster. Помимо прочего поддерживаются:

  • синхронный блокирующий режим работы при использовании внутреннего event loop (используется по умолчанию);
  • синхронный неблокирующий режим работы при использовании внешнего event loop;
  • асинхронный режим работы с возвратом результата через callback (разумно использовать только с внешним event loop);
  • упаковка/распаковка данных при помощи pack/unpack.

Объект класса MR::IProto::XS представляет собой кластер iproto-серверов. Конструктор поддерживаются следующие параметры:

  • shards - хэш шардов;
  • masters - мастера, если шард только один;
  • replicas - реплики, если шард только один;

В самом общем виде, создание объекта выглядит следующим образом:

my $iproto = MR::IProto::XS->new(
    shards => {
        1 => { masters => [['10.0.2.1:1002', '10.0.2.1:1012'], ['10.1.2.1:1002', '10.1.2.1:1012']], replicas => [['10.0.3.1:1003'], ['10.1.3.1:1013']] },
        2 => { masters => ['10.0.2.2:2002', '10.0.2.2:2012'], replicas => ['10.0.3.2:2003'] },
        3 => { masters => ['10.0.2.3:2002'], replicas => ['10.0.3.3:2003'] },
    },
);

В хеше shards ключами являются номера шардов от 1 до максимального, дырок быть не должно. В значениях - хэши с двумя ключами: masters и replicas, содержащими либо массивы строк host:port, либо массивы таких массивов. В первом случае, это будут равноправные серверы, обращение к которым будет выполняться в случайном порядке. Во втором случае, переход от одного массива к другому будет осуществляться только при недоступности всех серверов первого массива.

В случае только одного шарда запись можно упростить:

my $iproto = MR::IProto::XS->new(
    masters  => [['10.0.0.1:1000', '10.0.0.2:2000'], ['10.0.0.3:3000', '10.0.0.4:4000']],
    replicas => [['10.0.1.1:1001', '10.0.1.2:2001'], ['10.0.1.3:3001', '10.0.1.4:4001']],
);

Для того, чтобы не таскать по коду переменную, можно создать класс-синглетон при помощи метода create_singleton и выполнять все вызовы от имени класса:

package My::Super::Box;
use base 'MR::IProto::XS';
__PACKAGE__->create_singleton(masters => ["127.0.0.1:1234"]);

Впоследствии синглетон можно удалить методом remove_singleton (хотя вряд ли это необходимо).

Собственно выполнение запросов осуществляется при помощи метода bulk, либо его упрошенной формы do:

my $resp = $iproto->bulk([
    {
        code     => 17,
        request  => { method => 'pack', format => 'LL', data => [ 97, 10976 ] },
        response => { method => 'unpack', format => 'L' },
    },
    {
        code     => 25,
        request  => { method => 'pack', format => 'CL$', data => [ 1, 15, "something" ] },
        response => { method => 'unpack', format => 'L' },
    },
]);

Метод bulk вернет массив хешей, содержащих ключи error и, если нет ошибок, data. В error содержится dualvar, который в числовом контексте содержит код ошибки, а в строковом - описание (подобно тому как работает $!). В data содержится либо необработанный ответ, либо, если указан способ распаковки ответа, результат этой распаковки. В случае, если ответ был получен от реплики, то будет также присутствовать ключ replica со значением 1.

Метод do делает все ровно то же самое, но рассчитан на отправку одного запроса и принимает вместо массива хэш одного запроса и возвращает хэш одного ответа.

Для асинхронных запросов (содержащих ключ callback) вместо результата функции вернут undef, а собственно результат будет передан в callback-функцию.

Собственно хэш запроса может содержать следующие ключи:

  • code - числовой код типа сообщений;
  • request - параметры упаковки запроса:
    • method - метод упаковки, поддерживается "raw", "pack" и "sub";
    • если method = "pack":
      • format - строка формата для pack;
      • data - массив данных для pack;
    • если method = "sub":
      • sub - функция-энкодер, должна возвращать строку с упакованными данными;
      • data - значение, передаваемое в нее первым параметром;
  • response- параметры распаковки запроса:
    • errcode - длина кода ошибки (1, 2, 4, или 8), которая вырезается из начала ответа перед распаковкой;
    • errstr - если код ошибки ненулевой, то все оставшееся считается текстом ошибки;
    • method - метод распаковки, поддерживается "raw", "unpack" и "sub";
    • если method = "pack":
      • format - строка формата для unpack;
    • если method = "sub":
      • sub - функция-декодер, принимает на вход строку с упакованными данными;
  • shard_num - номер шарда;
  • max_tries - максимальное количество попыток (по умолчанию 3);
  • from- порядок обращения к серверам при попытках:
    • "master" - только мастер (по умолчанию);
    • "replica" - только реплика;
    • "master,replica" - мастер, если не получилось, то реплика;
    • "replica,master" - реплика, если не получилось, то мастер;
  • early_retry - выполнять ли ранние перепопытки;
  • safe_retry - выполнять перепопытки только если запрос не был отправлен на сервер (по умолчанию);
  • retry_same - выполнять перепопытки всегда к тому же серверу (во избежание дупликатов например);
  • timeout - таймаут на запрос (без учета времени на коннект) в секундах с плавающей точкой (по умолчанию 0.5);
  • inplace - модифицировать хэш запроса и дописать ответ прямо в него;
  • callback - функция, которая будет вызвана после выполнения запроса, результат будет передан в нее первым и единственным параметром;
  • soft_retry_callback - callback-функция, при помощи можно на раннем этапе определить неуспешные запросы и повторить их.

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

После инициализации библиотека по умолчанию использует внутренний event loop для того, чтобы не было странных интерференций разных вызовов в синхронном коде (а также, чтобы сохранить поведение предыдущих версий). Изменить используемый event loop можно при помощи метода set_ev_loop:

MR::IProto::XS->set_ev_loop(EV::default_loop);

Установка

Зависимости

  • Coro
  • EV
  • libiprotocluster

Сборка

perl Makefile.PL
make
make install

About

(A)synchronous iproto client for Perl

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •