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: bndtools takes too long for SHA-256 and is not interruptable #5322

Closed
reckart opened this issue Jul 18, 2022 · 14 comments · Fixed by #5323
Closed

Performance: bndtools takes too long for SHA-256 and is not interruptable #5322

reckart opened this issue Jul 18, 2022 · 14 comments · Fixed by #5323

Comments

@reckart
Copy link
Contributor

reckart commented Jul 18, 2022

It seems that bndtools is slowing down things significantly when used in a large Eclipse workspace / projects with lots of dependencies. Using the sampler VisualVM, it appears that the time is mostly spent for SHA-256 calculation.

Screenshot 2022-07-18 at 12 38 25

Even when trying to shut down Eclipse, the shut down hangs because bndtools first wants to complete these SHA-256 calculations.

  • It would be nice if calculations would not take so much time - maybe they can be performed lazily or maybe they can be cached?
  • When Eclipse is being shut down, it would be nice if the m2e bndtools would detect this and stop their build.
@pkriens
Copy link
Member

pkriens commented Jul 18, 2022

The issue is not the bnd code, it is the code that is called in the VM (it is confusing that you not show the next 2-3 levels?). Checking for interrupts will only make it slower in the normal case.

@reckart
Copy link
Contributor Author

reckart commented Jul 18, 2022

When I have the opportunity, I'll provide a deeper trace. That said, I had opened it and it stopped at a I/O copy operation that was taking long. The machine I am working on unfortunately does not have a very fast I/O. I looked at the ResourceBuilder code and it seemed to me there that the calculation of the SHA-256 happens unconditionally and is also not subject to any type of caching. That may work ok in smaller workspaces and/or when you have a fast I/O. I believe though that it may not scale well to large workspaces with couple of hundered projects in them and in particular not in the face of a somewhat slowish I/O situation.

@reckart
Copy link
Contributor Author

reckart commented Jul 18, 2022

Similarly, it takes a very long time on my machine to open a bndrun file in the BND editor in Eclipse - from clicking on the file until the ditor opens, it takes 15 minutes (just measured it). Eclipse completely freezes/beachballs during that time and won't accept any input. And this also seems to run into the same branch of the code.

Screenshot 2022-07-18 at 14 52 43

@bjhargrave
Copy link
Member

also not subject to any type of caching

You can't really cache a cache key. The SHA is a unique identifier for the file. Not the other way around.

All that could be done here is to defer the SHA calculation (perhaps forever) until it is needed. But if it is needed, it still needs to be computed.

I have an idea on how to handle deferral here which I will experiment with.

@reckart
Copy link
Contributor Author

reckart commented Jul 18, 2022

The SHA-256 is generated from a file, right? As long as the file does not change, it would not be necessary to recalculate the checksum. Maybe a file timestamp could be used as an indication whether the file has changed and if a re-calculation of the sum would be necessary?

@bjhargrave
Copy link
Member

As long as the file does not change, it would not be necessary to recalculate the checksum.

And how do you know the file changed? You know by calculating the hash to see if it is the same or not. You cannot trust the file system metadata (length, modified time) as that can be easily manipulated.

@reckart
Copy link
Contributor Author

reckart commented Jul 18, 2022

Sure. What I have done in a potentially similar situation is to keep an in-memory cache of hashes, each associated with a timestamp. When a hash becomes older than a certain time, I re-calculate it. When the file on disk has a newer timestamp than the one in memory, I also re-calculate. It is not perfect, but reduces the need to calculate the hash at every opportunity.

bjhargrave added a commit to bjhargrave/bnd that referenced this issue Jul 18, 2022
The osgi.content capability must hold the SHA-256 value of the
resource. But this value is rarely used. So, when building a resource
from a file, we defer the SHA-256 calculation until actually needed.
The can help performance of FileSetRepository used by bndtools m2e.

However, we do need the hashCode of the SHA-256 value early, so use
a substitute hashCode value based upon the File object. This is not
perfect since two files can hold identical content and the hashCode of
their SHA-256 values should be identical. But in practice, this should
work when creating a resource from a file since the early need for the
hashCode of the SHA-256 value is in the computing of the hashCode of
the capability so it can be inserted in a set. But creating a resource
from a file only creates a single osgi.content capability.

Fixes bndtools#5322

Signed-off-by: BJ Hargrave <bj@hargrave.dev>
bjhargrave added a commit to bjhargrave/bnd that referenced this issue Jul 18, 2022
The osgi.content capability must hold the SHA-256 value of the
resource. But this value is rarely used. So, when building a resource
from a file, we defer the SHA-256 calculation until actually needed.
The can help performance of FileSetRepository used by bndtools m2e.

However, we do need the hashCode of the SHA-256 value early, so use
a substitute hashCode value based upon the File object. This is not
perfect since two files can hold identical content and the hashCode of
their SHA-256 values should be identical. But in practice, this should
work when creating a resource from a file since the early need for the
hashCode of the SHA-256 value is in the computing of the hashCode of
the capability so it can be inserted in a set. But creating a resource
from a file only creates a single osgi.content capability.

Fixes bndtools#5322

Signed-off-by: BJ Hargrave <bj@hargrave.dev>
@bjhargrave
Copy link
Member

I have an idea on how to handle deferral here which I will experiment with.

@reckart Please try PR #5323 to see if that helps your performance issue.

bjhargrave added a commit to bjhargrave/bnd that referenced this issue Jul 19, 2022
The osgi.content capability must hold the SHA-256 value of the
resource. But this value is rarely used. So, when building a resource
from a file, we defer the SHA-256 calculation until actually needed.
The can help performance of FileSetRepository used by bndtools m2e.

However, we do need the hashCode of the SHA-256 value early, so use
a substitute hashCode value based upon the File object. This is not
perfect since two files can hold identical content and the hashCode of
their SHA-256 values should be identical. But in practice, this should
work when creating a resource from a file since the early need for the
hashCode of the SHA-256 value is in the computing of the hashCode of
the capability so it can be inserted in a set. But creating a resource
from a file only creates a single osgi.content capability.

Fixes bndtools#5322

Signed-off-by: BJ Hargrave <bj@hargrave.dev>
@reckart
Copy link
Contributor Author

reckart commented Jul 20, 2022

The situation seems to be improved. I'll keep monitoring it. Thanks!

@reckart
Copy link
Contributor Author

reckart commented Jul 20, 2022

So, opening the said bndrun file in a freshly opened and fully built workspace is down from 15 minutes beachballing to 2 minutes beachballing. Not bad ;)

@reckart
Copy link
Contributor Author

reckart commented Jul 20, 2022

That said, it appears that the background task that builds the implicit repository can still take a very long time and it seems it can also make the Eclipse UI freeze up for a significant time. A first glance with VisualVM does not point to a particular hotspot. The time seems to be spend in general on artifact resolving distributed over a number of difference methods.

@reckart
Copy link
Contributor Author

reckart commented Jul 20, 2022

Here we see the process is triggered by the bnd/m2e integration
Screenshot 2022-07-20 at 14 54 54

Here we see that the time is actually spend in m2e code
Screenshot 2022-07-20 at 14 57 12

Not sure if bnd could call that m2e code in a more efficient way....

@reckart
Copy link
Contributor Author

reckart commented Jul 20, 2022

Seems there are still cases where an extended period of time is spend in the hash-calculation path:

Part 1: top levels
Screenshot 2022-07-20 at 17 21 50

Part 2: deep levels
Screenshot 2022-07-20 at 17 21 36

@bjhargrave
Copy link
Member

At some points, the SHA-256 value is needed. There is no way to avoid it being needed. The PR only deferred the calculation into some future which you now seem to be running into. ResourceImpl.equals needs the value to properly determine if two Resources are equal. This equality test needs the values of the attributes of all the resource's capability which includes the SHA-256 value.

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 a pull request may close this issue.

3 participants