-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
fix: Provide according to Reprovider.Strategy #10886
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This updates boxo to this PR ipfs/boxo#976, which decentralizes the providing responsibilities. Then it perfoms the necessary changes in Kubo, which consist in initializing the Pinner, MFS and the blockstore with the provider.System. Since the provider.System is created first, the reproviding KeyChanFunc is set later when we can create it.
dc44336
to
72a97c7
Compare
Rather than fx.Provide(). Since no one was needing the strategy for anything, it was not getting called, and not getting set in the reprovider.
This comment was marked as outdated.
This comment was marked as outdated.
This commit ensure that added blocks get provided with "pinned" strategy. Normally, blocks would get provided at the blockstore or pinner facility, but when adding with "pinned" strategy, the blockstore does not provide, and the pinner does not traverse the DAG so we need to provide directly from the Adder. This is resolved by wrapping the DAGService in a "providingDAGService" which provides every added block, when using the "pinned" strategy. There are alternatives like wiring a provider in coreunix but this seems simple enough and follows existing style as the DAGService is already wrapped as a Syncer. CoreAPI also overwrote the provider into a NoopProvider when using --offline. However, we have strategies to follow and it did not overwrite the blockstore. So --offline would provide anyways with strategy "all", and not provide with strategy "pinned". It seems reasonable to provide following the provider strategy when the node is online, regardless of the client flag. Otherwise we can change it later by overwriting the provider and the blockstore. cli/provider tests have been fixed and made to not rely on `--offline`.
…ccording-to-strategy
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Self review and clarifications
core/coreapi/coreapi.go
Outdated
@@ -70,7 +73,8 @@ type CoreAPI struct { | |||
ipldPathResolver pathresolver.Resolver | |||
unixFSPathResolver pathresolver.Resolver | |||
|
|||
provider provider.System | |||
provider provider.System | |||
providingStrategy string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Carry the strategy so we can react on it when adding content.
if err := api.provider.Provide(ctx, dagNode.Cid(), true); err != nil { | ||
return err | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously, at the end of the Pin process, coreapi would trigger a Provide for the root CID (regardless of prividing strategy).
We now provide according to strategy, and this does not need to happen here (happens in the pinner).
core/coreapi/unixfs.go
Outdated
var dserv ipld.DAGService = merkledag.NewDAGService(bserv) | ||
|
||
// wrap the DAGService in a providingDAG service which provides every block written. | ||
// note about strategies: | ||
// - "all"/"flat" gets handled directly at the blockstore so no need to provide | ||
// - "roots" gets handled in the pinner | ||
// - "mfs" gets handled in mfs | ||
// We need to provide the "pinned" cases only. Added blocks are not | ||
// going to be provided by the blockstore (wrong strategy for that), | ||
// nor by the pinner (it does not traverse the pinned DAG). | ||
if settings.Pin && !settings.OnlyHash && | ||
(api.providingStrategy == "pinned" || api.providingStrategy == "pinned+mfs") { | ||
dserv = &providingDagService{dserv, api.provider} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per the comment, we need to ensure we provide blocks while Adding with the "pinned" strategy as this cannot happen in the Pinner (it doesn't traverse the DAG itself). For that, we wrap the DagService.
@@ -183,7 +200,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options | |||
if err != nil { | |||
return path.ImmutablePath{}, err | |||
} | |||
mr, err := mfs.NewRoot(ctx, md, emptyDirNode, nil) | |||
mr, err := mfs.NewRoot(ctx, md, emptyDirNode, nil, nil) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new nil
is the provider, which we leave disabled for MFS here. We are using a providing DAG service when needed.
Could we potentially passed a provider around and initialize MFS with it here and have it provide this way, rather than wrapping the DAGService? Potentially yes, but I'm not sure what happens with file-chunks and if MFS touches them at all. If not, I would need to wire the chunkers too etc. Overall it seemed more complex and fragile to do it that way.
core/node/provider.go
Outdated
|
||
in.Provider.SetKeyProvider(kcf) | ||
|
||
var strategyChanged bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The strategy-change detection has been moved here. No changes in code blocks below.
d1de66a
to
64d5096
Compare
Things like block/put are now provided correctly. Tests rely on those things not being provided and a manual call to "routing provide" being needed. Fix things by setting "roots" as strategy for tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See comments.
core/coreapi/unixfs.go
Outdated
@@ -126,6 +141,8 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options | |||
} | |||
} | |||
|
|||
// reminder: the dag server gets wrapped again (!) as a batching dagservice in coreunix.Adder. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where does this happen? Does this refer to where a batch is created in the dag put
command?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here:
Line 52 in 96aa052
bufferedDS := ipld.NewBufferedDAG(ctx, ds) |
There is a normal DAGService, which gets wrapped in a providing DAGService, which gets wrapped in a SyncDAGService, which gets wrapped in a Buffered DAGService.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added a comment which documents this: c8d1f73#diff-f95c7ebeb06be691a9a243030e11f7d3a1c4297086e8ebfa20ac3c7936878a32R145
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
A few comments
* more tests * work with bit flags rather than string for the strategies * fix typos
…ccording-to-strategy
just a precaution, since we don't want pinner provide to hide issues with "all" strategy
extra info from comments to #10886
did too many things, this makes it easier to understand and maintain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed some extra go comments with context from this and boxo PRs + small refactor.
Lgtm, but want to run some additional manual tests before merging.
Will post once done.
just making sure dag and block puts are wired "the same way" as add command
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @hsanjuan, this should make future changes easier to reason about. Lgtm, pushed extra docs/tests.
Ok to squash&merge, but would like you to take one final look at split I did in 3b481cd and give 👍
If no concerns my plan is to merge this by the end of this week (end of Friday 8th) to unblock other PRs that depend on latest boxo (e.g. #10851 (comment)).
Split looks good |
This updates boxo to this PR ipfs/boxo#976, which decentralizes the providing responsibilities.
Then it perfoms the necessary changes in Kubo, which consist in initializing the Pinner, MFS and the blockstore with the provider.System.
Since the provider.System is created first, the reproviding KeyChanFunc is set later when we can create it.
Aims to Close #10837