lock.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. package database
  2. import (
  3. "time"
  4. "github.com/pkg/errors"
  5. log "github.com/sirupsen/logrus"
  6. "github.com/crowdsecurity/crowdsec/pkg/database/ent"
  7. "github.com/crowdsecurity/crowdsec/pkg/database/ent/lock"
  8. "github.com/crowdsecurity/crowdsec/pkg/types"
  9. )
  10. const (
  11. CAPIPullLockTimeout = 120
  12. MetricsLockTimeout = 30
  13. )
  14. func (c *Client) AcquireLock(name string) error {
  15. // pessimistic lock
  16. _, err := c.Ent.Lock.Create().
  17. SetName(name).
  18. SetCreatedAt(types.UtcNow()).
  19. Save(c.CTX)
  20. if ent.IsConstraintError(err) {
  21. return err
  22. }
  23. if err != nil {
  24. return errors.Wrapf(InsertFail, "insert lock: %s", err)
  25. }
  26. return nil
  27. }
  28. func (c *Client) ReleaseLock(name string) error {
  29. _, err := c.Ent.Lock.Delete().Where(lock.NameEQ(name)).Exec(c.CTX)
  30. if err != nil {
  31. return errors.Wrapf(DeleteFail, "delete lock: %s", err)
  32. }
  33. return nil
  34. }
  35. func (c *Client) ReleaseLockWithTimeout(name string, timeout int) error {
  36. log.Debugf("(%s) releasing orphin locks", name)
  37. _, err := c.Ent.Lock.Delete().Where(
  38. lock.NameEQ(name),
  39. lock.CreatedAtLT(time.Now().Add(-time.Duration(timeout)*time.Minute)),
  40. ).Exec(c.CTX)
  41. if err != nil {
  42. return errors.Wrapf(DeleteFail, "delete lock: %s", err)
  43. }
  44. return nil
  45. }
  46. func (c *Client) IsLocked(err error) bool {
  47. return ent.IsConstraintError(err)
  48. }
  49. func (c *Client) AcquirePushMetricsLock() error {
  50. lockName := "pushMetrics"
  51. err := c.ReleaseLockWithTimeout(lockName, MetricsLockTimeout)
  52. if err != nil {
  53. log.Errorf("unable to release pushMetrics lock: %s", err)
  54. }
  55. return c.AcquireLock(lockName)
  56. }
  57. func (c *Client) ReleasePushMetricsLock() error {
  58. return c.ReleaseLock("pushMetrics")
  59. }
  60. func (c *Client) AcquirePullCAPILock() error {
  61. lockName := "pullCAPI"
  62. err := c.ReleaseLockWithTimeout(lockName, CAPIPullLockTimeout)
  63. if err != nil {
  64. log.Errorf("unable to release pullCAPI lock: %s", err)
  65. }
  66. return c.AcquireLock(lockName)
  67. }
  68. func (c *Client) ReleasePullCAPILock() error {
  69. return c.ReleaseLockWithTimeout("pullCAPI", CAPIPullLockTimeout)
  70. }