Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

transaction interface #21

Open
GopherJ opened this issue May 12, 2024 · 5 comments
Open

transaction interface #21

GopherJ opened this issue May 12, 2024 · 5 comments

Comments

@GopherJ
Copy link
Contributor

GopherJ commented May 12, 2024

No description provided.

@DavidBM
Copy link
Owner

DavidBM commented May 12, 2024

Transactions on Redis are kind of tricky. Turns out that Redis doesn't support rollback 1, so if something fails, you still end with a bad state.

I assume your ideal case is to be able to consume and send an event transactionally. Or to be able to send more than one event in a transaction.

In that case, you want the consumption to rollback if there is an error. You can simulate that with the timeout, so the message is only hidden for a couple of secs.

In the second case, to be able to emit several events, Redis lack of guarantees makes it impossible to make it work, because in case of error on the Redis side, it won't roll back.

What is the use case you want to support? Maybe is a use case different from the ones I describe?

@GopherJ
Copy link
Contributor Author

GopherJ commented May 21, 2024

I kind need send_message to be atomic, so eventually a two phase thing should work. send_message in a for loop then commit

need this in financial use case, I created this issue to take a note but redis-rs client doesn't have a good transaction support, at least it's not very easy to use

@GopherJ
Copy link
Contributor Author

GopherJ commented May 21, 2024

maybe a way is to write in lua sendMessages.lua etc, that should be interesting

OR pipeline many messages and make it atomic. I'm not sure what's the best yet

@GopherJ
Copy link
Contributor Author

GopherJ commented May 24, 2024

a working one is on: https://github.com/GopherJ/rsmq-sync/blob/feat/send-multiple-messages-using-lua/src/redis-scripts/sendMessage.lua

local ns = KEYS[1]
local qname = KEYS[2]
local ts_delay = tonumber(KEYS[3])
local queue_uids = cjson.decode(KEYS[4])
local messages = cjson.decode(KEYS[5])
local realtime = tonumber(KEYS[6])

local key = ns .. qname
local queue_key = ns .. qname .. ':Q'
local realtime_key = ns .. ':rt:' .. qname

for i = 1, #queue_uids do

redis.call('ZADD', key, ts_delay, queue_uids[i])
redis.call('HSET', queue_key, queue_uids[i], messages[i])

end

local result = redis.call('HINCRBY', queue_key, 'totalsent', #queue_uids)

if realtime == 1 then
    result = redis.call('ZCARD', key)
    redis.call('PUBLISH', realtime_key, result)
end

return result

@DavidBM
Copy link
Owner

DavidBM commented May 30, 2024

Does the pipeline work for you? We could build something on that case.

For for a financial case, you might not want to use a library like this one. Guarantees are quite low for handling money.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants