Мой помощник, хранящий эластичное соединение

Я экспериментирую с эластичным поиском в mojolicious.

Я достаточно новичок в обоих.

Я хотел создать помощника для хранения соединения ES, и я надеялся передать конфигурацию помощника, относящуюся к ES (например, информация об узле, файл trace_on и т. Д.).

Если я напишу следующий очень простой помощник, это сработает;

has elasticsearch => sub {
    return Search::Elasticsearch->new( nodes => '192.168.56.21:9200', trace_to => ['File','/tmp/elasticsearch.log'] );
};

а затем в запуске

$self->helper(es => sub { $self->app->elasticsearch() });

однако, если я пытаюсь расширить это, чтобы взять config - как следующее - это терпит неудачу. Я получаю сообщение об ошибке "не могу найти индекс для пакета", когда приложение вызывает $self->es->index

has elasticsearch => sub {
    my $config = shift;
    my $params->{nodes} = '192.168.56.21:' . $config->{port};
    $params->{trace_to} = $config->{trace_to} if $config->{trace_to};
    my $es = Search::Elasticsearch->new( $params );
    return $es;
};

и в запуске

$self->helper(es => sub { $self->app->elasticsearch($self->config->{es}) });

Я предполагаю, что я просто неправильно понимаю помощников или конфиг или оба - может кто-то просветить меня?

Просто к сведению, в отдельном файле контроллера я использую помощник следующим образом;

$self->es->index(
    index   => $self->_create_index_name($index),
    type    => 'crawl_data',
    id      => $esid,
    body    => {
        content => encode_json $data,
    }
);

это прекрасно работает, если я создаю помощника с помощью простой (1-й) формы выше. Я надеюсь, что это достаточно информации? пожалуйста, дайте мне знать, если что-то еще требуется?

1 ответ

Решение

Прежде всего, has а также helper не то же самое. has это ленивый атрибут экземпляра Единственный аргумент конструктора атрибута - это экземпляр. Для приложения это будет выглядеть так:

package MyApp;

has elasticsearch => sub {
  my $app = shift;
  Search::ElasticSearch->new($app->config->{es});
};

sub startup {
  my $app = shift;
  ...
}

Этот экземпляр затем сохраняется в течение всего срока службы приложения после первого использования. Я не уверен, что в S::ES есть какая-либо логика повторного подключения по капле, поэтому вам, возможно, придется подумать о том, что постоянный объект - это то, что вам нужно.

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

has (elasticsearch => sub {
  my ($c, $config) = @_;
  $config ||= $c->app->config->{es};
  Search::ElasticSearch->new($config);
});

Этот механизм будет создавать экземпляр по требованию и может принимать передаваемые аргументы, возможно, для необязательного переопределения конфигурации, как я показал в этом примере.

Я надеюсь, что это отвечает на ваши вопросы.

Другие вопросы по тегам