Skip to content

Move JCTools-based queues to a new log4j-jctools module #2104

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

Merged
merged 5 commits into from
Dec 18, 2023
Merged

Move JCTools-based queues to a new log4j-jctools module #2104

merged 5 commits into from
Dec 18, 2023

Conversation

vy
Copy link
Member

@vy vy commented Dec 18, 2023

This PR addresses #2075 by means of following changes:

  • Recycler factories in the API are converted to ServiceProviders
  • JCTools dependencies in log4j-api and log4j-core are removed in favor of a new module: log4j-jctools

Why does log4j-jctools depend on log4j-core?

There are two places where JCTools is used as an optional dependency:

  1. In log4j-api as a Recycler[Factory] (used almost everywhere) implementation
  2. In log4j-core as a BlockingQueueFactory (used by AsyncAppender in log4j-core) implementation

There are two approaches I can think of to remove the JCTools optional dependencies:

  1. Hoist BlockingQueueFactory from log4j-core to log4j-api
    • 😃 log4j-jctools will only need to depend on log4j-api
    • ☹️ log4j-api will be introduced a component that only matters for some log4j-core internal
    • ☹️ log4j-core has access to plugins and hence, users were expected to provide custom @Configurable @Plugin BlockingQueueFactory implementations that they can refer to in log4j2.xml. Though moving BlockingQueueFactory to log4j-api will break this contract completely, since log4j-api has no notion of plugins.
  2. Make log4j-jctools depend on log4j-core and provide both Recycler[Factory] and BlockingQueueFactory implementations
    • ☹️ Users who wants a JCTools-based recycler, but no log4j-core et al. (if there is such a use case at all) needs to manually exclude log4j-core

Review kit

  1. You can safely ignore files changed due to package relocations.
  2. Start with changes in o.a.l.log4j.internal.recycler and o.a.l.log4j.spi packages of log4j-api module
  3. Proceed to log4j-core
  4. Now it is safe to check log4j-jctools

@vy vy added this to the 3.0.0 milestone Dec 18, 2023
@vy vy requested a review from ppkarwasz December 18, 2023 11:08
@vy vy self-assigned this Dec 18, 2023
@vy vy changed the base branch from 2.x to main December 18, 2023 11:08
Copy link
Contributor

@ppkarwasz ppkarwasz left a comment

Choose a reason for hiding this comment

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

Nice job, looks good to me.

We might reevaluate the need for alternative recycler implementations in log4j-api in the future, but for now I agree that log4j-core is all we need.

I start to wonder how useful is it to fill log4j-api with partial implementations. For example a recycled LogBuilder is useful for log4j-core, but not so much for log4j-to-slf4j. If log4j-to-slf4j is bound to Logback, the Log4j API builder will be recycled, but the underlying SLF4J builder won't. We might as well remove Recycler from AbstractLogger and move it into core.Logger.

Comment on lines +29 to +45
/**
* Denotes the value to be used while sorting recycler factory providers to determine the precedence order.
* Values will be sorted naturally, that is, lower values will imply higher precedence.
*
* @return the value to be used while sorting
*/
default int getOrder() {
return 100;
}

/**
* The name of this recycler factory provider.
* Recycler factory providers are required to have unique names.
*
* @return the name of this recycler factory provider
*/
String getName();
Copy link
Contributor

Choose a reason for hiding this comment

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

In the future we might consider using ServiceLoader.Provider<RecyclerFactory> instead of this class and add an @Named and @Order annotation to the implementations of RecyclerFactory. We already have a @Named and @Order annotation in log4j-core and log4j-plugins. @jvz, what do you think?

I could open an issue to explore this direction, although I don't have too much confidence in ServiceLoader#stream, which is the only way to obtain ServiceLoader.Provider instances: it is unable to skip faulty service implementations.

Co-authored-by: Piotr P. Karwasz <[email protected]>
@vy
Copy link
Member Author

vy commented Dec 18, 2023

I start to wonder how useful is it to fill log4j-api with partial implementations. For example a recycled LogBuilder is useful for log4j-core, but not so much for log4j-to-slf4j. If log4j-to-slf4j is bound to Logback, the Log4j API builder will be recycled, but the underlying SLF4J builder won't. We might as well remove Recycler from AbstractLogger and move it into core.Logger.

Created #2106 and linked to it in #2016.

@vy vy merged commit 2e4e5e5 into main Dec 18, 2023
@vy vy deleted the api-queue branch December 18, 2023 20:07
@vy vy mentioned this pull request Dec 21, 2023
2 tasks
@ppkarwasz ppkarwasz modified the milestones: 3.0.0, 3.0.0-beta1 Feb 17, 2024
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.

2 participants