code.gitea.io/gitea@v1.19.3/modules/queue/queue_disk.go (about) 1 // Copyright 2019 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package queue 5 6 import ( 7 "context" 8 9 "code.gitea.io/gitea/modules/nosql" 10 11 "gitea.com/lunny/levelqueue" 12 ) 13 14 // LevelQueueType is the type for level queue 15 const LevelQueueType Type = "level" 16 17 // LevelQueueConfiguration is the configuration for a LevelQueue 18 type LevelQueueConfiguration struct { 19 ByteFIFOQueueConfiguration 20 DataDir string 21 ConnectionString string 22 QueueName string 23 } 24 25 // LevelQueue implements a disk library queue 26 type LevelQueue struct { 27 *ByteFIFOQueue 28 } 29 30 // NewLevelQueue creates a ledis local queue 31 func NewLevelQueue(handle HandlerFunc, cfg, exemplar interface{}) (Queue, error) { 32 configInterface, err := toConfig(LevelQueueConfiguration{}, cfg) 33 if err != nil { 34 return nil, err 35 } 36 config := configInterface.(LevelQueueConfiguration) 37 38 if len(config.ConnectionString) == 0 { 39 config.ConnectionString = config.DataDir 40 } 41 config.WaitOnEmpty = true 42 43 byteFIFO, err := NewLevelQueueByteFIFO(config.ConnectionString, config.QueueName) 44 if err != nil { 45 return nil, err 46 } 47 48 byteFIFOQueue, err := NewByteFIFOQueue(LevelQueueType, byteFIFO, handle, config.ByteFIFOQueueConfiguration, exemplar) 49 if err != nil { 50 return nil, err 51 } 52 53 queue := &LevelQueue{ 54 ByteFIFOQueue: byteFIFOQueue, 55 } 56 queue.qid = GetManager().Add(queue, LevelQueueType, config, exemplar) 57 return queue, nil 58 } 59 60 var _ ByteFIFO = &LevelQueueByteFIFO{} 61 62 // LevelQueueByteFIFO represents a ByteFIFO formed from a LevelQueue 63 type LevelQueueByteFIFO struct { 64 internal *levelqueue.Queue 65 connection string 66 } 67 68 // NewLevelQueueByteFIFO creates a ByteFIFO formed from a LevelQueue 69 func NewLevelQueueByteFIFO(connection, prefix string) (*LevelQueueByteFIFO, error) { 70 db, err := nosql.GetManager().GetLevelDB(connection) 71 if err != nil { 72 return nil, err 73 } 74 75 internal, err := levelqueue.NewQueue(db, []byte(prefix), false) 76 if err != nil { 77 return nil, err 78 } 79 80 return &LevelQueueByteFIFO{ 81 connection: connection, 82 internal: internal, 83 }, nil 84 } 85 86 // PushFunc will push data into the fifo 87 func (fifo *LevelQueueByteFIFO) PushFunc(ctx context.Context, data []byte, fn func() error) error { 88 if fn != nil { 89 if err := fn(); err != nil { 90 return err 91 } 92 } 93 return fifo.internal.LPush(data) 94 } 95 96 // PushBack pushes data to the top of the fifo 97 func (fifo *LevelQueueByteFIFO) PushBack(ctx context.Context, data []byte) error { 98 return fifo.internal.RPush(data) 99 } 100 101 // Pop pops data from the start of the fifo 102 func (fifo *LevelQueueByteFIFO) Pop(ctx context.Context) ([]byte, error) { 103 data, err := fifo.internal.RPop() 104 if err != nil && err != levelqueue.ErrNotFound { 105 return nil, err 106 } 107 return data, nil 108 } 109 110 // Close this fifo 111 func (fifo *LevelQueueByteFIFO) Close() error { 112 err := fifo.internal.Close() 113 _ = nosql.GetManager().CloseLevelDB(fifo.connection) 114 return err 115 } 116 117 // Len returns the length of the fifo 118 func (fifo *LevelQueueByteFIFO) Len(ctx context.Context) int64 { 119 return fifo.internal.Len() 120 } 121 122 func init() { 123 queuesMap[LevelQueueType] = NewLevelQueue 124 }