Help us shape the future of Go! Take the 2026 Go Developer Survey

waitpoll

package
v3.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 9, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package waitpoll provides shared polling loops for wait-style tools.

Index

Constants

View Source
const (
	// TransferBound is how long a transfer handler waits for the move.
	TransferBound = 45 * time.Second
	// TransferInterval is the time between two reads of the moved object.
	TransferInterval = 2 * time.Second
)

The timing project.transfer and group.transfer wait with. GitLab 19.4 made both transfers asynchronous: the request answers with the object where it still is, and a background worker moves it seconds later. Both handlers read the object back until it sits where the transfer put it, and they share one timing so the two descriptions that state it stay true together.

The bound keeps the whole call, the transfer request included, below the 60 seconds a common MCP client waits for a tool call before giving up on it (the TypeScript SDK's default request timeout). A wait that ran into that timeout would hand the model a client-side failure instead of the answer that says the move is still queued, which is the one it can act on.

Variables

This section is empty.

Functions

func AnsweredAt added in v3.1.0

func AnsweredAt(resp *gl.Response) time.Time

AnsweredAt is when GitLab answered a transfer, read from the Date header of its response, so it is GitLab's clock and not this server's that a failure is dated against. It is zero when the response carries no date it can read.

func TransferFailed added in v3.1.0

func TransferFailed(ctx context.Context, client *gitlabclient.Client, target TransferTarget, answeredAt time.Time) (destination string, failed bool, err error)

TransferFailed reports whether GitLab has recorded that a transfer of target failed in the background, answering the destination the to-do item names. Since GitLab 19.4 that item is the only report of such a failure: the transfer's own answer came before the worker ran, and the object is left where it was.

An item counts only when it was created no earlier than two seconds before answeredAt, because GitLab keeps one pending item per object and a user, and an item left by an earlier failure says nothing about this transfer. The two seconds are the Date header's whole-second precision and a worker that can fail before the web node writes that header. It follows that a failure is not seen while an earlier failure's item is still pending, since GitLab adds no second one, and that nothing is seen at all when answeredAt is zero: the item could not be told apart from an older one, and no request is made. Only the first page of 100 pending items is read.

func Until added in v3.1.0

func Until[T any](ctx context.Context, opts UntilOptions[T]) (state T, landed bool, err error)

Until reads an object every Interval until Landed accepts what Read returned, and answers that state and true. It answers the zero T and false when Bound runs out first, and the caller's context error when that context ends first: a caller that went away wants no answer, whether the change landed or not.

A read that fails is not an answer and does not end the wait. The change being waited for was already accepted, so one read GitLab fails to serve (a 502 from a proxy, a timeout) says nothing about it and the next may succeed. A failure that persists runs the wait to Bound, which the caller reports as a change not yet applied, the same answer a slow worker produces.

Each read runs under the bound as well as the caller's context, so a read still in flight when the bound runs out is abandoned rather than awaited.

Types

type DurationFunc

type DurationFunc func(seconds int) time.Duration

DurationFunc converts user-facing seconds into the duration used by timers.

type Options

type Options[T any] struct {
	Request         *mcp.CallToolRequest
	IntervalSeconds int
	TimeoutSeconds  int
	FailOnError     *bool
	PollDuration    DurationFunc
	ProgressMessage func(attempt int) string
	Poll            func(context.Context) (T, error)
	Status          func(T) string
	FailureError    func(T) error
}

Options configures a polling loop for one wait-style tool.

type Result

type Result[T any] struct {
	Item        T
	WaitedFor   string
	PollCount   int
	FinalStatus string
	TimedOut    bool
}

Result reports the final item and polling metadata.

func Poll

func Poll[T any](ctx context.Context, opts Options[T]) (Result[T], error)

Poll polls until the item reaches a terminal status, the context is canceled, or the configured timeout expires.

type TransferTarget added in v3.1.0

type TransferTarget struct {
	// ID is the project's or the group's numeric id.
	ID int64
	// Group says the object is a group rather than a project.
	Group bool
}

TransferTarget names the object a transfer moves, as GitLab's to-do list is filtered by it: a project by its project_id with target type Project, and a group by its group_id with target type Namespace, the class GitLab records a group target under.

type UntilOptions added in v3.1.0

type UntilOptions[T any] struct {
	// Request carries the caller's progress token. Nil sends no progress.
	Request *mcp.CallToolRequest
	// Interval is the time before each read, the first included: the caller
	// has just been told the change was accepted, so a read at once would only
	// find it pending.
	Interval time.Duration
	// Bound is how long the whole wait may take.
	Bound time.Duration
	// Message is the progress text sent before each read.
	Message string
	// Read fetches the object's current state.
	Read func(context.Context) (T, error)
	// Landed reports whether a state Read returned is the one waited for.
	Landed func(T) bool
}

UntilOptions configures Until: how to read an object GitLab changes in the background, and how to tell that the change has landed.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL