preemptive.go 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package cluster
  2. import (
  3. "errors"
  4. "github.com/langgenius/dify-plugin-daemon/internal/utils/cache"
  5. )
  6. // Plugin daemon will preemptively try to lock the slot to be the master of the cluster
  7. // and keep update current status of the whole cluster
  8. // once the master is no longer active, one of the slave will try to lock the slot again
  9. // and become the new master
  10. //
  11. // Once a node becomes master, It will take responsibility to gc the nodes has already deactivated
  12. // and all nodes should to maintenance their own status
  13. //
  14. // State:
  15. // - hashmap[cluster-status]
  16. // - node-id:
  17. // - list[ip]:
  18. // - address: string
  19. // - vote: int
  20. // - last_ping_at: int64
  21. // - preemption-lock: node-id
  22. // - node-status-upgrade-status
  23. //
  24. // A node will be removed from the cluster if it is no longer active
  25. const (
  26. CLUSTER_STATUS_HASH_MAP_KEY = "cluster-nodes-status-hash-map"
  27. PREEMPTION_LOCK_KEY = "cluster-master-preemption-lock"
  28. )
  29. // try lock the slot to be the master of the cluster
  30. // returns:
  31. // - bool: true if the slot is locked by the node
  32. // - error: error if any
  33. func (c *Cluster) lockMaster() (bool, error) {
  34. var final_error error
  35. for i := 0; i < 3; i++ {
  36. if success, err := cache.SetNX(PREEMPTION_LOCK_KEY, c.id, MASTER_LOCK_EXPIRED_TIME); err != nil {
  37. // try again
  38. if final_error == nil {
  39. final_error = err
  40. } else {
  41. final_error = errors.Join(final_error, err)
  42. }
  43. } else if !success {
  44. return false, nil
  45. } else {
  46. return true, nil
  47. }
  48. }
  49. return false, final_error
  50. }
  51. // update master
  52. func (c *Cluster) updateMaster() error {
  53. // update expired time of master key
  54. if _, err := cache.Expire(PREEMPTION_LOCK_KEY, MASTER_LOCK_EXPIRED_TIME); err != nil {
  55. return err
  56. }
  57. return nil
  58. }