在我的Rails应用程序的一些部署之后,我出现了一个间歇性错误。
这段代码在Sidekiq中运行(每个进程有10个线程),它运行在一个Docker容器中。我可以让成千上万的这些工作在任何时候排队。
path = Path.find(path_id)
nearby_nodes = Node.where("ST_DWITHIN(geog, ST_GeographyFromText(?), 25)", path.geog.to_s)错误是:
ActiveRecord::StatementInvalid: PG::InternalError: ERROR: parse error - invalid geometry
HINT: "01" <-- parse error at position 2 within geometry
PG::InternalError: ERROR: parse error - invalid geometry
HINT: "01" <-- parse error at position 2 within geometry如果我让所有的Sidekiq进程安静下来,停止工人,等一下,然后启动工人,我就可以成功地运行这些作业。
我在我的部署过程中添加了一些延迟(如果重新启动工作人员解决了问题,那么估计放慢速度可能会有帮助),但这并没有帮助。
我通常每天能得到一次成功的部署。在第一次部署之后,它更有可能陷入这种失败状态&如果它进入这种状态,那么以后的每个部署都会导致同样的问题。
Path.first.geog返回:#<RGeo::Geographic::SphericalPointImpl:0x3ffd8b2a6688 "POINT (-72.633932 42.206081)">
Path.first.geog.class返回:RGeo::Geographic::SphericalPointImpl
我尝试了许多不同的查询格式,这些格式可能说明了这种查询是如何/为什么失败的(尽管我仍然很困惑为什么它只是间歇性的):
Node.where("ST_DWITHIN(geog, ST_GeographyFromText(?), 25)", path.geog)失败,生成此查询:Node Load (1.0ms) SELECT "nodes".* FROM "nodes" WHERE (ST_DWITHIN(geog, ST_GeographyFromText('0020000001000010e6c05228925785f8d340451a60dcb9a9da'), 25)) LIMIT $1 [["LIMIT", 11]]这个错误是:
ActiveRecord::StatementInvalid (PG::InternalError: ERROR: parse error - invalid geometry)
HINT: "00" <-- parse error at position 2 within geometryNode.where("ST_DWITHIN(geog, ST_GeographyFromText('#{path.geog}'), 25)")成功,生成了以下查询:Node Load (5.1ms) SELECT "nodes".* FROM "nodes" WHERE (ST_DWITHIN(geog, ST_GeographyFromText('POINT (-72.633932 42.206081)'), 25)) LIMIT $1 [["LIMIT", 11]]Node.where("ST_DWITHIN(geog, ST_GeographyFromText(?), 25)", path.geog.to_s)也成功地生成了相同的查询:Node Load (2.3ms) SELECT "nodes".* FROM "nodes" WHERE (ST_DWITHIN(geog, ST_GeographyFromText('POINT (-72.633932 42.206081)'), 25)) LIMIT $1 [["LIMIT", 11]]to_s转换,因为某种迷信测试也有效:geog_string = path.geog.to_s
nearby_nodes = Node.where("ST_DWITHIN(geog, ST_GeographyFromText(?), 25)", geog_string)查询2-4通常可以工作,但在一些时候和部署之后表现得类似于查询1。我无法使2-4像Rails控制台中的第一个查询那样运行。唯一一次查询2-4的行为类似于第一个查询是在部署后的Sidekiq作业中。这就好像字符串转换有时不能工作一样。
下面列出了一些可能相关的宝石/版本:
F 252
发布于 2020-04-14 12:24:17
不需要将地理位置转换为字符串,然后将其作为地理位置读取。
你可以直接尝试
Node.where("ST_DWITHIN(geog, ?, 25)", path.geog)话虽如此,你可能确实有一些无效的几何图形。
https://stackoverflow.com/questions/61198786
复制相似问题