三个常见场景怎么写

下面三种形状反复出现。每一段都完整到可以贴进项目里再改。

本页目录

下面的例子省掉了 createOrder、download 这类辅助函数,要看的是流程的形状。

事件和超时赛跑

三十分钟内没付款就关单。难的从来不是定时器,是支付和超时会撞上:拆成两个流程互相取消,这场竞态得你自己赢。这里胜负由一次原子操作定死,29:59.9 落地的那笔钱要么被采纳、要么被拒,不会两边都成立。

tick.Flow("order/close", func(ctx *gotick.Context) {    orderId, _ := ctx.MetaData("order_id")     gotick.Task(ctx, "create-order", func(c *gotick.TaskContext) error {        return orders.Create(c, orderId)    })     paid, ok := gotick.WaitForSignal[Payment](ctx, "paid",        gotick.WithSignalTimeout(30*time.Minute))     if !ok {        gotick.Task(ctx, "close-order", func(c *gotick.TaskContext) error {            return orders.Close(c, orderId)        })        return    }     gotick.Task(ctx, "ship", func(c *gotick.TaskContext) error {        return shipping.Send(c, orderId, paid.TradeNo)    })})

散开,再收回来

下载一批文件,最多四个同时进行。Array 记住列表,每一遍对「要遍历什么」的答案都一样。AsyncArray 把列表展开成并行步骤,Wait 等它们做完。每个元素有自己的状态,重启之后只接着做没做完的那些。

tick.Flow("media/convert", func(ctx *gotick.Context) {    dir, _ := ctx.MetaData("dir")     files := gotick.Array(ctx, "list", func(c *gotick.TaskContext) ([]string, error) {        return storage.List(c, dir)    })     fs := gotick.AsyncArray(ctx, "convert", files,        func(c *gotick.TaskContext, name string, i int) (string, error) {            return ffmpeg.Convert(c, name)        })     gotick.Wait(ctx, 4, fs...)     gotick.Task(ctx, "publish", func(c *gotick.TaskContext) error {        out := make([]string, 0, len(fs))        for _, f := range fs {            out = append(out, f.(*gotick.FutureT[string]).Value())        }        return catalog.Publish(c, dir, out)    })})

只有最后一次改动算数

用户一分钟内改了同一份文档十次,每次都触发一轮很贵的重新生成,但只有最后一次的结果会被人看到。用文档 ID 给流程做 key,前九次自己就取消了,不用再为没人看的结果付钱。

tick.Flow("doc/preview", func(ctx *gotick.Context) {    docId, _ := ctx.MetaData("doc_id")     // expensive, and only the newest result will ever be looked at    url := gotick.Memo(ctx, "render", func() (string, error) {        return renderer.Build(docId)    })     gotick.Task(ctx, "attach", func(c *gotick.TaskContext) error {        return docs.SetPreview(c, docId, url)    })}) // in the save handler — ten edits, nine of them canceled automaticallytick.Trigger(ctx, "doc/preview", gotick.MetaData{"doc_id": docId},    gotick.WithKey(docId))

更多能直接跑的例子在仓库的 example 目录里,包括上面这个关单的例子,接上真的 Redis 几秒钟就能看到结果。 example/

Render diagnostics