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

Create Disruptor with a ThreadFactory instead of ExecutorService #570

Merged
merged 5 commits into from
Jul 25, 2021

Conversation

brenuart
Copy link
Collaborator

See #567

@philsttr
Copy link
Collaborator

philsttr commented Jul 18, 2021

After this change, the AsyncDisruptorAppender no longer uses its executorService. The executorService is now only used by the AbstractLogstashTcpSocketAppender.

I think we have two options here:

  1. Keep the executorService on AsyncDisruptorAppender for backwards compatibility in case there are other subclasses outside of logstash-logback-encoder using the executorService. In this case, the javadocs should be updated to indicate it's not used by AsyncDisruptorAppender directly, and kept for backwards compatibility for subclass usage only.
    OR
  2. Move the executorService down to AbstractLogstashTcpSocketAppender.

I'm leaning in favor of 1. If you agree, can you update the javadoc of the field, and perhaps the getter as well?

We could also deprecate the executorService on AsyncDisruptorAppender with the intention of moving it down to AbstractLogstashTcpSocketAppender later. Thoughts?

@brenuart
Copy link
Collaborator Author

I see your point. However, we are moving to 7.0 and removed deprecated methods which are likely to break other people's code (I know they were marked @deprecated for a while already but, you know, I doubt many moved away from them already ;-)

I'd like to start the 7 series with as less deprecation as possible... Removing the ExecutorService from AsyncDisruptorAppender without notice is indeed not very "friendly" but how many will be affected? The workaround is very easy - just create the executor service yourself from the ThreadFactory and you are back in business.

So I would go for option (2) + describe the workaround in the release note.
Do you think this is acceptable?

@philsttr
Copy link
Collaborator

Yeah, I think 2 is acceptable since we're bumping the major version.

brenuart and others added 3 commits July 20, 2021 16:44
… the AbstractLogstashTcpSocketAppender

AsyncDisruptorAppender does use the ExecutorService anymore - move it inside classes that need it
@brenuart brenuart force-pushed the gh567-disruptor-threadfactory branch from 85128ac to ceb78f2 Compare July 20, 2021 20:29
@brenuart
Copy link
Collaborator Author

brenuart commented Jul 20, 2021

Ok - done.
I'll write a note about the removal of the ExecutorService in the draft release note after the PR is merged.

I still have a question tho... I'm wondering why we have to set the corePoolSize on the ScheduledThreadPoolExecutor. This kind of executor will create threads on demand with no upper limit. The corePoolSize indicates the number of threads to keep in the pool, even if they are idle, unless allowCoreThreadTimeOut is set in which case idle threads may be evicted after a while. We have at most 3 threads/tasks:
- the KeepAlive task. This is a delayed task that is re-submitted after execution.
- the WriteTimeout. This task consumes a thread as long as the connection is open.
- the ReaderCallable. Used to read the input stream and detect when the destination closes the connection. It also consumes a thread for the duration of the connection.

If we start with a default corePoolSize of zero, the pool will start initially empty and at most 3 threads will be created depending on the configuration of the appender. Once created, 2 of them will remain active for the duration of the connection. They will return to the pool when the connection is closed and since the pool is not configured with an idle timeout they will stay there until they are reused by the subsequent connection. The recurrent KeepAlive task will also consume a thread for nearly 100% of the time and - again - will reuse one already in the pool when it is re-submitted.

My conclusion is we don't need to care about the corePoolSize at all...

(forget about the above - I was wrong - the ScheduledThreadPoolExecutor keeps only coreSize threads in the pool and discard any additional thread immediately after a task is completed and no more is waiting in the queue. Using a coreSize of zero is almost identical to not pooling anything at all)

@brenuart
Copy link
Collaborator Author

@philsttr Are you ok with these changes? Can I squash & merge?

@philsttr philsttr merged commit 6386d2a into logfellow:main Jul 25, 2021
@brenuart
Copy link
Collaborator Author

I need to add some words in the release note about the removal of the ExecutorService from the AsyncDisruptorAppender. Could you please create a first draft of the release note? I haven't done this yet with Github... I'll take care to fill in the blanks afterwards.

@philsttr
Copy link
Collaborator

Sure thing. Give me a few mins.

@philsttr philsttr added this to the 7.0 milestone Jul 25, 2021
@brenuart
Copy link
Collaborator Author

Np. Time for me to go to sleep anyway ;-)

@brenuart brenuart deleted the gh567-disruptor-threadfactory branch July 26, 2021 22:11
@philsttr philsttr added type/enhancement warn/api-change Breaking change with compilation or xml configuration errors labels Nov 13, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/enhancement warn/api-change Breaking change with compilation or xml configuration errors
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Creating a Disruptor instance with an Executor is deprecated in favour of a ThreadFactory
2 participants