-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
XML::Error.errors
leaks memory
#14934
Comments
Maybe an opt-in flag, and raise an error to specify the flag when trying to access |
I don't like the idea of breaking the existing code. An opt-in means that. I was playing with the idea of using a macro hook to detect the usage of |
Suppose we could somehow detect whether I don't think we should do that. If you really want to use Considering this, I don't see any good reason to continue using |
I'm not sure we'll be breaking anything: The upgrade path looks easy (use |
Playing devils advocate, if it's really not used anywhere and is already deprecated, do we really need to do anything at all and just save the break until 2.0? Like sure it's leaking memory but is it actually a significant amount to make going thru all this effort of discussion/implementation worth it? |
Yes, this is immensely relevant. This leak was discovered in a production application. An app that parses large numbers of XML documents will occasionally encounter some parsing errors. All these errors get collected in |
EDIT2: These are from old forks that aren't in master anymore.
EDIT: NVM, I see the problem now. It'll leak because they're not using it. 👍. |
The problem is that the memory exists even when you don't use the deprecated API. There's no opt-in for The example in the OP does not use |
The search results are from outdated copies of the standard library. That usage was removed in #13038. |
💡 Idea: how about changing the backing storage of these errors to a single integer? Then the legacy method would return N times a fake error message |
Sorry, I realized these both just before you replied 🙈. Thanks for the confirmation tho. |
@oprypin That's an interesting thought. But I think it might be better to introduce a hard break and alert of the situation instead of putting the old API on some sort of minimal life-support. |
Sure, personally I'm not against this breakage. The entrenched policy is clearly against it though 😬 |
I say it's better to change the behavior to just keep the last message, place that in the deprecation message, and be done with it. We keep some backward compatibility, but not the leak. |
@oprypin No, I believe this is within the limits of the compatibility policy: https://crystal-lang.org/reference/1.13/project/release-policy.html#reservations
We can chose in which way to do that.
I suppose another option could be to generalize the error messages (i.e. remove quotes of the input document such as element names) and put them in a string pool. That could restrict overall memory usage to a tolerable amount. But it requires a bit of effort just to keep supporting a deprecated API that is not very useful anyway. Or as mentioned in the OP, we could put a cap on the number of stored error messages and drop old ones. That's similar to #14934 (comment) which puts the cap at 1. |
After further considerations after #14966 's comments, I'm now convinced that this is a breakage we need to do. It's impact in the ecosystem should be very limited, and the attempts at having a backwards-compatible version that doesn't leak and still works is challenging at best. So I'm now in favor of simply blocking its usage. #14934 is nice in that it doesn't remove the methods, but instead shows a nice explanatory message of why using it is not allowed. |
XML::Error
has a class variable@@errors
which accumulates error messages from calls intolibxml2
.It's accessible via the class method
XML::Error.errors
which returns the current items and resets the instance variable.This global error handling is a legacy mechanism. Its use is deprecated. It was replaced by a more localized variant in #12663.
Still, we're keeping the old API around for backwards compatibility.
But when you don't use the deprecated API - as recommended - that means
.errors
never resets@@errors
and the array with error messages only grows and wastes memory.Example:
This bug is a bit of a dilemma: We keep supporting an old API but not using it causes it to malfunction.
Maybe we could try to come up with some clever mechanism to clear the errors array every now and then or cap its size to keep extend in check. But I don't think that's going to work sufficiently well. For users of the new API it would still be wasteful. And we cannot guarantee stability for users of the old API.
So IMO our only option is to cut off the global error collection.
We could keep the deprecated method
XML::Error.errors
and have it always returnnil
. But at that point it has no meaningful function anymore and we could just drop it entirely. That'll at least mean a hard break for any code that still uses the deprecated API.If necessary, it could be possible to provide the previous behaviour as an opt-in.
The text was updated successfully, but these errors were encountered: