This PR adds Actuator endpoint that lists Quartz Scheduler jobs and allows retrieval of their details.

The updated spring-boot-sample-quartz sample can be used to try out the new endpoint.

Comment From: snicoll

See also #9623

Comment From: wilkinsona

I suspect we'll want a single endpoint that provides information about quartz scheduling and "normal" scheduling. We'll consider this one once the Framework changes blocking #9623 are available.

Comment From: vpavic

Thanks for the feedback.

How would the actual response payload look in the case these two are combined? Obviously the model of the scheduling related entities differs quite a bit between the two so I doubt it will be possible to fit them into the same representation. Something like this comes in mind:

{
    "spring": [
        // ...
    ],
    "quartz": [
        // ...
    ]
}

However I'm not sure I like that since at some point we could support operations other than reads. There's also the question of disabling the information from specific scheduler - for example user would like to have Quartz scheduling report but not Spring scheduling. All of this adds complexity to endpoint if it's a single one.

OTOH this could be viewed from the perspective of Flyway/Liquibase endpoints - both are database migration tools yet there are separate endpoints.

Comment From: vpavic

With #8831 resolved, are there any ideas with regard to the direction this PR will be taking?

Comment From: wilkinsona

@vpavic Having implemented the new scheduled tasks endpoint and what you're proposing here, I'm now in agreement with keeping them separate.

I'd quite like to get this into 2.0 if we can. One thing that would help with that is adding some documentation for the endpoint along the lines of what's just be done in https://github.com/spring-projects/spring-boot/commit/4de208bc94d3537f07e26043a7c929092a4d9556. Do you have time to take a look at that?

Comment From: vpavic

Do you have time to take a look at that?

Yes, I should be able to take care of that over the next few days.

Comment From: vpavic

@wilkinsona I've added the endpoint docs.

Comment From: wilkinsona

@vpavic Thanks for the docs.

What was the motivation for splitting the endpoint into two operations? Perhaps retrieving details of all the scheduled jobs is prohibitively expensive when using Quartz? I'm leaning towards reworking this to provide a single operation that shows details of all the scheduled jobs. I think it would make the endpoint easier to use and would also bring it into line with the schedulers endpoint.

Comment From: wilkinsona

Having looked at this some more, I'm wondering if the endpoint should present jobs and triggers as two separate, top-level concerns. That would open up the possibility of having separate operations for manipulating jobs and triggers in the future. In web terms, something like the following:

  • GET /actuator/quartz/jobs lists all jobs known to the scheduler
  • GET /actuator/quartz/triggers lists all groups known to the scheduler

Then, in the future, we could introduce the following:

  • GET /actuator/quartz/jobs/{group}/{name} details of a specific job
  • GET /actuator/quartz/triggers/{group}/{name} details of a specific trigger
  • POST /actuator/quartz/jobs/{group}/{name} pause/resume a job
  • POST /actuator/quartz/triggers/{group}/{name} pause/resume a trigger

Beyond that, I could also see operations for pausing or resuming whole groups:

  • POST /actuator/quartz/jobs/{group} pause/resume a group of jobs
  • POST /actuator/quartz/triggers/{group} pause/resume a group of triggers

Comment From: vpavic

Thanks for the feedback @wilkinsona. The idea of splitting the endpoint into two operations originates from the chat @snicoll and I had shortly after #4299 was merged.

Personally I'm still in favor of such arrangement as listing all the jobs can indeed be quite a costly operation. For each job, we need to go to Scheduler API to retrieve job details and triggers which are basically JobStore operations and in a typical Quartz use case, with database store, this can potentially results in quite big amount of queries.

I'd also avoid looking at Quartz endpoint through comparison with Schedulers endpoint as the two are quite different in nature - the latter usually contains a smaller set of jobs that are static and not backed by a external store, while the former is dynamic and can contain hundreds or even thousands of jobs at a given moment.

Comment From: wilkinsona

Thanks, @vpavic.

I’m rather sceptical that the cost would be prohibitive but do realise it could be the case. IMO, as things stand, the changes proposed here are compromising the usability of the endpoint for a theoretical performance problem. Until the performance cost has been quantified and found to be too large, I don’t think that compromise is justified. Even if the cost is relatively high, endpoint response caching will mitigate it to some degree.

Unfortunately, time is running out for RC1 and I don’t have time to gather performance data that would inform the design of the endpoint. I’m going to drop this from RC1 as I’d rather this landed in 2.1 having been carefully considered than we rush it into 2.0 and regret it.

Comment From: wilkinsona

To make progress, this PR requires the following:

  • Performance data proving or disproving the need for the proposed split.
  • If the split is needed, a proposal for how the possible future operations discussed above would be modelled.

Comment From: alexherr

any progress on it task?

Comment From: wilkinsona

17836 shows that the performance of the preferred structure isn't a problem. Thanks for your efforts here, @vpavic, but I think it makes sense to close this one at this point in favour of #17836.

Comment From: snicoll

I've rebased this change on top of master (quite a ride!) and I am now reviewing it. After having spent quite some time on the alternative proposal, I think this change is simpler and more aligned with what we'd like for a first version. I am sure we'll refine it based on the community feedback in a future release.