-
-
Notifications
You must be signed in to change notification settings - Fork 799
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
Add BufferRecyclerProvider
configuration
#1083
Add BufferRecyclerProvider
configuration
#1083
Conversation
|
||
public abstract BufferRecycler acquireBufferRecycler(TokenStreamFactory forFactory); | ||
|
||
public abstract void releaseBufferRecycler(BufferRecycler r); |
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.
Not 100% sure this is needed by life-cycle, but I think it may be.
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 the most general case I believe that this method is necessary, even though for some implementations, like the ThreadLocal
based one, it could be empty. If you turn this abstract class into an interface as I was suggesting, maybe you can also provide a default
implementation for this method with an empty body?
{ | ||
private static final long serialVersionUID = 1L; | ||
|
||
public abstract BufferRecycler acquireBufferRecycler(TokenStreamFactory forFactory); |
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.
Wasn't sure of naming for get/return etc, open to different names than acquire/release.
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.
Naming wise I believe that what's wrong here is the name of the class. The fact that is a pool should be reflected in its name, so we should call it BufferRecyclerPool
. Once you do this acquire
and release
will be the most natural choices, but of course I'm open to other suggestions.
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.
Hmmmh. Ok. Not sure how I managed to miss this comment before merging.
I agree that if there's life-cycle, "provider" is not quite the right choice.
Not sure I like "pool" but maybe that'd be better...
Let me first merge things as they are and the consider renaming.
* | ||
* @since 2.16 | ||
*/ | ||
public static class ThreadLocalBufferRecyclerProvider |
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.
Was going back and forth between creating a main-level class vs nested here; mostly located here to keep close to defaultProvider()
defined above.
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.
I agree that it's better to keep all default implementations in one place and have them internal to the main level class. By the way we will also need another implementation not pooling anything but simply returning a new BufferRecycler
every time that acquire
is called. I believe that this "dummy" implementation should be also placed here.
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.
I was wondering about "no-op" implementation but for now it did not seem necessary. But maybe I am wrong.
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.
Oh. The reason -- maybe not great one -- was that the check for "do not recycle" is using a simple Feature, and by-passes provider/pool altogether.
Maybe using and passing no-op instance would make more sense, nonetheless, instead of using null
provider/pool.
cc @mariofusco @pjfanning this would be building block for #1064: defined as separate PR so I can merge this scaffolding to |
src/main/java/com/fasterxml/jackson/core/util/BufferRecyclerProvider.java
Outdated
Show resolved
Hide resolved
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.
Making the BufferRecyclerProvider
(or better Pool
imo) pluggable is actually a great decision, also because it will allow users to provide their own implementation, possibly based on an already existing pooling library, without forcing jackson-core to also directly depend on that library. Why didn't I think about it? :)
My only outstanding doubt is about the IOContext
constructor and life-cycle. The IOContext
is actually the only user and owner of the BufferRecycler
, so it's evident that their 2 life-cycles are related and the second should be returned to the pool only when the first is closed. So my doubts are:
- Is it reasonable to allow to create an
IOContext
without going through theJsonFactory
? At the moment we have many test cases doing this, but I don't understand if this is a valid use case and for which situation. - If so should there exist a constructor of the
IOContext
that doesn't take theBufferRecycler
as an argument? I introduced it in my other pull request because I wanted to make it clear that the first is the owner of the second and also controls its life-cycle. In general I still believe that this was a good idea (if a resource has only one exclusive owner it should be possibly created by that owner to fully encapsulate its life-cycle in the owner implementation), but this specific situation maybe doesn't fit that general good practice.
Once you will have clarified this doubts, and eventually addressed my other comments in the code, please feel free to merge this pull request asap and I will take care to rebase mine against it and rework it accordingly.
I think the IOContext should normally be tried to a JsonFactory and that there is an argument that the a buffer recycler could be reused by all IOContexts associated with a JsonFactory instance. If there is test code that creates IOContexts directly, then there might be an argument for us to change those to use JsonFactories. @cowtowncoder can clarify if IOContexts need to creatable without Json Factories. |
@mariofusco @pjfanning You are correct: EDIT: Ok actually there is at least one alternate/secondary owner for This leads to another thing that is bit open: need for I think I will remove this method before merging; it (or similar) can easily be added when scaffolding is ready; for now only acquire method is really needed. |
…ary release-method
Merged: looking at code I do think that WDYT? |
Quick note: I will do another PR with at least following changes:
|
Did #1085, merged it. So I think this is closer to working baseline. |
Agreed, and I did something similar in my pull request. Actually there also |
No description provided.