Add DAGService.GetLinks() method and use it in the GC and elsewhere.#3255
Add DAGService.GetLinks() method and use it in the GC and elsewhere.#3255whyrusleeping merged 3 commits intomasterfrom
Conversation
|
Part of #2634. |
439da7c to
0c0959a
Compare
|
It doesnt appear that the linkservice interface has anything that implements it, and doesnt appear to be used anywhere |
|
Right. It doesn't have a use yet outside of the filestore. This commit has an implementation 5a73226. |
|
@whyrusleeping, if #2634 is going to get merged within a reasonable amount of time, I am okay with this P.R. not getting merged at the same time as #2634. I mainly separated it out for easier reviewing. |
|
@kevina I think that we should change the linkservice interface so that the existing dagservice implements it. That way any thing that just needs a link service can still have the dag service passed to it. And any place that needs both should just have the dagservice passed in. Then, for the filestore, we can make a small wrapper around the current dagservice code that overrides the GetLinks method to use the filestore backing instead. That way, it makes it easy for us to do other things later, like plug in a graph database to help resolve links. |
|
So what i'm getting at here, is that we want the linkservice and the dagservice to ideally be exposed via the same object. Where the linkservice interface is just a limited subset of the dagservices interface. With them separate, a few things start to feel weird. I would never want to call So for the purpose of this PR, we should just be adding the linkservice interface with type FancyDagServiceWithLinkMagic struct {
DAGService
linkStuff *linkResolver
}
func (a *FancyDagServiceWithLinkMagic) GetLinks(....) (Link, error) {
return a.linkStuff.GetLinks(...)
}And upon node construction, use that object as the nodes |
|
@whyrusleeping @Kubuxu I just pushed a commit that implemented what we seamed to agree on over IRC. |
whyrusleeping
left a comment
There was a problem hiding this comment.
I'm still not sold on the GetOffline thing. I think that its probably okay to just expect the user to pass the right thing in. I get the appeal of having the type system check that for us, but i think it might be cluttering the interfaces a bit too much.
cc @Kubuxu @diasdavid @jbenet for their thoughts as well
| return node.Links, nil | ||
| } | ||
|
|
||
| func (n *dagService) GetOfflineLinkService() LinkService { |
There was a problem hiding this comment.
I think this can be moved to the main DAGService interface. There are many situations where we would want to use this to get an offline dagservice.
There was a problem hiding this comment.
Look at the return type.
There was a problem hiding this comment.
Right, but the actual implementation is returning an offline DAGService, which is something that we would want to have available.
I'm thinking that when we need an offline linkservice, we could call dag.GetOffline() (which would return a DAGService) and then simply pass that into the function requiring the offline linkservice.
There was a problem hiding this comment.
I did it this way to enforce type safety. Otherwise we could be passed a LinkService and get a DAGService. If you really don't like that I can change it.
There was a problem hiding this comment.
Type safety is good, lets move forward with this
merkledag/merkledag.go
Outdated
| // TODO: parallelize to avoid disk latency perf hits? | ||
| func EnumerateChildren(ctx context.Context, ds DAGService, root *Node, visit func(*cid.Cid) bool, bestEffort bool) error { | ||
| for _, lnk := range root.Links { | ||
| func EnumerateChildren(ctx context.Context, ds LinkService, links []*Link, visit func(*cid.Cid) bool, bestEffort bool) error { |
There was a problem hiding this comment.
I would prefer this just take a since *cid.Cid as its input instead of an array of links. Makes it easier to call in general.
There was a problem hiding this comment.
Okay, I will look into it.
|
|
||
| bsrv := bserv.New(bs, offline.Exchange(bs)) | ||
| ds := dag.NewDAGService(bsrv) | ||
| ls = ls.GetOfflineLinkService() |
There was a problem hiding this comment.
Ah, i see why this was on the LinkService and not the DAGService. Hrm... thats tricky.
pin/gc/gc.go
Outdated
|
|
||
| // EnumerateChildren recursively walks the dag and adds the keys to the given set | ||
| err = dag.EnumerateChildren(ctx, ds, nd, func(c *cid.Cid) bool { | ||
| // EnumerateChildren recursively walks the dag and adls the keys to the given set |
There was a problem hiding this comment.
Yes, will fix the comment.
pin/pin.go
Outdated
|
|
||
| func hasChild(ds mdag.DAGService, root *mdag.Node, child key.Key) (bool, error) { | ||
| for _, lnk := range root.Links { | ||
| func hasChild(ds mdag.LinkService, links []*mdag.Link, child key.Key) (bool, error) { |
There was a problem hiding this comment.
Should accept a *cid.Cid instead of []*mdag.Link
There was a problem hiding this comment.
Okay, will look into it.
723a743 to
b315144
Compare
| return out | ||
| } | ||
|
|
||
| func (bs *Bitswap) IsOnline() bool { |
There was a problem hiding this comment.
It doesnt look like we use this anywhere. Am i missing something or is this just dead code from a different approach?
There was a problem hiding this comment.
It is used. I added a IsOnline() method to exchange to be able to tell if the exchange is online or not.
There was a problem hiding this comment.
Ah, yeah. I missed it on my previous pass through
|
Alright, I think this looks good to me. @Kubuxu wanna give it a good look over? |
core/core.go
Outdated
| Reporter metrics.Reporter | ||
| Discovery discovery.Service | ||
| FilesRoot *mfs.Root | ||
| Peerstore pstore.Peerstore // storage for other Peer instances |
There was a problem hiding this comment.
Could you try an undo these changes? its just noise on the diff
There was a problem hiding this comment.
Yes. I was just about to re-base to clean up this diff noise. 😄
2697850 to
f0e5138
Compare
This method will use the (also new) LinkService if it is available to retrieving just the links for a MerkleDAG without necessary having to retrieve the underlying block. For now the main benefit is that the pinner will not break when a block becomes invalid due to a change in the backing file. This is possible because the metadata for a block (that includes the Links) is stored separately and thus always available even if the backing file changes. License: MIT Signed-off-by: Kevin Atkinson <k@kevina.org>
e491d52 to
3899194
Compare
Instead make LinkService a part of DAGService. The LinkService is now simply an interface that DAGService implements. Also provide a GetOfflineLinkService() method that the GC uses to get an offline instance. License: MIT Signed-off-by: Kevin Atkinson <k@kevina.org>
…g.Link Author: Kevin Atkinson <k@kevina.org> Fix EnumerateChildren & hasChild to take a *cid.Cid instead of []*mdag.Link Author: Jeromy Johnson <why@ipfs.io> make FetchGraph use a cid pin: fix TestPinRecursiveFail License: MIT Signed-off-by: Jeromy <why@ipfs.io> License: MIT Signed-off-by: Kevin Atkinson <k@kevina.org>
baad64b to
721df36
Compare
|
Just rebased on master and assuming the tests pass this should be good to go. @Kubuxu what do you think? |
This method will use the (also new) LinkService if it is available to
retrieving just the links for a MerkleDAG without necessary having to
retrieve the underlying block.
For now the main benefit is that the pinner will not break when a block
becomes invalid due to a change in the backing file. This is possible
because the metadata for a block (that includes the Links) is stored
separately and thus always available even if the backing file changes.
For context (and test cases) please see the original commits: 5a73226 8b396fd