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
handle max storage when gc is disabled #5768
Conversation
ab6a965
to
a382d3a
Compare
@kjzz Can I trouble you with a brief description of the PR please? Just a couple of sentences explaining what did you wanted to achieve and how, thanks! |
Hi @schomatis , this pr is aimed to solve the problem that when a repo size limit is configured bug gc is disabled (i.e., no --enable-gc flag has been passed), I think we should have multiple levels of warnings: 1.warning when datastore usage is at 90% you can also see the discussion in issue #5140 . |
core/coreapi/unixfs.go
Outdated
@@ -24,6 +25,10 @@ import ( | |||
mfs "gx/ipfs/QmcUXFi2Fp7oguoFT81f2poJpnb44dFkZanQhDBHMoYyG9/go-mfs" | |||
) | |||
|
|||
var ( | |||
errFullStorage = errors.New("DataStorage is full,please enable gc and restart node") |
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.
nit: add a space after the "," (same for the log errors below)
@@ -126,6 +131,23 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.File, opts ...options | |||
fileAdder.SetMfsRoot(mr) | |||
} | |||
|
|||
// Get storageMax when node is online. |
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.
Is Add
the only entry point that will make the repo grow?
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.
No. Unfortunately, this really needs to go much lower. We probably need some kind of datastore wrapper that rejects writes when the datastore is full (and calls a user-provided "free" function at N% of full).
core/coreapi/unixfs.go
Outdated
@@ -126,6 +131,23 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.File, opts ...options | |||
fileAdder.SetMfsRoot(mr) | |||
} | |||
|
|||
// Get storageMax when node is online. | |||
if fileAdder.Pin && !n.EnableGC && n.OnlineMode() { |
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.
Do we need to check for Pin
here? the file will be added anyway even if we don't pin it, right? (it can be removed later but it will make the repo grow)
@@ -126,6 +131,23 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.File, opts ...options | |||
fileAdder.SetMfsRoot(mr) | |||
} | |||
|
|||
// Get storageMax when node is online. | |||
if fileAdder.Pin && !n.EnableGC && n.OnlineMode() { | |||
storageUsage, err := n.Repo.GetStorageUsage() |
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.
Is GetStorageUsage
a faithful metric of repo size? Is it compatible with StorageMax
? (this is a naive question but I'm not familiar with the repo API)
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.
In my testing , maybe GetStorageUsage
is a faithful metric of repo size.
return nil, err | ||
} | ||
if !gc.EnableGC { | ||
log.Warningf("GC: %s", "Repo GC is disabled.") |
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.
Why do we need this warning? Is it part of the original intention of the PR?
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.
Is it part of the original intention of the PR?
We should print some warning message when the gc is disable.
You can see the comment in the issue
@@ -23,10 +23,12 @@ var ErrMaxStorageExceeded = errors.New("maximum storage limit exceeded. Try to u | |||
type GC struct { | |||
Node *core.IpfsNode | |||
Repo repo.Repo | |||
EnableGC 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.
Why do we need this second EnableGC
?
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.
Because I need to get this param in func maybeRunGC(req *cmds.Request, node *core.IpfsNode) (<-chan error, error)
.
if err != nil { | ||
return nil, err | ||
} | ||
gc.EnableGC = enableGC |
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.
Let's keep enableGC
set-value and load-value operations as close as possible, move the enableGC, _ := req.Options[enableGCKwd].(bool)
line down here if it's not used anywhere else.
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.
Because i should get this param in other function.
func maybeRunGC(req *cmds.Request, node *core.IpfsNode) (<-chan error, error) {
gc, err := initGC(req, node)
if err != nil {
return nil, err
}
if !gc.EnableGC {
log.Warningf("GC: %s", "Repo GC is disabled.")
return nil, nil
}
.........
} | ||
|
||
if cfg.Datastore.GCPeriod == "" { | ||
cfg.Datastore.GCPeriod = "1h" |
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.
Unrelated to this PR (since this was already present in the code) but could we add a warning here to notify the user the GCPeriod
wasn't set and we're using a default value of an hour?
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.
Good idea!
if err != nil { | ||
return nil, err | ||
} | ||
storPercentage := float64(storageUsage) / float64(n.StorageMax) |
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.
From gc.go
I'm seeing that StorageMax
can be left unset by the user and we'll silently assume a 10GB limit which can make this test a little brittle, a user who just doesn't care about any of this (didn't set the GC, didn't set a max capacity for the repo) will hit this error (which will even prevent it from using IPFS) without understanding what's really going on (and how to fix it).
Left several comments but the most important one to address first is #5768 (diff) (which may require a change in the approach of the PR's proposed solution). |
ping @kjzz |
Sorry @schomatis,recently I'm preparing the opening report of my graduation thesis.I will do for this on next week.Thx. |
Hey no rush, take your time, definitively concentrate on your thesis now :) |
License: MIT Signed-off-by: Kejie Zhang <601172892@qq.com>
@schomatis sorry for delay,i have update my pr.please help me review it again.Thx a lot! |
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.
Sorry for jumping in on this very late but, unfortunately, we need to handle this case at a much lower level. Ideally at the datastore level but we probably don't want to reject writes of non-blocks for any reason (will make the daemon unusable).
I believe the correct approach (for now) is to do this at the blockstore level. That is, we'll have to modify the blockstore to reject puts if RepoSize grows too much.
} | ||
|
||
// PeriodicGC create a goroutine to gc. | ||
func PeriodicGC(ctx context.Context, gc *GC) error { |
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.
At this point, this should just be a function on the GC
instance.
@@ -126,6 +131,23 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.File, opts ...options | |||
fileAdder.SetMfsRoot(mr) | |||
} | |||
|
|||
// Get storageMax when node is online. |
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.
No. Unfortunately, this really needs to go much lower. We probably need some kind of datastore wrapper that rejects writes when the datastore is full (and calls a user-provided "free" function at N% of full).
feature #5140
License: MIT
Signed-off-by: Kejie Zhang 601172892@qq.com