grpc

package
v1.6.0 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package grpc provides a gRPC client for the Spooled API.

Index

Constants

View Source
const DefaultAddress = "grpc.spooled.cloud:443"

DefaultAddress is the default gRPC server address.

Variables

This section is empty.

Functions

func Int32 added in v1.1.0

func Int32(v int32) *int32

Int32 returns a pointer to v, for the optional *int32 fields on EnqueueRequest (e.g. MaxRetries: grpc.Int32(3)).

func SetNoRetry added in v1.5.0

func SetNoRetry(req *pb.FailRequest) *pb.FailRequest

SetNoRetry makes a pb.FailRequest dead-letter the job instead of retrying it, and returns req. Use it when you build a pb.FailRequest yourself, for example to settle a job on a ProcessJobs stream; Client.Fail does the same for FailRequest.NoRetry.

The backend declares FailRequest.retry `optional bool`: omitted means retry according to the job's max_retries, false means dead-letter now. The SDK's pb.FailRequest keeps Retry a plain bool so code written against earlier releases still compiles, and proto3 never puts a plain false on the wire: `Retry: false` alone reaches the server as "omitted", and the job is retried. SetNoRetry sets Retry to false and adds retry=false (field 4, varint 0) to the message's unknown fields, which are marshaled as they are. The server reads that as an explicit false, older servers as a plain false. Calling it twice changes nothing. A nil req is returned as is.

SetNoRetry is one-way. Do not set Retry on the message afterwards: a known Retry of true is marshaled as field 4 = 1 and the unknown field 4 = 0 follows it, so two field 4 values go on the wire and the last one wins. The server still reads false, because the unknown fields are written last, but the message is then ambiguous to any reader that takes the first value. To undo it, build a new pb.FailRequest. The helper does not guard against the later assignment: nothing observes a write to Retry, and the wire result is defined (false) either way.

Types

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is the gRPC client for Spooled.

func NewClient

func NewClient(opts ClientOptions) (*Client, error)

NewClient creates a new gRPC client.

func (*Client) Close

func (c *Client) Close() error

Close closes the gRPC connection.

func (*Client) Complete

func (c *Client) Complete(ctx context.Context, req *CompleteRequest) error

Complete marks a job as completed.

func (*Client) Dequeue

func (c *Client) Dequeue(ctx context.Context, req *DequeueRequest) (*DequeueResponse, error)

Dequeue dequeues jobs for a worker.

func (*Client) DeregisterWorker

func (c *Client) DeregisterWorker(ctx context.Context, workerID string) error

DeregisterWorker deregisters a worker.

func (*Client) Enqueue

func (c *Client) Enqueue(ctx context.Context, req *EnqueueRequest) (*EnqueueResponse, error)

Enqueue enqueues a new job.

func (*Client) Fail

func (c *Client) Fail(ctx context.Context, req *FailRequest) error

Fail marks a job as failed. Unless req.NoRetry is set the job is retried with backoff until max_retries is used up, like a failure reported over REST. FailWithResponse also returns whether the job will be retried.

func (*Client) FailWithResponse added in v1.5.0

func (c *Client) FailWithResponse(ctx context.Context, req *FailRequest) (*FailResponse, error)

FailWithResponse marks a job as failed like Fail and returns the server's decision: whether the job will be retried and after what delay.

func (*Client) GetJob

func (c *Client) GetJob(ctx context.Context, jobID string) (*Job, error)

GetJob retrieves a job by ID.

func (*Client) GetQueueStats

func (c *Client) GetQueueStats(ctx context.Context, queueName string) (*QueueStats, error)

GetQueueStats retrieves queue statistics.

func (*Client) ProcessJobs

ProcessJobs opens a bidirectional stream for job processing.

Settlements on the stream are pb messages you build yourself. Each needs the dequeued job's LeaseId. To fail a job without a retry, pass its pb.FailRequest through SetNoRetry: a plain `Retry: false` is not put on the wire, and the server retries the job.

func (*Client) RegisterWorker

func (c *Client) RegisterWorker(ctx context.Context, req *RegisterWorkerRequest) (*RegisterWorkerResponse, error)

RegisterWorker registers a new worker.

func (*Client) RenewLease

func (c *Client) RenewLease(ctx context.Context, req *RenewLeaseRequest) (*RenewLeaseResponse, error)

RenewLease renews the lease on a job.

func (*Client) StreamJobs

func (c *Client) StreamJobs(ctx context.Context, queueName, workerID string) (pb.QueueService_StreamJobsClient, error)

StreamJobs opens a streaming connection to receive jobs.

func (*Client) WorkerHeartbeat

func (c *Client) WorkerHeartbeat(ctx context.Context, req *WorkerHeartbeatRequest) error

WorkerHeartbeat sends a worker heartbeat.

type ClientOptions

type ClientOptions struct {
	// Address is the gRPC server address (e.g., "grpc.spooled.cloud:443")
	Address string
	// APIKey is the API key for authentication
	APIKey string
	// UseTLS forces TLS on or off. When nil, TLS is used for port 443 (and for an
	// address with no port, which gRPC dials on 443) and plaintext is used for
	// every other port, including localhost:50051. Set it to dial a TLS
	// endpoint on another port, such as ":8443".
	UseTLS *bool
	// TLSConfig is custom TLS configuration (optional)
	TLSConfig *tls.Config
	// DialOptions are additional gRPC dial options
	DialOptions []grpc.DialOption
	// Timeout is the connection timeout
	Timeout time.Duration
}

ClientOptions configures the gRPC client.

type CompleteRequest

type CompleteRequest struct {
	JobID    string
	WorkerID string
	Result   map[string]any
	// LeaseID is the lease fencing token from the dequeued Job (Job.LeaseID).
	// It is required: the server answers a Complete without it with
	// InvalidArgument, and one that does not match the job's current lease is
	// rejected.
	LeaseID string
}

CompleteRequest is the request to complete a job.

type DequeueRequest

type DequeueRequest struct {
	QueueName        string
	WorkerID         string
	BatchSize        int32
	LeaseDurationSec int32
}

DequeueRequest is the request for dequeuing jobs.

type DequeueResponse

type DequeueResponse struct {
	Jobs []*Job
}

DequeueResponse is the response from dequeuing jobs.

type EnqueueRequest

type EnqueueRequest struct {
	QueueName      string
	Payload        map[string]any
	Priority       int32
	MaxRetries     *int32
	TimeoutSeconds *int32
	ScheduledAt    *time.Time
	IdempotencyKey string
}

EnqueueRequest is the request for enqueueing a job.

MaxRetries and TimeoutSeconds are optional pointers:

  • nil → field omitted on the wire; backend applies QUEUE_DEFAULT_*
  • non-nil → value sent (backend still maps <=0 to QUEUE_DEFAULT_*)

Explicit zero retries cannot be expressed over gRPC proto3 int32 (same as REST omit vs 0 distinction on the server).

Payload travels as a google.protobuf.Struct, so it is always a JSON object, and Struct numbers are doubles: an integer of 2^53 or more (a Discord or Snowflake ID, for example) arrives rounded. A job that a REST client created with a non-object payload (an array, string or number) is delivered over gRPC with an empty payload. Use the REST API for those payloads.

type EnqueueResponse

type EnqueueResponse struct {
	JobID   string
	Created bool
}

EnqueueResponse is the response from enqueueing a job.

type FailRequest

type FailRequest struct {
	JobID    string
	WorkerID string
	Error    string
	// Retry has no effect any more: a failed job is retried, up to the job's
	// max_retries, unless NoRetry is set.
	//
	// Deprecated: the zero value used to mean "dead-letter now" because proto3
	// cannot tell an omitted bool from false, so a Fail without Retry skipped
	// every retry. Retrying is now the default; set NoRetry to opt out.
	Retry bool
	// NoRetry dead-letters the job immediately instead of scheduling a retry.
	NoRetry bool
	// LeaseID is the lease fencing token from the dequeued Job (Job.LeaseID).
	// It is required: the server answers a Fail without it with
	// InvalidArgument, and one that does not match the job's current lease is
	// rejected.
	LeaseID string
}

FailRequest is the request to fail a job.

type FailResponse added in v1.5.0

type FailResponse struct {
	Success bool
	// WillRetry is true when the job went back to pending for another attempt,
	// false when it was dead-lettered (NoRetry, or max_retries used up).
	WillRetry bool
	// NextRetryDelaySecs is the backoff before the retry; 0 when the job was
	// dead-lettered.
	NextRetryDelaySecs int32
}

FailResponse is what the server decided for a failed job.

type Job

type Job struct {
	ID             string
	QueueName      string
	Payload        map[string]any
	Priority       int32
	RetryCount     int32
	MaxRetries     int32
	TimeoutSeconds int32
	LeaseExpiresAt *time.Time
	// LeaseID is the lease fencing token issued by the server for this
	// dequeue. Echo it back on Complete, Fail and RenewLease: the server
	// requires it there (a settlement without it fails with InvalidArgument
	// "lease_id is required for job settlement") and applies the call only to
	// the lease this worker actually holds.
	LeaseID string
}

Job represents a dequeued job.

Payload comes from a google.protobuf.Struct: a job created over REST with a non-object payload (array, string, number) arrives empty here, and integers of 2^53 or more arrive rounded. Read such jobs over REST.

type QueueStats

type QueueStats struct {
	QueueName  string
	Pending    int64
	Scheduled  int64
	Processing int64
	Completed  int64
	Failed     int64
	Deadletter int64
	Total      int64
	MaxAgeMs   int64
}

QueueStats represents queue statistics.

type RegisterWorkerRequest

type RegisterWorkerRequest struct {
	QueueName      string
	Hostname       string
	MaxConcurrency int32
	Version        string
	Metadata       map[string]string
	// WorkerID is an optional stable worker id: 1-128 characters from
	// [A-Za-z0-9._-]. Send the same id after a restart and the server updates
	// that worker instead of adding one, so a restarting worker does not count
	// twice against the plan's worker limit. Empty: the server assigns a new
	// id. An id another organization already uses fails with AlreadyExists.
	WorkerID string
}

RegisterWorkerRequest is the request to register a worker.

type RegisterWorkerResponse

type RegisterWorkerResponse struct {
	WorkerID             string
	HeartbeatIntervalSec int32
	LeaseDurationSec     int32
}

RegisterWorkerResponse is the response from registering a worker.

type RenewLeaseRequest

type RenewLeaseRequest struct {
	JobID         string
	WorkerID      string
	ExtensionSecs int32
	// LeaseID is the lease fencing token from the dequeued Job (Job.LeaseID).
	// It is required: the server answers a RenewLease without it with
	// InvalidArgument, and one that does not match the job's current lease is
	// rejected.
	LeaseID string
}

RenewLeaseRequest is the request to renew a job lease.

type RenewLeaseResponse

type RenewLeaseResponse struct {
	Success      bool
	NewExpiresAt *time.Time
}

RenewLeaseResponse is the response from renewing a lease.

type WorkerHeartbeatRequest

type WorkerHeartbeatRequest struct {
	WorkerID    string
	CurrentJobs int32
	Status      string
}

WorkerHeartbeatRequest is the request for a worker heartbeat.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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