Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@electricmonk
Copy link

ScheduledThreadPoolTimer doesn't allow creating a Timer instance around a pre-existing ScheduledExecutorService.

My fix introduces a new class, ScheduledExecutorServiceTimer, which is spawned from ScheduledThreadPoolTimer. The latter now extends the former and only handles the construction of a ThreadPoolScheduler based on the constructor arguments, passing the resulting ScheduledExecutorService to the super constructor.

Copy link
Contributor

Choose a reason for hiding this comment

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

this import is redundant.

@mariusae
Copy link
Contributor

Thanks. I'm pulling this internally, and it should appear here shortly (after review there)

Copy link
Contributor

Choose a reason for hiding this comment

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

looks like this remove was anyway redundant?

Copy link
Contributor

Choose a reason for hiding this comment

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

it looks like this isn't redundant. the executor service will not actually proactively remove the runnable from its queues if .remove isn't called

Copy link
Contributor

Choose a reason for hiding this comment

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

Given that ScheduledThreadPoolExecutor is the only implementation in the Java standard library of this, the simplest thing would be to just use that for the dependency instead, even if that's a bit icky. Some other alternatives are:

  1. Some sort of marker trait that allows you to remove runnables
  2. Wrap the scheduled executor service so that it does the right things on cancel.

Sadly, both of these introduce complexity.

Copy link
Contributor

Choose a reason for hiding this comment

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

FYI, jdk7 provides a method on ScheduledThreadPoolExecutor, setRemoveOnCancelPolicy(boolean), that properly handles cancellation.

@electricmonk
Copy link
Author

Note that I didn't actually change any logic, just split ScheduledThreadPoolTimer into two separate classes. Marius, anything I can do to help or have you got this?

@mariusae
Copy link
Contributor

It did change, unfortunately: see my line comment above. The underlying.remove(runnable) was removed.
I'll take care of it, probably by taking a ScheduledThredPoolExecutor in the constructor.

@electricmonk
Copy link
Author

Hmm. I must have missed that last commit by @jpinner somehow. Sorry for that.

Taking a ScheduledThredPoolExecutor kind of defeats the purpose of this pull request; we are using a DelegatedScheduledExecutorService that decorates Runnables with additional "aspects" like statistics gathering and error reporting, and the point here was to allow an arbitrary implementation of ScheduledExecutorService.

Note, also, that returns instances of ScheduledFutureTask, which actually remove themselves (using ScheduledThredPoolExecutor#remove) from the queue upon cancellation (see lines 280 and 522 of ScheduledThreadPoolExecutor.java (HotSpot 1.7_06) as long as ScheduledThreadPoolExecutor#setRemoveOnCancelPolicy was set to true.

I'm going to commit a further fix which calls this method from the new makeScheduler method I introduced. If the user chose to pass their own instance of ScheduledExecutorService, I think it would suffice to add some warning to the documentation of the method and make it the user's problem.

…nd documenting why this is important for ScheduledExecutorServiceTimer
@mariusae
Copy link
Contributor

Unfortunately this was introduced in JDK7, and we still need to be compatible with JDK6.

@electricmonk
Copy link
Author

Oh crap.

The last resort would be to not have ScheduledThreadPoolTimer extend ScheduledExecutorServiceTimer. They can probably share some code via a Trait. The original class, which is intimately familiar with ScheduledThreadPoolExecutor will call underlying.remove and the new one will not.

It's either that, or do some isInstanceOf checking (blugh :|). Or just cancel this pull request and I'll just add the new timer to our infrastructure :).

What do you say?

@mariusae
Copy link
Contributor

I like the idea of just refactoring some of it out via a mixin so you can reuse that code.

…merSupport, which provides a hook to be called on task cancellation. ScheduledThreadPoolTimer extends this hook and being intimately familiar with ScheduledThreadPoolExecutor, removes the runnable from the executor's queue to prevent retention of tasks with long delay
@mariusae
Copy link
Contributor

Thanks. Pulling this internally & it should appear here shortly.

@mariusae
Copy link
Contributor

I changed the support class to be a mixin (with self-types) and made underlying protected.

@stevegury
Copy link
Contributor

This is now in master, closing

@stevegury stevegury closed this Jun 14, 2013
smarter pushed a commit to smarter/twitter-util that referenced this pull request Aug 12, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

4 participants