2020-01-07 14:23:09 +03:00
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package queue
import (
2021-05-15 17:22:26 +03:00
"context"
2020-09-28 00:09:46 +03:00
"code.gitea.io/gitea/modules/nosql"
2020-01-07 14:23:09 +03:00
"gitea.com/lunny/levelqueue"
)
// LevelQueueType is the type for level queue
const LevelQueueType Type = "level"
// LevelQueueConfiguration is the configuration for a LevelQueue
type LevelQueueConfiguration struct {
2020-02-03 02:19:58 +03:00
ByteFIFOQueueConfiguration
2020-09-28 00:09:46 +03:00
DataDir string
ConnectionString string
QueueName string
2020-01-07 14:23:09 +03:00
}
// LevelQueue implements a disk library queue
type LevelQueue struct {
2020-02-03 02:19:58 +03:00
* ByteFIFOQueue
2020-01-07 14:23:09 +03:00
}
// NewLevelQueue creates a ledis local queue
func NewLevelQueue ( handle HandlerFunc , cfg , exemplar interface { } ) ( Queue , error ) {
configInterface , err := toConfig ( LevelQueueConfiguration { } , cfg )
if err != nil {
return nil , err
}
config := configInterface . ( LevelQueueConfiguration )
2020-09-28 00:09:46 +03:00
if len ( config . ConnectionString ) == 0 {
config . ConnectionString = config . DataDir
}
2021-05-15 17:22:26 +03:00
config . WaitOnEmpty = true
2020-09-28 00:09:46 +03:00
byteFIFO , err := NewLevelQueueByteFIFO ( config . ConnectionString , config . QueueName )
2020-02-03 02:19:58 +03:00
if err != nil {
return nil , err
}
byteFIFOQueue , err := NewByteFIFOQueue ( LevelQueueType , byteFIFO , handle , config . ByteFIFOQueueConfiguration , exemplar )
2020-01-07 14:23:09 +03:00
if err != nil {
return nil , err
}
queue := & LevelQueue {
2020-02-03 02:19:58 +03:00
ByteFIFOQueue : byteFIFOQueue ,
2020-01-07 14:23:09 +03:00
}
2020-01-29 04:01:06 +03:00
queue . qid = GetManager ( ) . Add ( queue , LevelQueueType , config , exemplar )
2020-01-07 14:23:09 +03:00
return queue , nil
}
2021-04-09 10:40:34 +03:00
var _ ByteFIFO = & LevelQueueByteFIFO { }
2020-01-07 14:23:09 +03:00
2020-02-03 02:19:58 +03:00
// LevelQueueByteFIFO represents a ByteFIFO formed from a LevelQueue
type LevelQueueByteFIFO struct {
2020-09-28 00:09:46 +03:00
internal * levelqueue . Queue
connection string
2020-01-07 14:23:09 +03:00
}
2020-02-03 02:19:58 +03:00
// NewLevelQueueByteFIFO creates a ByteFIFO formed from a LevelQueue
2020-09-28 00:09:46 +03:00
func NewLevelQueueByteFIFO ( connection , prefix string ) ( * LevelQueueByteFIFO , error ) {
db , err := nosql . GetManager ( ) . GetLevelDB ( connection )
if err != nil {
return nil , err
}
internal , err := levelqueue . NewQueue ( db , [ ] byte ( prefix ) , false )
2020-01-07 14:23:09 +03:00
if err != nil {
2020-02-03 02:19:58 +03:00
return nil , err
2020-01-07 14:23:09 +03:00
}
2020-02-03 02:19:58 +03:00
return & LevelQueueByteFIFO {
2020-09-28 00:09:46 +03:00
connection : connection ,
internal : internal ,
2020-02-03 02:19:58 +03:00
} , nil
2020-01-07 14:23:09 +03:00
}
2020-02-03 02:19:58 +03:00
// PushFunc will push data into the fifo
2021-05-15 17:22:26 +03:00
func ( fifo * LevelQueueByteFIFO ) PushFunc ( ctx context . Context , data [ ] byte , fn func ( ) error ) error {
2020-02-03 02:19:58 +03:00
if fn != nil {
if err := fn ( ) ; err != nil {
return err
}
2020-01-29 04:01:06 +03:00
}
2020-02-03 02:19:58 +03:00
return fifo . internal . LPush ( data )
2020-01-29 04:01:06 +03:00
}
2022-01-23 00:22:14 +03:00
// PushBack pushes data to the top of the fifo
func ( fifo * LevelQueueByteFIFO ) PushBack ( ctx context . Context , data [ ] byte ) error {
return fifo . internal . RPush ( data )
}
2020-02-03 02:19:58 +03:00
// Pop pops data from the start of the fifo
2021-05-15 17:22:26 +03:00
func ( fifo * LevelQueueByteFIFO ) Pop ( ctx context . Context ) ( [ ] byte , error ) {
2020-02-03 02:19:58 +03:00
data , err := fifo . internal . RPop ( )
if err != nil && err != levelqueue . ErrNotFound {
return nil , err
2020-01-07 14:23:09 +03:00
}
2020-02-03 02:19:58 +03:00
return data , nil
2020-01-07 14:23:09 +03:00
}
2020-02-03 02:19:58 +03:00
// Close this fifo
func ( fifo * LevelQueueByteFIFO ) Close ( ) error {
2020-09-28 00:09:46 +03:00
err := fifo . internal . Close ( )
_ = nosql . GetManager ( ) . CloseLevelDB ( fifo . connection )
return err
2020-01-07 14:23:09 +03:00
}
2020-02-03 02:19:58 +03:00
// Len returns the length of the fifo
2021-05-15 17:22:26 +03:00
func ( fifo * LevelQueueByteFIFO ) Len ( ctx context . Context ) int64 {
2020-02-03 02:19:58 +03:00
return fifo . internal . Len ( )
2020-01-07 14:23:09 +03:00
}
func init ( ) {
queuesMap [ LevelQueueType ] = NewLevelQueue
}