Billzabob
During a database transaction, we are spawning a Task. The Task ends up querying the database itself, which leads to a race condition: the transaction may or may not have been committed by the time the Task runs its query.
One solution here is to perform the query before the Task and pass its results into the Task. That way the query is run in the transaction and there is no race condition. The problem here is that we moved the query into the Task for performance reasons; Doing the query synchronously was causing timeouts.
We have tried to figure out a way to have the Task poll the transaction status in the main process and only run once it’s complete, but that seems to be impossible since that info is stored on the process dictionary of the main process.
The way we are currently leaning is to just put a Process.sleep call at the beginning of the Task so that the transaction has time to finish and commit before the Task runs, but that obviously feels super dirty.
Any other suggestions?
Trending in Questions
Other Trending 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
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #ai
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 5- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
mbuhot
The task could use a blocking
receiveto wait for a message from the original process before running the query.Alternatively it might be appropriate to switch to a supervised
GenServerwith ahandle_cast.Billzabob
The problem with that is that when we’re spawning the
Taskwe are very deep into the callstack and the transaction is started near the top. We’d have to return the pid of theTaskall the way back up so that we cansendto it once the transaction is finished, which feels a little messy, especially since we don’t own a lot of the calling code.mbuhot
If you’re using Postgres, you could use Listen/Notify to wait for the transaction to complete.
benwilson512
This sounds like you want something like Oban, where instead of spawning a task, you would enqueue a job, and then when the transaction commits, that job can be run.
outlog
+1 for oban