pipeline

package
v0.7.2 Latest Latest
Warning

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

Go to latest
Published: Aug 18, 2026 License: MIT Imports: 14 Imported by: 0

Documentation

Overview

Package pipeline 实现 javdb.pipeline/v1 机器协议核心:typed envelope、 严格 NDJSON/文本解码、输入分类与输出模式。

命令之间通过 NDJSON 组合:生产者按固定 schema 输出逐条 envelope,消费者按 kind 选择 id 或 ref。默认输出文本;显式 --ndjson / --json 互斥。

Index

Constants

View Source
const Schema = "javdb.pipeline/v1"

Schema 是管道信封的固定 schema。

Variables

This section is empty.

Functions

func ConsumerRef

func ConsumerRef(input Envelope) string

ConsumerRef 返回输入项的稳定引用:优先内部 id,否则 ref。

func ErrorMessage added in v0.7.2

func ErrorMessage(envelope Envelope) string

ErrorMessage 提取上游错误信封的可展示 message;缺失、null 或非字符串值 统一使用稳定回退,避免把协议数据的类型错误泄露成 fmt 的诊断占位符。

func IsKind

func IsKind(kind Kind) bool

IsKind 报告 kind 是否为稳定集合之一。

func RunBatch

func RunBatch(writer *Writer, inputs []Envelope, command string, fn BatchFunc) (failures int, outputErr error)

RunBatch 按输入顺序处理全部项:单项失败输出原位错误信封并继续,成功项不 丢失;返回失败数与输出错误。调用方在所有输出完成后按失败数决定非零退出。

func WriteMovieRowsText

func WriteMovieRowsText(w, errW io.Writer, movies []map[string]any) error

WriteMovieRowsText 用 movie 投影写出影片列表文本;空列表输出 (空列表)。

Types

type BatchFunc

type BatchFunc func(Envelope) (Envelope, error)

BatchFunc 处理一个输入项并返回输出信封;错误会转成原位错误信封。

type BatchRunner

type BatchRunner struct {
	Name string
	// Context 是本次命令调用的生命周期;未设置时使用 Background。
	Context context.Context
	// Kinds 是文本 ref 输入分配的 kind 与消费者接受的 kind。
	Kinds []Kind
	// ClientFactory 每次批量执行调用一次,返回携带默认 token 的 client。
	ClientFactory func() (*javdb.Client, error)
	// RunOne 执行单项并返回输出信封。
	RunOne func(*javdb.Client, context.Context, Envelope) (Envelope, error)
	// RunMany 执行单项并返回多个输出信封(fan-out);设置时优先于 RunOne。
	// 调用方负责在返回的信封中携带稳定 ref/id。
	RunMany func(*javdb.Client, context.Context, Envelope) ([]Envelope, error)
	// Legacy 处理单项既有路径(args 为位置参数列表)。
	Legacy func(args []string) error
	// RenderText 是 pipeline 文本/人类模式的领域投影;nil 时输出稳定 ref。
	RenderText func(io.Writer, Envelope) error
	// RenderError 是 pipeline 文本/人类模式的错误投影;nil 使用 Name 前缀。
	RenderError func(io.Writer, error) error
	// RouteTextThroughPipeline 让单项纯文本输入的非 TTY OutputText 走 Consumer。
	// 未启用时保留本地/有副作用命令的既有 Legacy 文本语义;需要稳定记录的
	// 只读命令应显式启用此选项。
	RouteTextThroughPipeline bool
	// LegacyJSON 表示 Legacy 路径已支持显式 --json 输出(保持既有 shape)。
	// 为 false 时,单项显式 --json 也走 consumer 路径(RunOne + 信封对象输出),
	// 避免本地命令(mark/config 等)在 --json 下静默输出裸文本或无输出。
	LegacyJSON bool
	// Preflight 在批处理路径开始前校验全部输入(如 download 的全量目标展开
	// 与冲突检查);返回错误时整个批处理失败,不做任何写入。
	Preflight func([]Envelope) error
	// Concurrency 控制批量执行并发度;<= 0 表示串行。
	Concurrency int
}

BatchRunner 是只读命令的管道化执行器:

  • 单项 + (TTY 文本 或 显式 --json)走 Legacy 既有路径(保持既有 shape 与可选认证/匿名重试行为)。
  • 其余情况(多项,或单项显式 --ndjson)走逐项 RunOne:单项失败原位错误 信封并继续,最终非零;批量显式 --json 输出信封数组。

管道执行保持三条不变量:输入索引决定输出顺序;RunMany 只在对应输入槽内 fan-out;错误项只产生错误信封或 stderr 诊断,不伪造成功 ref。

func (*BatchRunner) Execute

func (b *BatchRunner) Execute(streams *invocation.Streams, args []string, ndjson, json bool) error

Execute 是命令 RunE 的通用实现。

func (*BatchRunner) ExecuteWithInputs

func (b *BatchRunner) ExecuteWithInputs(streams *invocation.Streams, inputs []Envelope, mode OutputMode) error

ExecuteWithInputs 处理已收集的输入(调用方已完成分类)。输入分类一旦完成, 不再根据来源(位置参数或 stdin)改变显式 NDJSON/JSON 的 cardinality;只有 纯文本单项的 legacy 分支保留命令原有 JSON/TTY shape。

type Classification

type Classification int

Classification 是 stdin 内容的输入类别。

const (
	// ClassificationImage 表示 JPEG/PNG/WEBP 图片字节。
	ClassificationImage Classification = iota
	// ClassificationNDJSON 表示 javdb.pipeline/v1 信封流。
	ClassificationNDJSON
	// ClassificationText 表示逐行纯文本 ref。
	ClassificationText
)

func Classify

func Classify(reader *bufio.Reader) (Classification, []byte, error)

Classify 按固定顺序识别 stdin 类别:图片 magic → NDJSON → 文本。 不消费输入:图片判定只 Peek 前 12 字节;NDJSON/文本判定读取全部剩余内容。

type Consumer

type Consumer struct {
	Name string
	// Context 是本次命令调用的生命周期;未设置时使用 Background。
	Context context.Context
	// AcceptedKinds 是输入项允许的 kind;nil 表示接受任意 kind(文本 ref)。
	AcceptedKinds []Kind
	// RunOne 执行单项并返回输出信封。
	RunOne func(context.Context, Envelope) (Envelope, error)
	// RunMany 执行单项并返回多个输出信封(fan-out);设置时优先于 RunOne。
	RunMany func(context.Context, Envelope) ([]Envelope, error)
	// RenderText 输出默认的人类文本。
	RenderText func(io.Writer, Envelope) error
	// RenderError 将文本/人类模式的单项错误写到 stderr;nil 使用 Name 前缀。
	RenderError func(io.Writer, error) error
	// LegacyJSON 输出单项显式 --json 的既有 shape;nil 时输出信封对象。
	LegacyJSON func(io.Writer, Envelope) error
	// Concurrency 控制批量执行并发度;<= 0 表示串行。并发时结果按输入顺序
	// 写出,单项失败不阻塞其他项。
	Concurrency int
}

Consumer 把只读命令的单项执行包装成统一输入/输出管道:

  • 输入:位置参数或非 TTY stdin(分类:图片 magic → NDJSON → 文本)。
  • 消费者严格检查 kind,不兼容输入生成原位错误信封。
  • 输出:默认文本;显式 --ndjson/--json 互斥。
  • 显式 --json:单项走 LegacyJSON 既有 shape,多项输出信封数组。

func (*Consumer) Execute

func (c *Consumer) Execute(streams *invocation.Streams, args []string, ndjson, json bool) error

Execute 是命令 RunE 的通用实现(不消费图片;需要图片输入的调用方自行先行处理)。

func (*Consumer) RunInputs

func (c *Consumer) RunInputs(streams *invocation.Streams, inputs []Envelope, mode OutputMode) error

RunInputs 按输出模式处理已收集的输入;单项失败原位错误信封并继续。 调用方(如 search)可自行完成图片分类后复用本方法。

文本/人类模式(OutputText/OutputHuman)下:

  • 成功项:若 RenderText 已设置则调用它渲染人类/稳定文本,否则逐行 ref。
  • 失败项:错误原因写 stderr,不向 stdout 写任何内容(不伪造成功 ref)。

NDJSON/JSON 模式下:失败项原位 error 信封写入 stdout(机器契约),保持 输出顺序与单项错误可观测性。

Concurrency > 0 时批量请求并发执行,结果按输入顺序写出。 processAll 只按索引写入独立结果槽,所有 worker 完成后才进入渲染阶段, 因而 fan-out、失败信封和文本输出都不会因请求完成顺序改变协议顺序。

type Envelope

type Envelope struct {
	Schema string         `json:"schema"`
	Kind   Kind           `json:"kind"`
	Ref    string         `json:"ref,omitempty"`
	ID     string         `json:"id,omitempty"`
	Data   map[string]any `json:"data,omitempty"`
	Meta   map[string]any `json:"meta,omitempty"`
}

Envelope 是管道记录。

func CollectInputs

func CollectInputs(reader *bufio.Reader, streams *invocation.Streams, arg string, textKinds []Kind) ([]Envelope, error)

CollectInputs 统一收集输入:位置参数(单个)或非 TTY stdin 批。 位置参数与非空 stdin 同时存在是歧义错误。stdin 按固定顺序分类 (图片 magic → NDJSON → 文本);图片输入显式报错(调用方先行处理)。

func DecodeNDJSON added in v0.7.1

func DecodeNDJSON(line string) (Envelope, error)

DecodeNDJSON 严格解码一条 NDJSON 记录;拒绝非对象行、尾随数据与非法信封。

func DecodeText

func DecodeText(line string) (Envelope, error)

DecodeText 把一行纯文本解码为 ref(kind 由消费者命令决定)。

func ErrorEnvelope

func ErrorEnvelope(input Envelope, command, stage, code, message string) Envelope

ErrorEnvelope 构造原位错误信封;不含 secret。

func New

func New(kind Kind, ref, id string) Envelope

New 构造一个 schema 校验通过的信封。

func ParseBatch

func ParseBatch(content []byte, kind Kind) ([]Envelope, error)

ParseBatch 把 stdin 内容按分类解码为信封序列:

  • 输入分类固定顺序为图片 magic、NDJSON、文本(由 Classify 完成);
  • NDJSON 模式逐行严格解码,混合/非法行返回带行号的错误;
  • 文本模式逐行转 ref。

func (Envelope) Validate

func (e Envelope) Validate() error

Validate 校验信封 schema 与 kind;ref/id 至少一个存在。

func (Envelope) WithData

func (e Envelope) WithData(data map[string]any) Envelope

WithData 返回附带 data 的信封副本。

func (Envelope) WithMeta

func (e Envelope) WithMeta(meta map[string]any) Envelope

WithMeta 返回附带 meta 的信封副本。

type Kind

type Kind string

Kind 是稳定的记录类别;消费者只接受声明匹配的 kind。

const (
	KindMovie     Kind = "movie"
	KindActor     Kind = "actor"
	KindSeries    Kind = "series"
	KindMaker     Kind = "maker"
	KindDirector  Kind = "director"
	KindCode      Kind = "code"
	KindList      Kind = "list"
	KindAccount   Kind = "account"
	KindComment   Kind = "comment"
	KindMagnet    Kind = "magnet"
	KindDownload  Kind = "download"
	KindConfigKey Kind = "config_key"
	KindError     Kind = "error"
)
const KindNDJSONInput Kind = "ndjson"

KindNDJSONInput 是 ParseBatch 的哨兵:表示逐行 NDJSON 严格解码。

const KindTag Kind = "tag"

KindTag 是标签目录条目的稳定 kind(kind 集合的最小契约之外按需扩展)。

type ListProducer

type ListProducer struct {
	Name string
	// ClientFactory 每次执行调用一次。
	ClientFactory func() (*javdb.Client, error)
	// Fetch 执行并返回列表项。
	Fetch func(context.Context, *javdb.Client) ([]map[string]any, error)
	// JSON 构造显式 --json 的既有 shape 载荷。
	JSON func([]map[string]any) (map[string]any, error)
	// ErrNote 可选:输出前写 stderr 注解。
	ErrNote func(io.Writer, []map[string]any)
	// ItemKind 是信封 kind(默认 movie)。
	ItemKind Kind
	// ItemRef 提取 (ref, id)(默认 number/id)。
	ItemRef func(map[string]any) (string, string)
	// RowText 渲染人类文本行(默认 movie 投影行)。
	RowText func(io.Writer, io.Writer, []map[string]any) error
}

ListProducer 是"拉取列表"类 producer 命令的通用执行器: 不消费 stdin;默认输出人类文本;显式 --ndjson 输出逐条信封,--json 走 JSON 载荷。

func (*ListProducer) Execute

func (p *ListProducer) Execute(streams *invocation.Streams, ndjson, json bool) error

Execute 是 producer 命令 RunE 的通用实现。

type MovieListProducer

type MovieListProducer = ListProducer

MovieListProducer 是影片列表 producer 的便捷别名。

type OutputMode

type OutputMode int

OutputMode 是命令的输出格式。

const (
	// OutputAuto 表示尚未解析显式输出 flag。
	OutputAuto OutputMode = iota
	// OutputHuman 是 TTY 默认:人类可读文本,由命令的 RenderText 渲染。
	OutputHuman
	// OutputText 是非 TTY 默认:稳定记录流,一行一个 ref/URI,便于管道消费。
	OutputText
	// OutputNDJSON 强制逐条信封 NDJSON。
	OutputNDJSON
	// OutputJSON 显式 --json:单项保持命令既有形状,多项输出 JSON 数组。
	OutputJSON
)

func ResolveOutputMode

func ResolveOutputMode(flagNDJSON, flagJSON bool, outIsTerminal bool) (OutputMode, error)

ResolveOutputMode 校验互斥并解析输出模式:显式 --ndjson/--json 优先且互斥; 未显式指定时,TTY stdout 使用人类文本(OutputHuman),非 TTY stdout 使用 稳定记录流(OutputText)。测试可显式设置 OutIsTerminal 来模拟两种场景。

type Producer

type Producer struct {
	Name string
	// Produce 执行并返回输出信封序列(空切片表示无结果)。
	Produce func(context.Context) ([]Envelope, error)
	// RenderText 渲染人类文本。
	RenderText func(io.Writer, []Envelope) error
	// LegacyJSON 输出显式 --json 的既有 shape。
	LegacyJSON func(io.Writer) error
}

Producer 是无位置参数命令的输出器:不消费 stdin,默认走 Text 渲染; 显式 --ndjson 逐条输出信封,--json 走 LegacyJSON。

func (*Producer) Execute

func (p *Producer) Execute(streams *invocation.Streams, ndjson, json bool) error

Execute 是 producer 命令 RunE 的通用实现。

type Writer

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

Writer 按输出模式逐条写出信封;OutputJSON 模式在 Finish 时按 cardinality 输出(单信封对象,多信封数组)。

func NewWriter

func NewWriter(out io.Writer, mode OutputMode) *Writer

NewWriter 构造按 mode 输出的 writer。

func (*Writer) Count

func (w *Writer) Count() int

Count 返回已写入/缓冲的信封数量。

func (*Writer) Finish

func (w *Writer) Finish() error

Finish 结束输出:OutputJSON 模式按 cardinality 写出对象或数组;其余模式 无操作。

func (*Writer) Mode

func (w *Writer) Mode() OutputMode

Mode 返回解析后的输出模式。

func (*Writer) Write

func (w *Writer) Write(envelope Envelope) error

Write 写出一个信封;OutputJSON 模式先缓冲。OutputHuman 在 Writer 层面 退化为 OutputText(逐行 ref);命令级别的人类渲染由 Consumer.RenderText 或 Producer.RenderText 负责,在进入 Writer 前已完成分流。

Jump to

Keyboard shortcuts

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