go-redis/cache

codec.Once() running from different binaries

alexbolgov opened this issue · 5 comments

Hello!
Thanks for supporting this library.

I started using codec.Once() today and noticed that it's not obtaining a distributed lock before executing a Func, what results in executing Func more than one-at-a-time

Is this behaviour by design?

It is the expected behavior though DistributedOnce would be a nice thing to have. In Go I usually don't have that many nodes to justify having it enabled by default...

Don't you mind if I contribute with "DistributedOnce"?

Please do - it is definitely useful thing to have.

Feel free to use whatever makes sense, but there is already lib https://github.com/bsm/redislock that provides distributed locks for Redis. Currently it does not support v8 so you may need to use a copy from https://github.com/vmihailenco/taskq/blob/master/internal/redislock/redislock.go that is updated to work with redis/v8.

I'm looking at this now and have some thoughts/concerns/ideas:

If some existing implementation of Redis lock is used as a dependency, this causes rediser interface to grow. See here https://github.com/bsm/redislock/blob/master/redislock.go#L31.

This will introduce a breaking change. I assume it's not good, so I have another idea:

What if adding some locker interface + having a Locker parameter in cache Options. This way it will let a client passing any desired locker implementation and keep locker configuration away from the cache library.

Probably, to make this approach more user-friendly, it's possible to have some builder-functions that convert some popular Redis-lock implementations to a locker interface

see this commit alexbolgov@81e2f4b

What do you think @vmihailenco ?

@alexbolgov I would just extend rediser with commands you need. It is very unlikely that anyone will need custom locker implementation and if they do - they likely have some other unknown requirements as well. Let's keep it simple at this point :)