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

performance: reduce the # of open file handles #298

Merged
merged 3 commits into from
Oct 24, 2018

Conversation

jeffdiclemente
Copy link
Member

Installing thousands of bundles within a process can cause undefined behavior if the OS open file limit has been reached. In our use case, we reached this open file limit on Windows.

In order to resolve the issue on Windows and to allow thousands of bundles to be installed into an applications, this solution will close the file handle for the bundle if it only contains a manifest file. The idea is that with only a manifest.json file, clients are unlikely to use another CppMicroServices resource API to read meta-data from the .zip file. If the resource API is used after the bundle is installed, the file will remain open until the bundle is uninstalled.

There are most likely more improvements that can be made to manage the # of file handles CppMicroServices keeps open and this is a small step towards getting to that state.

Installing thousands of bundles within a process can cause undefined behavior when the OS open file limit has been reached. 

If the bundle only contains a manifest.json, close the file after reading the manifest.json contents.
If the bundle meta-data is read again, open the file and leave it open until the bundle is uninstalled.

Signed-off-by: The Mathworks Inc <Roy.Lurie@mathworks.com>
@jeffdiclemente jeffdiclemente self-assigned this Aug 22, 2018
@jeffdiclemente jeffdiclemente requested review from saschazelzer and a team August 22, 2018 12:35
@@ -25,6 +25,7 @@

#include "miniz.h"

#include <atomic>
Copy link
Contributor

Choose a reason for hiding this comment

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

Think you don't need this anymore

@codecov-io
Copy link

codecov-io commented Aug 22, 2018

Codecov Report

Merging #298 into development will increase coverage by 0.09%.
The diff coverage is 87.8%.

Impacted file tree graph

@@               Coverage Diff               @@
##           development     #298      +/-   ##
===============================================
+ Coverage        84.21%   84.31%   +0.09%     
===============================================
  Files               94       94              
  Lines             6539     6999     +460     
===============================================
+ Hits              5507     5901     +394     
- Misses            1032     1098      +66
Impacted Files Coverage Δ
framework/src/bundle/BundleResourceContainer.h 100% <ø> (ø) ⬆️
framework/src/bundle/BundleStorageMemory.cpp 95.65% <ø> (+3.98%) ⬆️
framework/src/bundle/BundleStorageFile.cpp 0% <ø> (ø) ⬆️
framework/src/bundle/BundleStorage.h 100% <ø> (ø) ⬆️
framework/src/bundle/BundleArchive.cpp 95.23% <ø> (ø) ⬆️
framework/src/bundle/BundlePrivate.cpp 81.92% <100%> (+1.75%) ⬆️
framework/src/bundle/BundleResourceContainer.cpp 92.5% <80.95%> (-2.5%) ⬇️
framework/src/util/Utils.cpp 70.52% <93.75%> (+4.7%) ⬆️
...include/cppmicroservices/detail/ServiceTracker.tpp 79.07% <0%> (+2.5%) ⬆️
... and 2 more

@jeffdiclemente
Copy link
Member Author

@CppMicroServices/developers please review as soon as possible. I'd like to submit this within a couple weeks if there are no significant issues. Thanks!

Signed-off-by: The Mathworks Inc <Roy.Lurie@mathworks.com>
Copy link
Member

@saschazelzer saschazelzer left a comment

Choose a reason for hiding this comment

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

I believe we had a discussion about opening / closing the bundle resource container on demand, if a resource is actually requested. But I cannot find a record of that conversation.
The changes are definitely good and should be merged. We can further improve this later. However, the manifest file checking in combination with the more recent heap allocation PR #306 probably needs another look (in the context of the PR #306 .

mz_zip_reader_end(&m_ZipArchive);
try {
CloseContainer();
} catch(...) {}
Copy link
Member

Choose a reason for hiding this comment

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

I suggest to not use ... in catch clauses. If SEH on Windows is enabled, this will swallow hardware exceptions and continuing is usually not a good idea.

Copy link
Member Author

Choose a reason for hiding this comment

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

ok. i'll change ... to const std::exception&

// if the only resource is the manifest file. On this assumption,
// close the open file handle to the zip file to improve performance
// and avoid exceeding OS open file handle limits.
if (OnlyContainsManifest(location)) {
Copy link
Member

Choose a reason for hiding this comment

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

In combination with the heap allocation PR, this would copy the zip blob into memory, just for reading the central directory record and check the entry names. I think we should try and do better in such cases.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. PR #306 needs to be re-factored after this PR is merged.

@jeffdiclemente
Copy link
Member Author

@saschazelzer we did have a conversation about opening / closing the bundle resource container on demand in issue #299.
I will re-factor PR #306 once this PR is merged into development.

@saschazelzer
Copy link
Member

@jeffdiclemente Thanks for pointing this out. What is the strategy then? Are you currently looking into changing how the resource container manages file handles or do you rather want to merge this now as is and go ahead with PR #306 ?

@jeffdiclemente
Copy link
Member Author

@saschazelzer I'd like to merge this PR now and I'll create a follow up issue to change how the resource container manages file handles.

@saschazelzer
Copy link
Member

@saschazelzer I'd like to merge this PR now and I'll create a follow up issue to change how the resource container manages file handles.

@jeffdiclemente Sounds good to me.

@jeffdiclemente jeffdiclemente merged commit 486e9ea into development Oct 24, 2018
@jeffdiclemente jeffdiclemente deleted the perf-open-file-handles branch October 24, 2018 12:46
arcadien pushed a commit to pollen-metrology/CppMicroServices that referenced this pull request May 20, 2019
Fixes CppMicroServices#299 

Installing thousands of bundles within a process can cause undefined behavior when the OS open file limit has been reached. 

If the bundle only contains a manifest.json, close the file after reading the manifest.json contents.
If the bundle meta-data is read again, open the file and leave it open until the bundle is uninstalled.

Signed-off-by: The Mathworks Inc <Roy.Lurie@mathworks.com>
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.

5 participants