【问题标题】:ElasticSearch async delete? 200 just after deleting index in Rails appElasticSearch异步删除?在 Rails 应用程序中删除索引后为 200
【发布时间】:2018-05-04 06:47:26
【问题描述】:

我们在 Rails 应用程序上使用 ElasticSearch 和 Tire gem。对于我们的集成测试,我们在每个示例之前删除并重新创建索引,类似于

Foo.index.delete
Foo.create_elasticsearch_index

其中Foo 包括Tire::Model::Persistence。但是当我们在 CI 上运行我们的测试套件时,我们开始时不时地出现缺少索引的错误。我继续启用调试,然后在日志中发现以下内容:

# 2013-10-04 09:25:05:839 [DELETE] ("test_index")
#
curl -X DELETE http://some-server:9200/test_index

# 2013-10-04 09:25:05:840 [200]
#
# {
#   "ok": true,
#   "acknowledged": true
# }

# 2013-10-04 09:25:05:852 [HEAD] ("test_index")
#
curl -I "http://some-server:9200/test_index"

# 2013-10-04 09:25:05:852 [200]

如您所见,我得到了 DELETE 请求的 200 ok 响应,但是当 Tire 在创建索引之前执行 HEAD 请求以查看索引是否存在时,它仍然返回 200 而不是 404。这随机发生,大多数情况下它可以正常工作,但在测试套件中的某些时候它会失败。

我尝试在删除和创建操作之间等待黄色状态,但没有成功。所以我的问题是,删除索引操作是否以某种方式异步? (在 ES 文档上找不到任何关于此的内容)。有什么方法可以等待索引被删除? (因为黄色状态不起作用)。

编辑:感谢@PinnyM 的澄清。所以所有的操作都通过HTTP API are indeed asynchronous。那么剩下的问题是,我怎样才能等待索引被删除才能重新创建呢?

【问题讨论】:

标签: ruby-on-rails ruby elasticsearch tire


【解决方案1】:

在每个示例之前,您删除并重新创建索引。作为该过程的一部分,您可以通过轮询 exists 函数以返回 false 来确保删除过程已(异步)完成...在蹩脚的伪代码中...

max_wait = 5
while wait < max_wait and Tire.index("test_index").exists:
    wait some more
    if wait > max_wait:
        throw WaitedTooLongException()

exist 的轮胎文档在这里 - 基本上他们正在执行您在调试代码中找到的相同索引轮询: http://rubydoc.info/github/karmi/tire/master/Tire/Index#exists?-instance_method 来电:http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-exists.html

就个人而言,我会调整您使用 ES 实例的测试...如果您将 not-exists 循环放在测试开始时并在测试结束时删除索引,那么您可以获得两个好处。你可以:

  • 在测试开始时断言该索引不存在 - 干净整洁。
  • 在测试结束时请求删除索引并运行下一个可能不需要 ES 的测试 - 可能会稍微加快速度,具体取决于测试排序的应用和 CI 实现。

【讨论】:

  • 好主意!我听从了你的建议,在Tire::Index 中添加了一个小的ensure_deleted 方法,如果索引仍然存在,它将尝试5 次并抛出异常。这已经足够了,因为在我看到的所有情况下,索引已经被第二个请求删除了。另外,我按照您建议的方式对其进行了更改(在before(:each) 创建之前检查索引是否缺失并在after(:each) 上删除它)。谢谢!
  • 感谢@julio.olvr 的反馈 - 很高兴我的伪代码有帮助(我不是 Ruby 开发人员)。
【解决方案2】:

等待异步操作完成我在我的 RSpecs 中使用

collection.__elasticsearch__.refresh_index!

当我刚刚索引一个新文档并且我想在我的规范之后立即对其进行搜索时非常有用。

.refresh_index! 是一种阻塞方法。其实我相信所有! 方法都可能是……你试过其他! 方法了吗?

collection.__elasticsearch__.delete_index!
collection.__elasticsearch__.create_index!

(使用 ES 5.x 和适当的 elasticsearch-ruby/rails gems,不带轮胎)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多