Skip to content

Commit faa5074

Browse files
authored
Expanding documentation in queue.go
A set of terminology, along with a broader description, can help more people engage with the Gitea queue system, providing insights and ensuring its correct use.
1 parent 1bfb3f7 commit faa5074

File tree

1 file changed

+47
-12
lines changed

1 file changed

+47
-12
lines changed

modules/queue/queue.go

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,62 @@
11
// Copyright 2023 The Gitea Authors. All rights reserved.
22
// SPDX-License-Identifier: MIT
33

4-
// Package queue implements a specialized queue system for Gitea.
4+
// Package queue implements a specialized concurrent queue system for Gitea.
55
//
6-
// There are two major kinds of concepts:
6+
// Terminology:
77
//
8-
// * The "base queue": channel, level, redis:
9-
// - They have the same abstraction, the same interface, and they are tested by the same testing code.
10-
// - The dummy(immediate) queue is special, it's not a real queue, it's only used as a no-op queue or a testing queue.
8+
// 1. Task:
9+
// - A task can be a simple value, such as an integer, or a more complex structure that has multiple fields and
10+
// methods. The aim of a task is to be a unit of work, a set of tasks will be sent to a handler to be processed.
1111
//
12-
// * The WorkerPoolQueue: it uses the "base queue" to provide "worker pool" function.
13-
// - It calls the "handler" to process the data in the base queue.
14-
// - Its "Push" function doesn't block forever,
15-
// it will return an error if the queue is full after the timeout.
12+
// 2. Batch:
13+
// - A collection of tasks that are grouped together for processing. Each worker receives a batch of tasks.
14+
//
15+
// 3. Worker:
16+
// - Individual unit of execution designed to process tasks from the queue. It's a goroutine that calls the Handler
17+
// - Workers will get new tasks through a channel (WorkerPoolQueue is responsible for the distribution)
18+
// - As workers operate in parallel, the default value of max workers is n/2, where n is the number of logical CPUs
19+
//
20+
// 4. Handler (represented by HandlerFuncT type):
21+
// - It's the function responsible to process tasks. Each active worker will call this.
22+
// - When processing these batches, there might be instances where certain tasks remain unprocessed or "unhandled".
23+
// In such scenarios, the Handler ensures these unhandled tasks are returned to the base queue after a brief delay.
24+
// This mechanism is particularly beneficial in cases where the processing entity (like a document indexer) is
25+
// temporarily unavailable. It ensures that no task is skipped or lost due to transient failures in the processing
26+
// mechanism.
27+
//
28+
// 5. Base queue:
29+
// - Represents the underlying storage mechanism for the queue. There are several implementations:
30+
// - Channel: Uses Go's native channel constructs to manage the queue, suitable for in-memory queuing.
31+
// - Level, Redis: Especially useful in persistent queues and clusters, where we may have multiple nodes.
32+
// - Dummy: This is special, it's not a real queue, it's only used as a no-op queue or a testing queue.
33+
// - They all have the same abstraction, the same interface, and they are tested by the same testing code.
34+
//
35+
// 6. WorkerPoolQueue:
36+
// - It's responsible to glue all together, using the "base queue" to provide "worker pool" functionality. He creates
37+
// new workers if needed and can flush the queue, running all the tasks synchronously till it finishes.
38+
// - Its "Push" function doesn't block forever, it will return an error if the queue is full after the timeout.
39+
//
40+
// 7. Manager:
41+
// - The purpose of it is to serve as a centralized manager for multiple WorkerPoolQueue instances. Whenever we want
42+
// to create a new queue, flush, or get a specific queue, we have to use it.
1643
//
1744
// A queue can be "simple" or "unique". A unique queue will try to avoid duplicate items.
1845
// Unique queue's "Has" function can be used to check whether an item is already in the queue,
1946
// although it's not 100% reliable due to there is no proper transaction support.
2047
// Simple queue's "Has" function always returns "has=false".
2148
//
22-
// The HandlerFuncT function is called by the WorkerPoolQueue to process the data in the base queue.
23-
// If the handler returns "unhandled" items, they will be re-queued to the base queue after a slight delay,
24-
// in case the item processor (eg: document indexer) is not available.
49+
// A WorkerPoolQueue is a generic struct; this means it will work with any type but just for that type.
50+
// If you want another kind of tasks to run, you would have to call the manager to create a new WorkerPoolQueue for you
51+
// with a different handler that works with this new type of task. As an example of this:
52+
//
53+
// func Init() error {
54+
// taskQueue = queue.CreateSimpleQueue(graceful.GetManager().ShutdownContext(), "task", handler)
55+
// ...
56+
// }
57+
// func handler(items ...*admin_model.Task) []*admin_model.Task { ... }
58+
//
59+
// As you can see, the handler defined the admin_model.Task type for the queue
2560
package queue
2661

2762
import "code.gitea.io/gitea/modules/util"

0 commit comments

Comments
 (0)