Skip to content

Commit 398f033

Browse files
anjorparkan
andauthored
Simplify create-batch: replace --replication with repeatable --deal-type (#652)
## Summary - Replace `--replication dealType=count` flag with simpler repeatable `--deal-type` flag (market, pdp, ddo) on `create-batch` - Per-provider differentiation is expressed by running separate `create-batch` commands with different `--group` labels - Bump go-synapse to latest (`v0.0.0-20260326143334-8c86c7fc3b17`) - Update CLI reference docs and guides to match Per discussion on #651 — this is a simpler UX that avoids encoding counts in a single invocation while preserving the cross-product semantics. ## Test plan - [x] `go build ./...` — compiles clean - [x] `go vet ./...` — no issues - [x] `go test ./handler/deal/schedule/...` — passes --------- Co-authored-by: Arkadiy Kukarkin <parkan@gmail.com>
1 parent 8257b36 commit 398f033

6 files changed

Lines changed: 65 additions & 57 deletions

File tree

cmd/deal/schedule/create_batch.go

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
package schedule
22

33
import (
4-
"fmt"
54
"slices"
6-
"strconv"
7-
"strings"
85

96
"github.com/cockroachdb/errors"
107
"github.com/data-preservation-programs/singularity/cmd/cliutil"
@@ -18,14 +15,22 @@ import (
1815
var CreateBatchCmd = &cli.Command{
1916
Name: "create-batch",
2017
Usage: "Create the cross-product of schedules for multiple preparations and providers",
21-
Description: `Create all schedules for preparations x providers x replication policy.
18+
Description: `Create all schedules for preparations x providers x deal types.
2219
2320
Examples:
21+
# Cold DDO copies to 2 providers
2422
singularity deal schedule create-batch \
25-
--group dataset-a \
23+
--group dataset-a-cold \
2624
--preparation prep-a --preparation prep-b \
2725
--provider f01000 --provider f02000 \
28-
--replication market=1 --replication pdp=1
26+
--deal-type ddo
27+
28+
# Warm + cold to 1 provider
29+
singularity deal schedule create-batch \
30+
--group dataset-a-warm \
31+
--preparation prep-a \
32+
--provider f03000 \
33+
--deal-type ddo --deal-type pdp
2934
`,
3035
Flags: append([]cli.Flag{
3136
&cli.StringSliceFlag{
@@ -39,10 +44,9 @@ Examples:
3944
Required: true,
4045
},
4146
&cli.StringSliceFlag{
42-
Name: "replication",
43-
Category: "Batching",
44-
Usage: "Replication policy entry in dealType=count form, e.g. market=1 or pdp=2. Repeat this flag.",
45-
Value: cli.NewStringSlice(fmt.Sprintf("%s=1", model.DealTypeMarket)),
47+
Name: "deal-type",
48+
Usage: "Deal types to create schedules for: market, pdp, or ddo. Repeat for multiple types.",
49+
Value: cli.NewStringSlice(string(model.DealTypeMarket)),
4650
},
4751
}, scheduleCreateFlags(false)...),
4852
Action: func(c *cli.Context) error {
@@ -59,9 +63,9 @@ Examples:
5963
return errors.New("at least one provider is required")
6064
}
6165

62-
replicationPolicy, err := parseReplicationPolicy(c.StringSlice("replication"))
66+
dealTypes, err := parseDealTypes(c.StringSlice("deal-type"))
6367
if err != nil {
64-
return errors.WithStack(err)
68+
return err
6569
}
6670

6771
db, closer, err := database.OpenFromCLI(c)
@@ -76,10 +80,10 @@ Examples:
7680
}
7781

7882
lotusClient := util.NewLotusClient(c.String("lotus-api"), c.String("lotus-token"))
79-
created := make([]model.Schedule, 0, len(preparations)*len(providers)*len(replicationPolicy))
83+
created := make([]model.Schedule, 0, len(preparations)*len(dealTypes)*len(providers))
8084

8185
for _, preparation := range preparations {
82-
for _, dealType := range replicationPolicy {
86+
for _, dealType := range dealTypes {
8387
for _, provider := range providers {
8488
request := createRequest(c, preparation, provider, string(dealType), allowedPieceCIDs)
8589
schedule, err := handlerschedule.Default.CreateHandler(c.Context, db, lotusClient, request)
@@ -97,28 +101,17 @@ Examples:
97101
},
98102
}
99103

100-
func parseReplicationPolicy(values []string) ([]model.DealType, error) {
101-
policy := make([]model.DealType, 0)
102-
for _, value := range values {
103-
parts := strings.SplitN(strings.TrimSpace(value), "=", 2)
104-
if len(parts) != 2 {
105-
return nil, errors.Newf("invalid replication policy entry %q: expected dealType=count", value)
106-
}
107-
108-
dealType := model.DealType(strings.TrimSpace(parts[0]))
109-
if !slices.Contains(model.DealTypes, dealType) {
110-
return nil, errors.Newf("invalid replication deal type %q", dealType)
111-
}
112-
113-
count, err := strconv.Atoi(strings.TrimSpace(parts[1]))
114-
if err != nil || count < 1 {
115-
return nil, errors.Newf("invalid replication count %q", parts[1])
116-
}
117-
118-
for i := 0; i < count; i++ {
119-
policy = append(policy, dealType)
104+
func parseDealTypes(values []string) ([]model.DealType, error) {
105+
dealTypes := make([]model.DealType, 0, len(values))
106+
for _, v := range values {
107+
dt := model.DealType(v)
108+
if !slices.Contains(model.DealTypes, dt) {
109+
return nil, errors.Newf("invalid deal type %q: must be one of market, pdp, ddo", v)
120110
}
111+
dealTypes = append(dealTypes, dt)
121112
}
122-
123-
return policy, nil
113+
if len(dealTypes) == 0 {
114+
return nil, errors.New("at least one deal type is required")
115+
}
116+
return dealTypes, nil
124117
}

docs/en/cli-reference/deal/schedule/create-batch.md

Lines changed: 12 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/en/deal-making/create-a-deal-schedule.md

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,25 +45,35 @@ singularity deal schedule create -h
4545

4646
## Batch schedule creation
4747

48-
When you need to replicate multiple preparations across multiple storage providers with a defined replication policy, use `create-batch` to generate all schedules in one command:
48+
When you need to replicate multiple preparations across multiple storage providers, use `create-batch` to generate all schedules in one command:
4949

5050
```sh
51+
# Cold DDO copies to 2 providers
5152
singularity deal schedule create-batch \
52-
--group my-dataset \
53+
--group dataset-a-cold \
5354
--preparation prep-a --preparation prep-b \
5455
--provider f01000 --provider f02000 \
55-
--replication market=1 --replication pdp=1
56+
--deal-type ddo
57+
58+
# Warm + cold to 1 provider
59+
singularity deal schedule create-batch \
60+
--group dataset-a-warm \
61+
--preparation prep-a \
62+
--provider f03000 \
63+
--deal-type ddo --deal-type pdp
5664
```
5765

58-
This creates the full cross-product: for each preparation, for each deal type in the replication policy, a schedule is created for every provider. The example above produces 8 schedules (2 preparations x 2 deal types x 2 providers).
66+
This creates the full cross-product: for each preparation, for each deal type, a schedule is created for every provider. The first example produces 4 schedules (2 preparations x 1 deal type x 2 providers). The second produces 2 schedules (1 preparation x 2 deal types x 1 provider).
67+
68+
### Deal types
5969

60-
### Replication policy
70+
The `--deal-type` flag specifies which deal types to create. Repeat for multiple types:
6171

62-
The `--replication` flag specifies deal types and how many schedules of that type to create per provider per preparation:
72+
- `market` — legacy f05 market deal (default)
73+
- `pdp` — PDP (Proof of Data Possession) deal
74+
- `ddo` — DDO (Decentralized Data Onboarding) allocation
6375

64-
- `market=1` — one legacy market deal schedule
65-
- `pdp=2` — two PDP deal schedules
66-
- `ddo=1` — one DDO allocation schedule
76+
To express per-provider differentiation (e.g., some providers get cold copies only, one gets warm + cold), run separate `create-batch` commands with different groups.
6777

6878
### Group labels
6979

docs/en/topics/ddo-contract-deal-guide.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,14 +123,14 @@ Expected state flow:
123123

124124
## Batch DDO schedules
125125

126-
To schedule DDO deals across multiple preparations and providers in one command, use `create-batch` with `--replication ddo=1`:
126+
To schedule DDO deals across multiple preparations and providers in one command, use `create-batch` with `--deal-type ddo`:
127127

128128
```bash
129129
singularity deal schedule create-batch \
130130
--group my-ddo-dataset \
131131
--preparation prep-a --preparation prep-b \
132132
--provider t01000 --provider t02000 \
133-
--replication ddo=1 \
133+
--deal-type ddo \
134134
--url-template "https://downloads.example.com/piece/{PIECE_CID}.car"
135135
```
136136

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/bcicen/jstream v1.0.1
99
github.com/brianvoe/gofakeit/v6 v6.23.2
1010
github.com/cockroachdb/errors v1.11.3
11-
github.com/data-preservation-programs/go-synapse v0.0.0-20260310124115-0faeb6924d36
11+
github.com/data-preservation-programs/go-synapse v0.0.0-20260326143334-8c86c7fc3b17
1212
github.com/data-preservation-programs/table v0.0.3
1313
github.com/dustin/go-humanize v1.0.1
1414
github.com/ethereum/go-ethereum v1.14.12

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,8 @@ github.com/cronokirby/saferith v0.33.0 h1:TgoQlfsD4LIwx71+ChfRcIpjkw+RPOapDEVxa+
275275
github.com/cronokirby/saferith v0.33.0/go.mod h1:QKJhjoqUtBsXCAVEjw38mFqoi7DebT7kthcD7UzbnoA=
276276
github.com/cskr/pubsub v1.0.2 h1:vlOzMhl6PFn60gRlTQQsIfVwaPB/B/8MziK8FhEPt/0=
277277
github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis=
278-
github.com/data-preservation-programs/go-synapse v0.0.0-20260310124115-0faeb6924d36 h1:NJ1jwnGQ+IIWMIKgfatmXVjYIH3krCV4fO/29nED6BI=
279-
github.com/data-preservation-programs/go-synapse v0.0.0-20260310124115-0faeb6924d36/go.mod h1:qgzPsiGWjTPT/oACA6Uj1+WsASwsYFW/iJ8AWacJdjc=
278+
github.com/data-preservation-programs/go-synapse v0.0.0-20260326143334-8c86c7fc3b17 h1:pTOIdr5W7pHrxFaQdONxHWiCtIOgdc6zfKL82SS4xhI=
279+
github.com/data-preservation-programs/go-synapse v0.0.0-20260326143334-8c86c7fc3b17/go.mod h1:qgzPsiGWjTPT/oACA6Uj1+WsASwsYFW/iJ8AWacJdjc=
280280
github.com/data-preservation-programs/table v0.0.3 h1:hboeauxPXybE8KlMA+RjDXz/J4xaG5CAFCcxyOm8yWo=
281281
github.com/data-preservation-programs/table v0.0.3/go.mod h1:sRGP/IuuqFc/y9QfmDyb5h6Q2wrnhhnBofEOj9aDRJg=
282282
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

0 commit comments

Comments
 (0)