bsm / redislock

Simplified distributed locking implementation using Redis
Other
1.45k stars 157 forks source link

I have added more functions, please check the specific information for details. Looking forward to your reply. #39

Closed musclechen closed 2 years ago

musclechen commented 2 years ago

Modified content:

  1. Use the hash type as the lock, and improve the lua script for locking, so that the lock becomes a ReentrantLock.
  2. Added the strategy of using expiration time as spin waiting time. This is more efficient and saves CPU resources than using custom waiting time.
  3. The publish and subscribe phase is newly added, which saves the free time after entering the CAS phase and the first attempt to lock. At this stage, Redis's List type is used as a simple message queue, which guarantees FIFO to a certain extent.
  4. Added WatchDog mechanism, users can choose whether to use it or not. This mechanism provides a daemon thread that can refresh the lock expiration time regularly to prevent the lock from failing prematurely.
  5. Use the go-promise component to complete the asynchronous function. The 'subscribe' cannot set a timeout period, so you need to use this component to actively end the subscription to prevent the thread from being blocked all the time. When the thread is blocked, it is caused by the CPU switching time slice, so no better solution has been found yet.

Existing problems: Maybe using go-test will display "use of closed network connection", but if you use the Gin framework to introduce distributed locks, there will be no similar problems. I have used Jmeter for testing and there are no similar problems.

Problem analysis: Each goroutine did not immediately execute "defer pub.Unsubscribe(ctx, key+"-pub")" on line 494 after the execution was completed, but waited until the main thread ended before executing this line of code, but after the main thread ended the redis link is closed.

The distributed lock borrows Java's Redisson implementation. Welcome to point out the unreasonable points. I will try my best to modify it. I look forward to the code can be merged into the main branch, and I will contribute my own strength to GitHub.

dim commented 2 years ago

@cyfckl2012 thanks for the effort and apologies for delayed response, but I am not sure I like what I see :)

First of all, it's too many things in one PR. The other problem for me is that the code is not very clean. You still have debug (fmt.Println) there and some methods (e.g. pubsub and watchDog) are almost unreadable.

I also have a hard time to fully understand why this implementation is better/faster/less contentious. I cannot see how it would improve real-world applications even in ultra-low-latency scenarios. But, that takes us back to my initial "too many things in one PR" comment. I would really appreciate if you could submit multiple, smaller PRs with one feature each, then we can discuss the code one step at a time.

Thanks again for the contribution, but I will decline this PR for now, since it's not in a ready-to-merge state (yet).