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  }