Skip to content
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

Ensure that flush on the mfs root flushes its directory #4509

Merged
merged 1 commit into from
Jan 2, 2018

Conversation

whyrusleeping
Copy link
Member

During ipfs add, we periodically call flush on the mfs root to free up unused memory. Apparently Flush on the mfs root object wasnt actually calling Flush on its directory, which led to memory not actually being freed. I'm trying to think of the best way to test this.

License: MIT
Signed-off-by: Jeromy [email protected]

@ghost ghost assigned whyrusleeping Dec 20, 2017
@ghost ghost added the status/in-progress In progress label Dec 20, 2017
Stebalien
Stebalien previously approved these changes Dec 20, 2017
Copy link
Member

@Stebalien Stebalien left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Stebalien
Copy link
Member

I'm trying to think of the best way to test this.

We may want to add some general sharness tests for stuff like this. That is, upload a file, directory, large, large, small, etc. in one subprocess and repeatedly check memory usage in the other (and see if it goes above some high watermark). Unfortunately, tests like this tend to be flaky (but we could probably set the watermark high enough to avoid false positives).

@Stebalien Stebalien dismissed their stale review December 20, 2017 03:58

Why broke it :(

@Stebalien
Copy link
Member

Why broke it :(

Nevermind. I can't read.

mfs/dir.go Outdated
return d.getNode(false)
}

func (d *Directory) getNode(clear bool) (node.Node, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There has to be a cleaner way to do this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, i'm thinking about it. Its pretty obnoxious right now...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That cross my mind also, but I didn't find it objectionable enough to comment. :)

Copy link
Contributor

@kevina kevina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code changes LGTM, but I don't understand the code enough to be sure the change is doing what it is suppose to.

@whyrusleeping
Copy link
Member Author

So, while this fixes the memory leak problem, it does bring up another interesting issue. We have the potential for someone to hold a stale reference to a directory, after it has been removed.

@whyrusleeping
Copy link
Member Author

One thing we could do for now is have a different call that we only use in the add code since we know we won't run into any of these stale reference problems.

@whyrusleeping
Copy link
Member Author

There... thats a slightly better solution that doesnt introduce weirdness around the directory references.

In any case though, the mfs directory thing needs work. Otherwise any use of mfs will not clear out its cache.

// them to be garbage collected.
// CAUTION: Take care not to ever call this while holding a reference to any
// child directories. Those directories will be bad references and using them
// may have unintended racy side effects.
Copy link
Member

@Stebalien Stebalien Dec 20, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exactly do you mean here? How will removing these from the map lead to race conditions?

I think what's throwing me is the term "cache". Is it a write cache? A read cache?

Answered offline. Basically, we could have open file descriptors and we'll lose updates to these files if we remove the references to them from the cache.

mfs/system.go Outdated
}

for _, name := range names {
dir.Uncache(name)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of listing then uncaching, can we just uncache all cached names? That ListNames call could get expensive.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifically, with sharded directories.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, youre right. This will go through all names, even if they arent cached.

return fmt.Errorf("invalid mfs structure, root should be a directory")
}

if err := dir.Flush(); err != nil {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if we concurrently modify this directory? Can we end up uncaching non-flushed entries? Is that an issue?

Should we have a single FlushAndUncache() method?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats basically the purpose of this method. In my comment i make it explicit that you shouldnt use this method concurrently with any other operations since there are deeper issues that could potentially happen.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. I'm working on improving this situation, FYI.

License: MIT
Signed-off-by: Jeromy <[email protected]>
@whyrusleeping
Copy link
Member Author

@Stebalien fixed the 'iterate over every single child' issue.

Copy link
Member

@Stebalien Stebalien left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@whyrusleeping whyrusleeping merged commit 1a0d6ec into master Jan 2, 2018
@whyrusleeping whyrusleeping deleted the fix/mfs-flush-free-mem branch January 2, 2018 19:41
@ghost ghost removed the status/in-progress In progress label Jan 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants