cjk
Timeout errors with long running transactions
Hi there,
I have a problem with ecto timeouts (so it seems). In a Elixir application I wrote a module for importing data. It gets a CSV file, goes through that file line by line (with a Stream.map()), looks if this dataset already exists in the database, updates it or inserts it as a new dataset. Pretty basic.
To make that operation restartable I wrap this whole process in a database transaction. The amount of datasets is pretty large and it can take up to an hour.
I know of Ecto timeouts, and thus I start that transaction with timeout: :infinity to avoid timeout problems. It works in development, but in prod I get strange errors:
16:02:34.435 [error] Postgrex.Protocol (#PID<0.423.0>) disconnected: ** (DBConnection.ConnectionError) ssl send: closed
or
** (exit) an exception was raised:
** (DBConnection.ConnectionError) ssl send: closed
(ecto_sql) lib/ecto/adapters/sql.ex:624: Ecto.Adapters.SQL.raise_sql_call_error/1
(ecto_sql) lib/ecto/adapters/sql.ex:557: Ecto.Adapters.SQL.execute/5
(ecto) lib/ecto/repo/queryable.ex:147: Ecto.Repo.Queryable.execute/4
(ecto) lib/ecto/repo/queryable.ex:18: Ecto.Repo.Queryable.all/3
(ecto) lib/ecto/repo/queryable.ex:66: Ecto.Repo.Queryable.one/3
(termitool) lib/termitool/meta/meta.ex:332: Termitool.Meta.get_user_by/1
(termitool) lib/termitool/meta/meta.ex:439: Termitool.Meta.get_by_username/1
(termitool) lib/termitool/meta/meta.ex:465: Termitool.Meta.username_password_auth/2
Basically connection errors at random places in the application. I can avoid this problem by setting timeout: :infinity in the repo configuration, but this seems wrong and dangerous to me.
The code is basically:
Repo.transaction(fn ->
stream
|> Stream.map(fn {row, idx} -> update_or_create_row(row) end)
end,
timeout: :infinity)
I am using a stream because that’s what I get from the CSV parsing library.
What am I doing wrong?
Best regards,
CK
Marked As Solved
engineeringdept
Are you running in a Docker container? I discovered a bug in the the official Elixir 1.8.1 container, which is backed by Erlang 21.3, which caused SSL problems like these in production. I had to switch to a custom image running Erlang 21.2.7.
Also Liked
outlog
think you are hitting this 21.3 OTP bug that is just emerging:
and mentioned here Workaround for Docker with Erlang/OTP 21.3 and
Redirecting… (identical but with patch)
can you downgrade to OTP 21.2.7 ? or wait for patch release (presumably later today)..
cjk
kokolegorille
Instead of inserting new rows, I keep them in a list, and proceed all in one go.
If You have different tables, You still might keep multiple lists (one per table), and proceed with multiple insert_all.
I had similar constraint (huge textfile, multiple tables, over 1’000’000 records) with update or create. I had to be careful to race condition when processing the file concurrently.
After using tasks, poolboy, I finally setup my import pipeline with GenStage, and a couple of insert_all.
Last Post!
cjk
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex









