code.gitea.io/gitea@v1.22.3/modules/queue/manager.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  	"sync"
     9  	"time"
    10  
    11  	"code.gitea.io/gitea/modules/log"
    12  	"code.gitea.io/gitea/modules/setting"
    13  )
    14  
    15  // Manager is a manager for the queues created by "CreateXxxQueue" functions, these queues are called "managed queues".
    16  type Manager struct {
    17  	mu sync.Mutex
    18  
    19  	qidCounter int64
    20  	Queues     map[int64]ManagedWorkerPoolQueue
    21  }
    22  
    23  type ManagedWorkerPoolQueue interface {
    24  	GetName() string
    25  	GetType() string
    26  	GetItemTypeName() string
    27  	GetWorkerNumber() int
    28  	GetWorkerActiveNumber() int
    29  	GetWorkerMaxNumber() int
    30  	SetWorkerMaxNumber(num int)
    31  	GetQueueItemNumber() int
    32  
    33  	// FlushWithContext tries to make the handler process all items in the queue synchronously.
    34  	// It is for testing purpose only. It's not designed to be used in a cluster.
    35  	FlushWithContext(ctx context.Context, timeout time.Duration) error
    36  
    37  	// RemoveAllItems removes all items in the base queue (on-the-fly items are not affected)
    38  	RemoveAllItems(ctx context.Context) error
    39  }
    40  
    41  var manager *Manager
    42  
    43  func init() {
    44  	manager = &Manager{
    45  		Queues: make(map[int64]ManagedWorkerPoolQueue),
    46  	}
    47  }
    48  
    49  func GetManager() *Manager {
    50  	return manager
    51  }
    52  
    53  func (m *Manager) AddManagedQueue(managed ManagedWorkerPoolQueue) {
    54  	m.mu.Lock()
    55  	defer m.mu.Unlock()
    56  	m.qidCounter++
    57  	m.Queues[m.qidCounter] = managed
    58  }
    59  
    60  func (m *Manager) GetManagedQueue(qid int64) ManagedWorkerPoolQueue {
    61  	m.mu.Lock()
    62  	defer m.mu.Unlock()
    63  	return m.Queues[qid]
    64  }
    65  
    66  func (m *Manager) ManagedQueues() map[int64]ManagedWorkerPoolQueue {
    67  	m.mu.Lock()
    68  	defer m.mu.Unlock()
    69  
    70  	queues := make(map[int64]ManagedWorkerPoolQueue, len(m.Queues))
    71  	for k, v := range m.Queues {
    72  		queues[k] = v
    73  	}
    74  	return queues
    75  }
    76  
    77  // FlushAll tries to make all managed queues process all items synchronously, until timeout or the queue is empty.
    78  // It is for testing purpose only. It's not designed to be used in a cluster.
    79  func (m *Manager) FlushAll(ctx context.Context, timeout time.Duration) error {
    80  	var finalErr error
    81  	qs := m.ManagedQueues()
    82  	for _, q := range qs {
    83  		if err := q.FlushWithContext(ctx, timeout); err != nil {
    84  			finalErr = err // TODO: in Go 1.20: errors.Join
    85  		}
    86  	}
    87  	return finalErr
    88  }
    89  
    90  // CreateSimpleQueue creates a simple queue from global setting config provider by name
    91  func CreateSimpleQueue[T any](ctx context.Context, name string, handler HandlerFuncT[T]) *WorkerPoolQueue[T] {
    92  	return createWorkerPoolQueue(ctx, name, setting.CfgProvider, handler, false)
    93  }
    94  
    95  // CreateUniqueQueue creates a unique queue from global setting config provider by name
    96  func CreateUniqueQueue[T any](ctx context.Context, name string, handler HandlerFuncT[T]) *WorkerPoolQueue[T] {
    97  	return createWorkerPoolQueue(ctx, name, setting.CfgProvider, handler, true)
    98  }
    99  
   100  func createWorkerPoolQueue[T any](ctx context.Context, name string, cfgProvider setting.ConfigProvider, handler HandlerFuncT[T], unique bool) *WorkerPoolQueue[T] {
   101  	queueSetting, err := setting.GetQueueSettings(cfgProvider, name)
   102  	if err != nil {
   103  		log.Error("Failed to get queue settings for %q: %v", name, err)
   104  		return nil
   105  	}
   106  	w, err := NewWorkerPoolQueueWithContext(ctx, name, queueSetting, handler, unique)
   107  	if err != nil {
   108  		log.Error("Failed to create queue %q: %v", name, err)
   109  		return nil
   110  	}
   111  	GetManager().AddManagedQueue(w)
   112  	return w
   113  }