源码索引 / CURRENT IMPLEMENTATION
learning/go-patterns/stages/07-cancel-join/quote.go
57 行 · 点击行号可定位;函数链接随声明位置更新,不手填行号。
跳到函数 / 声明
package main
import (
"context"
"errors"
"fmt"
)
var ErrUnknownItem = errors.New("unknown item")
type Price struct {
Item string
Cents int
}
type PriceSource interface {
Lookup(context.Context, string) (Price, error)
}
type Catalog map[string]int
func (c Catalog) Lookup(ctx context.Context, item string) (Price, error) {
if err := ctx.Err(); err != nil {
return Price{}, err
}
cents, ok := c[item]
if !ok {
return Price{}, fmt.Errorf("%w: %q", ErrUnknownItem, item)
}
return Price{Item: item, Cents: cents}, nil
}
type Service struct{ source PriceSource }
func NewService(source PriceSource) Service { return Service{source: source} }
func (s Service) Quote(ctx context.Context, item string) (Price, error) {
price, err := s.source.Lookup(ctx, item)
if err != nil {
return Price{}, err
}
shipping, err := s.source.Lookup(ctx, "shipping")
if err != nil {
return Price{}, err
}
return Price{Item: item, Cents: price.Cents + shipping.Cents}, nil
}
func (s Service) QuoteMany(ctx context.Context, items []string, limit int) ([]Price, error) {
quotes := make([]Price, len(items))
tasks := make([]Task, len(items))
for i, item := range items {
tasks[i] = func(taskCtx context.Context) (string, error) {
quote, err := s.Quote(taskCtx, item)
quotes[i] = quote
return "", err
}
}
_, err := RunFailFast(ctx, tasks, limit)
return quotes, err
}