package main import ( "context" ) // heldKey carries the nodes this call already holds, so an act that holds a node and then sends // through sendTo does not wait on itself. type heldKey struct{} // holdNodes holds the named nodes for composing and sending their declarations (novox/hq ADR // 0100), skipping any the context already holds, and returns a context that says it holds them. // Release gives back only what this call took. func holdNodes(ctx context.Context, open *stores, names []string) (context.Context, func(), error) { already, _ := ctx.Value(heldKey{}).(map[string]bool) var take []string for _, n := range names { if !already[n] { take = append(take, n) } } if len(take) == 0 { return ctx, func() {}, nil } release, err := open.inventory.HoldNodes(ctx, take) if err != nil { return ctx, nil, err } held := map[string]bool{} for n := range already { held[n] = true } for _, n := range take { held[n] = true } return context.WithValue(ctx, heldKey{}, held), release, nil }