中止对 neo4jrb 的查询
Aborting queries on neo4jrb
我正在 运行 遵循以下思路:
results = queries.map do |query|
begin
Neo4j::Session.query(query)
rescue Faraday::TimeoutError
nil
end
end
经过几次迭代后,我得到了一个未获救的 Faraday::TimeoutError: too many connection resets (due to Net::ReadTimeout - Net::ReadTimeout)
,Neo4j 需要关闭并重新打开。
我相信这是因为查询本身没有中止 - 即连接超时但 Neo4j 继续尝试 运行 我的查询。我实际上想让它们超时,所以简单地增加超时 window 对我没有帮助。
我有一个 scout,看起来我可以找到我的查询并通过 Neo4j API 中止它们,这将是我的下一步。
我的诊断正确吗?如果是这样,是否有推荐的方法来管理来自 neo4jrb 的查询(并中止它们)?
查询管理可以通过 Cypher 完成。您必须是管理员用户。
要列出所有查询,您可以使用 CALL dbms.listQueries;
。
要终止查询,您可以使用 CALL dbms.killQuery('ID-OF-QUERY-TO-KILL');
,其中 ID 从查询列表中获取。
前面的语句必须作为原始查询执行;您是否使用 OGM 并不重要,只要您可以手动输入查询即可。如果无法手动输入查询,并且在您的框架中也无法执行此操作,那么您将不得不使用其他方法访问数据库以执行查询。
Rebecca 关于手动管理查询的说法是正确的。虽然如果你希望 Neo4j 在特定时间段内自动停止查询,你可以在你的 neo4j
conf:
中设置它
dbms.transaction.timeout=60s
您可以在 the docs 中找到有关该设置的更多信息。
Ruby gem 正在使用 Faraday 通过 HTTP 连接到 Neo4j,Faraday 有一个内置超时,与 Neo4j 中的超时不同。我建议将 Neo4j 超时设置为比 Ruby(here 是配置法拉第超时的文档)中的超时长一点(可能 5-10 秒)。如果它们都有相同的超时,Neo4j 可能会在 Ruby 之前引发超时,从而导致不太明显的错误。
非常感谢 Brian 和 Rebecca 提供了有关 Neo4j 中查询管理的有用提示。这两个都指出了解决我的问题的可行方法,Brian 明确列出了通过 Neo4jrb 实现一个的步骤,因此我将其标记为正确。
正如两个答案所假设的那样,我做出的诊断是正确的 - 即如果您 运行 来自 Neo4jrb 的查询并且 HTTP 连接超时,Neo4j 将继续执行查询并且 Neo4jrb 将不会发出任何指令让它停止。
Neo4jrb 不提供任何查询管理功能的包装器,因此简单地设置事务超时似乎是最明智的,并且可能是我将采用的方法。实际上拦截和杀死查询也是可能的,但这意味着 运行 在一个线程上执行查询,以便您可以在另一个线程中查找它的 queryId。这是我正在使用 atm 的有点老套的解决方案:
class QueryRunner
DEFAULT_TIMEOUT=70
def self.query(query, timeout_limit=DEFAULT_TIMEOUT)
new(query, timeout_limit).run
end
def initialize(query, timeout_limit)
@query = query
@timeout_limit = timeout_limit
end
def run
start_time = Time.now.to_i
Thread.new { @result = Neo4j::Session.query(@query) }
sleep 0.5
return @result if @result
id = if query_ref = Neo4j::Session.query("CALL dbms.listQueries;").to_a.find {|x| x.query == @query }
query_ref.queryId
end
while @result.nil?
if (Time.now.to_i - start_time) > @timeout_limit
puts "killing query #{id} due to timeout"
Neo4j::Session.query("CALL dbms.killQuery('#{id}');")
@result = []
else
sleep 1
end
end
@result
end
end
我正在 运行 遵循以下思路:
results = queries.map do |query|
begin
Neo4j::Session.query(query)
rescue Faraday::TimeoutError
nil
end
end
经过几次迭代后,我得到了一个未获救的 Faraday::TimeoutError: too many connection resets (due to Net::ReadTimeout - Net::ReadTimeout)
,Neo4j 需要关闭并重新打开。
我相信这是因为查询本身没有中止 - 即连接超时但 Neo4j 继续尝试 运行 我的查询。我实际上想让它们超时,所以简单地增加超时 window 对我没有帮助。
我有一个 scout,看起来我可以找到我的查询并通过 Neo4j API 中止它们,这将是我的下一步。
我的诊断正确吗?如果是这样,是否有推荐的方法来管理来自 neo4jrb 的查询(并中止它们)?
查询管理可以通过 Cypher 完成。您必须是管理员用户。
要列出所有查询,您可以使用 CALL dbms.listQueries;
。
要终止查询,您可以使用 CALL dbms.killQuery('ID-OF-QUERY-TO-KILL');
,其中 ID 从查询列表中获取。
前面的语句必须作为原始查询执行;您是否使用 OGM 并不重要,只要您可以手动输入查询即可。如果无法手动输入查询,并且在您的框架中也无法执行此操作,那么您将不得不使用其他方法访问数据库以执行查询。
Rebecca 关于手动管理查询的说法是正确的。虽然如果你希望 Neo4j 在特定时间段内自动停止查询,你可以在你的 neo4j
conf:
dbms.transaction.timeout=60s
您可以在 the docs 中找到有关该设置的更多信息。
Ruby gem 正在使用 Faraday 通过 HTTP 连接到 Neo4j,Faraday 有一个内置超时,与 Neo4j 中的超时不同。我建议将 Neo4j 超时设置为比 Ruby(here 是配置法拉第超时的文档)中的超时长一点(可能 5-10 秒)。如果它们都有相同的超时,Neo4j 可能会在 Ruby 之前引发超时,从而导致不太明显的错误。
非常感谢 Brian 和 Rebecca 提供了有关 Neo4j 中查询管理的有用提示。这两个都指出了解决我的问题的可行方法,Brian 明确列出了通过 Neo4jrb 实现一个的步骤,因此我将其标记为正确。
正如两个答案所假设的那样,我做出的诊断是正确的 - 即如果您 运行 来自 Neo4jrb 的查询并且 HTTP 连接超时,Neo4j 将继续执行查询并且 Neo4jrb 将不会发出任何指令让它停止。
Neo4jrb 不提供任何查询管理功能的包装器,因此简单地设置事务超时似乎是最明智的,并且可能是我将采用的方法。实际上拦截和杀死查询也是可能的,但这意味着 运行 在一个线程上执行查询,以便您可以在另一个线程中查找它的 queryId。这是我正在使用 atm 的有点老套的解决方案:
class QueryRunner
DEFAULT_TIMEOUT=70
def self.query(query, timeout_limit=DEFAULT_TIMEOUT)
new(query, timeout_limit).run
end
def initialize(query, timeout_limit)
@query = query
@timeout_limit = timeout_limit
end
def run
start_time = Time.now.to_i
Thread.new { @result = Neo4j::Session.query(@query) }
sleep 0.5
return @result if @result
id = if query_ref = Neo4j::Session.query("CALL dbms.listQueries;").to_a.find {|x| x.query == @query }
query_ref.queryId
end
while @result.nil?
if (Time.now.to_i - start_time) > @timeout_limit
puts "killing query #{id} due to timeout"
Neo4j::Session.query("CALL dbms.killQuery('#{id}');")
@result = []
else
sleep 1
end
end
@result
end
end