unique_queue.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // Copyright 2015 - Present, The Gogs Authors. All rights reserved.
  2. // Copyright 2018 - Present, Gitote. All rights reserved.
  3. //
  4. // This source code is licensed under the MIT license found in the
  5. // LICENSE file in the root directory of this source tree.
  6. package sync
  7. import (
  8. "gitlab.com/gitote/com"
  9. )
  10. // UniqueQueue is a queue which guarantees only one instance of same
  11. // identity is in the line. Instances with same identity will be
  12. // discarded if there is already one in the line.
  13. //
  14. // This queue is particularly useful for preventing duplicated task
  15. // of same purpose.
  16. type UniqueQueue struct {
  17. table *StatusTable
  18. queue chan string
  19. }
  20. // NewUniqueQueue initializes and returns a new UniqueQueue object.
  21. func NewUniqueQueue(queueLength int) *UniqueQueue {
  22. if queueLength <= 0 {
  23. queueLength = 100
  24. }
  25. return &UniqueQueue{
  26. table: NewStatusTable(),
  27. queue: make(chan string, queueLength),
  28. }
  29. }
  30. // Queue returns channel of queue for retrieving instances.
  31. func (q *UniqueQueue) Queue() <-chan string {
  32. return q.queue
  33. }
  34. // Exist returns true if there is an instance with given indentity
  35. // exists in the queue.
  36. func (q *UniqueQueue) Exist(id interface{}) bool {
  37. return q.table.IsRunning(com.ToStr(id))
  38. }
  39. // AddFunc adds new instance to the queue with a custom runnable function,
  40. // the queue is blocked until the function exits.
  41. func (q *UniqueQueue) AddFunc(id interface{}, fn func()) {
  42. if q.Exist(id) {
  43. return
  44. }
  45. idStr := com.ToStr(id)
  46. q.table.Lock()
  47. q.table.pool[idStr] = true
  48. if fn != nil {
  49. fn()
  50. }
  51. q.table.Unlock()
  52. q.queue <- idStr
  53. }
  54. // Add adds new instance to the queue.
  55. func (q *UniqueQueue) Add(id interface{}) {
  56. q.AddFunc(id, nil)
  57. }
  58. // Remove removes instance from the queue.
  59. func (q *UniqueQueue) Remove(id interface{}) {
  60. q.table.Stop(com.ToStr(id))
  61. }