You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

queue_disk.go 2.2 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. // Copyright 2019 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package issues
  5. import (
  6. "encoding/json"
  7. "time"
  8. "code.gitea.io/gitea/modules/log"
  9. "github.com/lunny/levelqueue"
  10. )
  11. var (
  12. _ Queue = &LevelQueue{}
  13. )
  14. // LevelQueue implements a disk library queue
  15. type LevelQueue struct {
  16. indexer Indexer
  17. queue *levelqueue.Queue
  18. batchNumber int
  19. }
  20. // NewLevelQueue creates a ledis local queue
  21. func NewLevelQueue(indexer Indexer, dataDir string, batchNumber int) (*LevelQueue, error) {
  22. queue, err := levelqueue.Open(dataDir)
  23. if err != nil {
  24. return nil, err
  25. }
  26. return &LevelQueue{
  27. indexer: indexer,
  28. queue: queue,
  29. batchNumber: batchNumber,
  30. }, nil
  31. }
  32. // Run starts to run the queue
  33. func (l *LevelQueue) Run() error {
  34. var i int
  35. var datas = make([]*IndexerData, 0, l.batchNumber)
  36. for {
  37. bs, err := l.queue.RPop()
  38. if err != nil {
  39. log.Error(4, "RPop: %v", err)
  40. time.Sleep(time.Millisecond * 100)
  41. continue
  42. }
  43. i++
  44. if len(datas) > l.batchNumber || (len(datas) > 0 && i > 3) {
  45. l.indexer.Index(datas)
  46. datas = make([]*IndexerData, 0, l.batchNumber)
  47. i = 0
  48. }
  49. if len(bs) <= 0 {
  50. time.Sleep(time.Millisecond * 100)
  51. continue
  52. }
  53. var data IndexerData
  54. err = json.Unmarshal(bs, &data)
  55. if err != nil {
  56. log.Error(4, "Unmarshal: %v", err)
  57. time.Sleep(time.Millisecond * 100)
  58. continue
  59. }
  60. log.Trace("LedisLocalQueue: task found: %#v", data)
  61. if data.IsDelete {
  62. if data.ID > 0 {
  63. if err = l.indexer.Delete(data.ID); err != nil {
  64. log.Error(4, "indexer.Delete: %v", err)
  65. }
  66. } else if len(data.IDs) > 0 {
  67. if err = l.indexer.Delete(data.IDs...); err != nil {
  68. log.Error(4, "indexer.Delete: %v", err)
  69. }
  70. }
  71. time.Sleep(time.Millisecond * 10)
  72. continue
  73. }
  74. datas = append(datas, &data)
  75. time.Sleep(time.Millisecond * 10)
  76. }
  77. }
  78. // Push will push the indexer data to queue
  79. func (l *LevelQueue) Push(data *IndexerData) {
  80. bs, err := json.Marshal(data)
  81. if err != nil {
  82. log.Error(4, "Marshal: %v", err)
  83. return
  84. }
  85. err = l.queue.LPush(bs)
  86. if err != nil {
  87. log.Error(4, "LPush: %v", err)
  88. }
  89. }