zlacker

[return to "Choose Postgres queue technology"]
1. aduffy+82[view] [source] 2023-09-24 20:41:49
>>bo0tzz+(OP)
For several projects I’ve opted for the even dumber approach, that works out of the box with every ORM/Query DSL framework in every language: using a normal table with SELECT FOR UPDATE SKIP LOCKED

https://www.pgcasts.com/episodes/the-skip-locked-feature-in-...

It’s not “web scale” but it easily extends to several thousand background jobs in my experience

◧◩
2. matsem+x2[view] [source] 2023-09-24 20:44:27
>>aduffy+82
I've done even simpler without locks (as no transaction logic), where I select a row, and then try to update a field about it being taken. If 1 row is affected, it's mine. If 0, someone else did it before me and I select a new row.

I've used this for tasks at big organizations without issue. No need for any special deployments or new infra. Just spin up a few worker threads in your app. Perhaps a thread to reset abandoned tasks. But in three years this never actually happened, as everything was contained in try/catch that would add it back to the queue, and our java app was damn stable.

◧◩◪
3. andrel+a3[view] [source] 2023-09-24 20:48:04
>>matsem+x2
I guess you update it with the assigned worker id, where the "taken by" field is currently null? Does it mean that workers have persistent identities, something like an index? How do you deal with workers being replaced, scaled down, etc?

Just curious. We maintained a custom background processing system for years but recently replaced it with off the shelf stuff, so I'm really interested in how others are doing similar stuff.

◧◩◪◨
4. matsem+V3[view] [source] 2023-09-24 20:52:21
>>andrel+a3
No, just update set taken=1. If it was a change to the row, you updated it. If it wasn't, someone updated before you.

Our tasks were quick enough so that all fetched tasks would always be able to be completed before a scale down / new deploy etc, but we stopped fetching new ones when the signal came so it just finished what it had. I updated above, we did have logic to monitor if a task got taken but never got a finished status, but I can't remember it ever actually reporting on anything.

◧◩◪◨⬒
5. fbdab1+p4[view] [source] 2023-09-24 20:56:15
>>matsem+V3
I would set the taken field to a timestamp. Then you could have a cleanup job that looks for any lingering jobs aged past a reasonable timeout and null out the field.
◧◩◪◨⬒⬓
6. tylerg+h5[view] [source] 2023-09-24 21:02:35
>>fbdab1+p4
it wont work with a timestamp because each write will have an affected row of 1 beacuse the writes happen at different times. setting a boolean is static
◧◩◪◨⬒⬓⬔
7. twic+Ab[view] [source] 2023-09-24 21:54:36
>>tylerg+h5
update tasks set taken_timestamp = now() where task_id = ? and taken_timestamp is null
[go to top]