mirror of
https://gitea.com/gitea/act_runner.git
synced 2026-05-08 08:13:25 +02:00
refactor: use single poller with semaphore-based capacity control
Previously, capacity=N spawned N independent polling goroutines, each making FetchTask RPCs to the Gitea server concurrently. This caused unnecessary connection load on the server proportional to the runner's capacity setting. Replace the N-goroutine model with a single polling loop that uses a buffered channel as a semaphore to control concurrent task execution. The poller acquires a capacity slot before fetching; when at capacity, it blocks without issuing RPCs. Fetched tasks are dispatched to independent goroutines that release their slot on completion. Also fix a pre-existing bug in Shutdown() where the timeout branch used a blocking receive on p.done instead of a non-blocking select, which prevented shutdownJobs() from ever being called on timeout. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -19,11 +19,10 @@ import (
|
||||
"gitea.com/gitea/act_runner/internal/pkg/config"
|
||||
)
|
||||
|
||||
// TestPoller_PerWorkerCounters verifies that each worker maintains its own
|
||||
// backoff counters. With a shared counter, N workers each seeing one empty
|
||||
// response would inflate the counter to N and trigger an unnecessarily long
|
||||
// backoff. With per-worker state, each worker only sees its own count.
|
||||
func TestPoller_PerWorkerCounters(t *testing.T) {
|
||||
// TestPoller_WorkerStateCounters verifies that workerState correctly tracks
|
||||
// consecutive empty responses independently per state instance, and that
|
||||
// fetchTask increments only the relevant counter.
|
||||
func TestPoller_WorkerStateCounters(t *testing.T) {
|
||||
client := mocks.NewClient(t)
|
||||
client.On("FetchTask", mock.Anything, mock.Anything).Return(
|
||||
func(_ context.Context, _ *connect_go.Request[runnerv1.FetchTaskRequest]) (*connect_go.Response[runnerv1.FetchTaskResponse], error) {
|
||||
@@ -77,8 +76,8 @@ func TestPoller_FetchErrorIncrementsErrorsOnly(t *testing.T) {
|
||||
assert.Equal(t, int64(0), s.consecutiveEmpty)
|
||||
}
|
||||
|
||||
// TestPoller_CalculateInterval verifies the per-worker exponential backoff
|
||||
// math is correctly driven by the worker's own counters.
|
||||
// TestPoller_CalculateInterval verifies the exponential backoff math is
|
||||
// correctly driven by the workerState counters.
|
||||
func TestPoller_CalculateInterval(t *testing.T) {
|
||||
cfg, err := config.LoadDefault("")
|
||||
require.NoError(t, err)
|
||||
|
||||
Reference in New Issue
Block a user