channel

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Oct 11, 2026 License: AGPL-3.0 Imports: 15 Imported by: 0

Documentation

Overview

Package channel 提供上游渠道的建模与 HTTP 客户端:基址拼接、鉴权样式、超时、 重试与 SSE 读写。

渠道只负责「怎么把一段字节送到上游、怎么把上游的字节读回来」,不解析协议内容: 方言之间的转换在 relay 包。

Index

Constants

View Source
const (
	// StyleBearer 用 Authorization: Bearer <key>。
	StyleBearer = "bearer"
	// StyleAPIKey 用 x-api-key: <key>。
	StyleAPIKey = "x-api-key"
	// StyleQuery 把 key 放在查询参数上。
	StyleQuery = "query"
	// StyleCustom 用指定名字的请求头。
	StyleCustom = "custom"
	// StyleNone 不鉴权,用于指向本地假上游或已在内网放行的上游。
	StyleNone = "none"
)

鉴权样式的合法取值。

View Source
const DefaultMaxEventBytes = 8 << 20

DefaultMaxEventBytes 是单条 SSE 事件负载的默认上限。上游返回超长事件时按错误 处理,避免无上限地吃内存。

View Source
const DefaultMaxRetryAfter = 120 * time.Second

DefaultMaxRetryAfter 是上游 Retry-After 上限的默认值。取值对齐 openai-python 的 MAX_RETRY_AFTER_DELAY:超过它就不再等待重试,交给候选切换。

View Source
const DefaultTimeout = 120 * time.Second

DefaultTimeout 是未指定超时时的取值。

View Source
const MaxRetries = 10

MaxRetries 是重试次数的上限。转发是同步路径,重试次数乘以超时会直接变成 客户端等待时长,因此这里给一个上界而不是放任配置。

Variables

View Source
var ErrEventTooLarge = errors.New("channel: 事件负载超过上限")

ErrEventTooLarge 表示单条事件超过上限。

View Source
var ErrMissingCredential = errors.New("channel: 凭据环境变量未设置")

ErrMissingCredential 表示凭据环境变量未设置。

Functions

func CopyRaw

func CopyRaw(dst io.Writer, src io.Reader, flush func()) (int64, error)

CopyRaw 把上游流逐段搬给下游,不做解析,保留原始字节。返回搬运的字节数。

flushEvery 为每次刷新前累计的字节阈值,0 表示每段都刷新。同方言转发走这条路, 未建模字段因此逐字节保留。

func FailoverStatus added in v0.7.0

func FailoverStatus(status int) bool

FailoverStatus 报告状态码是否属于内置的换候选集合。同样只是默认值, 实际判据看 Client.ShouldFailover。

func RetryableStatus added in v0.7.0

func RetryableStatus(status int) bool

RetryableStatus 报告状态码是否属于内置的渠道内重试集合。

它是渠道级生效集合的默认值,不是某个渠道的实际判据:实际判据看 Client.ShouldRetry,因为配置可以覆盖。

Types

type Auth

type Auth struct {
	// Style 取 bearer、x-api-key、query、custom 或 none。
	Style string
	// KeyEnv 是凭据所在的环境变量名。凭据只在创建客户端时从进程环境读一次。
	KeyEnv string
	// Header 是 Style 为 custom 时的请求头名。
	Header string
	// Query 是 Style 为 query 时的查询参数名。
	Query string
}

Auth 是渠道的鉴权方式。

func (Auth) Validate

func (a Auth) Validate() error

Validate 校验鉴权描述。

type Backoff added in v0.7.0

type Backoff struct {
	// Base 是第一次重试前的等待时长,第 n 次重试等待 base × 2^(n-1)。
	Base time.Duration
	// Max 是指数退避的上限。
	Max time.Duration
	// MaxRetryAfter 是上游 Retry-After 的上限。上游要求的等待超过它时不再重试,
	// 直接交给候选切换;不缩短成上限再重试。
	MaxRetryAfter time.Duration
}

Backoff 是渠道内重试的退避参数。三个字段都可选,零值按内置常量处理, 因此不写这一节时的行为与逐条写死常量的版本相同。

type Client

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

Client 是一个渠道的 HTTP 客户端。可以并发使用。

func NewClient

func NewClient(spec Spec) (*Client, error)

NewClient 创建渠道客户端。凭据在此时从进程环境读一次,读不到直接报错。

func (*Client) Dialect

func (c *Client) Dialect() dialect.Name

Dialect 返回上游方言。

func (*Client) Name

func (c *Client) Name() string

Name 返回渠道名。

func (*Client) Send

func (c *Client) Send(ctx context.Context, req Request) (*http.Response, error)

Send 发送请求并返回响应。响应体由调用方关闭。

重试只覆盖「请求没成功建立」与「上游返回可重试状态」两类情况:连接错误、 408、429、5xx。非流式请求会带上整体超时,流式请求不加,靠 ResponseHeaderTimeout 与调用方的 context 控制。

渠道内重试的等待取指数退避与上游 Retry-After 的较大者;429 与 503 给出的 Retry-After 超过上限时不再重试,把响应原样交还给调用方,由后者决定换候选。

func (*Client) ShouldFailover added in v0.7.0

func (c *Client) ShouldFailover(status int) bool

ShouldFailover 报告这个渠道返回该状态码时是否值得换下一条候选。

func (*Client) ShouldRetry added in v0.7.0

func (c *Client) ShouldRetry(status int) bool

ShouldRetry 报告这个渠道内是否会对该状态码原地重试。

func (*Client) Spec

func (c *Client) Spec() Spec

Spec 返回渠道描述。

type Event

type Event struct {
	// Name 是 event 字段,缺省为空。
	Name string
	// Data 是 data 字段拼接后的内容,末尾换行已去掉。
	Data []byte
}

Event 是一条 SSE 事件。

type Reader

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

Reader 逐个读出 SSE 事件。

func NewReader

func NewReader(reader io.Reader) *Reader

NewReader 创建事件阅读器。

func (*Reader) Next

func (r *Reader) Next() (Event, error)

Next 返回下一条事件。流结束时返回 io.EOF。

解析遵循 SSE 的常用子集:忽略注释行与未知字段;data 行按行拼接,行间补 \n; 空行分发事件;`data: [DONE]` 之类的结束标记原样返回,由调用方判断。

func (*Reader) SetMaxEventBytes

func (r *Reader) SetMaxEventBytes(limit int)

SetMaxEventBytes 调整单条事件上限,非正数表示用默认值。

type Request

type Request struct {
	// Dialect 覆盖渠道的默认方言,用于同一条渠道上按路由切换协议。
	// 为空时用渠道自己的方言。覆盖生效时渠道的 Path 不参与拼接,
	// 因为那个值是按渠道方言写的。
	Dialect dialect.Name
	// Method 是 HTTP 方法,为空时用 POST。
	Method string
	// Model 是需要写进 URL 路径的模型名,只有 Gemini 用得到。
	Model string
	// Stream 决定取流式端点还是非流式端点,只有 Gemini 用得到。
	Stream bool
	// Body 是请求体,会被完整缓存在内存里,因此可以重试。
	Body []byte
	// Header 是请求级请求头,同名时覆盖 Spec.Headers 里的值。
	//
	// 覆盖是请求级比渠道级更具体的结果:同一个头只发一条,不会两条并存。
	// 渠道的鉴权头不在此列,它在最后按 Auth 写入。
	Header http.Header
	// OnRetry 在每次渠道内重试之前调用,为 nil 时什么也不做。它在调用方的
	// goroutine 上同步执行,channel 不加锁也不缓存:重试是这次调用的事实,
	// 交给调用方决定怎么记账。
	OnRetry func(RetryInfo)
}

Request 是一次上游调用。

type RetryInfo added in v0.7.0

type RetryInfo struct {
	// Attempt 是第几次重试,从 1 开始。第一次请求不算重试。
	Attempt int
	// Status 是触发这次重试的上游状态码。请求没建立时是 0。
	Status int
	// Wait 是这次重试之前等待的时长,取指数退避与上游 Retry-After 的较大者。
	Wait time.Duration
}

RetryInfo 是一次渠道内重试的事实。

type Set

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

Set 是按名字索引的渠道客户端集合。

func NewSet

func NewSet(specs []Spec) (*Set, error)

NewSet 按顺序创建渠道客户端集合。任一渠道不合法或凭据缺失都会失败。

func (*Set) Get

func (s *Set) Get(name string) (*Client, bool)

Get 按名字取客户端。

func (*Set) Len

func (s *Set) Len() int

Len 返回渠道数量。

func (*Set) Names

func (s *Set) Names() []string

Names 按创建顺序返回渠道名。

type Spec

type Spec struct {
	Name string
	// Dialect 是上游说话用的方言。
	Dialect dialect.Name
	// BaseURL 是渠道根地址,例如 https://api.openai.com。
	BaseURL string
	// Path 覆盖方言的默认上游路径。BaseURL 已带路径时(例如
	// https://openrouter.ai/api/v1)必须显式给出,取值从该路径之后算起。
	// Gemini 的路径含模型名,不允许覆盖。
	Path string
	// Auth 是鉴权方式。
	Auth Auth
	// Timeout 是单次请求的整体超时。为 0 时用 DefaultTimeout。
	Timeout time.Duration
	// MaxRetries 是失败后的重试次数,0 表示不重试。
	MaxRetries int
	// Headers 是附加到每个请求上的头。
	Headers map[string]string
	// Backoff 是渠道内重试的退避参数,零值字段按内置常量处理。
	Backoff Backoff
	// RetryStatuses 是渠道内重试的状态码集合,由装配层从全局的重试配置填入。
	// 为空时用包级 RetryableStatus 那个内置集合。
	RetryStatuses []int
	// FailoverStatuses 是换下一条候选的状态码集合,只有 server 读它。为空时用
	// 包级 FailoverStatus 那个内置集合;渠道级配置可以覆盖它。
	FailoverStatuses []int
}

Spec 是一个渠道的完整描述。

func (Spec) Validate

func (s Spec) Validate() error

Validate 校验渠道描述。

type Writer

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

Writer 按 SSE 格式写出事件,并在每次写出后刷新。

func NewWriter

func NewWriter(writer io.Writer) *Writer

NewWriter 创建事件写出器。底层实现 http.Flusher 时会自动刷新。

func (*Writer) Flush

func (w *Writer) Flush() error

Flush 把缓冲写到底层并调用其 Flush。

func (*Writer) Write

func (w *Writer) Write(event Event) error

Write 写出一条事件并刷新。

func (*Writer) WriteRaw

func (w *Writer) WriteRaw(data []byte) error

WriteRaw 原样写出一行 data 字段(不拆行),用于 [DONE] 之类的标记。

Jump to

Keyboard shortcuts

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