У меня периодически возникает ошибка после некоторых развертываний моего приложения Rails.
Этот код выполняется в Sidekiq (5 процессов каждый с 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 geometry
Node.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 после развертывания. Как будто преобразование строк иногда не работает.
Вот список потенциально важных версий / версий:
- activerecord-postgis-adapter (6.0.0)
- pg (1.2.3)
- рельсы (6.0.2.2)
- rgeo (2.1.1)
- rgeo-activerecord (6.2.1)
- sidekiq (6.0.6)
- Ruby 2.6.6
- PostgreSQL 11,6
- PostGIS 2.5.2
- Docker 19.03.8, сборка afacb8b7f0