The Infinispan-based TimerService treats the schedule expression of an automatic timer as immutable (in the same way that the schedule expression of a programmatic calendar-based persistent timer is immutable once created). Automatic persistent timers are identified by their associated method. When the application is first deployed, the timer is persisted along with its schedule expression. If an application is redeployed with a modified @Schedule, the timer is not recreated, as it already exists (per its identity), which also means that its schedule expression is not updated. In the context of a cluster, it is questionable whether this would even make sense, since the schedule expression may conflict with the existing timer definition on other cluster members (in particular, the cluster member on which the timer is currently scheduled) which may contain the version of the application with the original schedule expression. Since WildFly does not currently contain any notion of application version - it otherwise has no mechanism to determine which cluster member contains the "current"/"correct" schedule expression.
As far as I am aware, the Jakarta Enterprise Bean specification does not describe how an existing persistent timer should behave in the even that, upon redeploy on one JVM, its schedule expression has changed. The most relevant mention appears to be this:
> By default, each Schedule annotation corresponds to a single persistent timer, regardless of the number of JVMs across which the container is distributed.
In the absence of clear requirements, I have always interpreted this to mean that: if the annotation corresponds to the timer, then the first cluster member to create the timer determines the schedule expression.
That said, changing the schedule does seem like a perfectly reasonable, even if the specification does not describe how exactly this is meant to work.
Since we have a mechanism by which the schedule is identified, we could theoretically just update the value in the distributed cache.
If the timer is owned by the newly started server, all is fine.
If the timer is owned by a different server, and the new schedule would fire the event further in the future, all is fine.
However, if the timer is owned by another server, and the new schedule would fire the timer event sooner than the old schedule, the new schedule will not take effect until the subsequent invocation.
That all sounds reasonable, however...
What, instead of modifying the schedule, the annotation was modified to be non-persistent? What would you expect to happen?
Given how this stuff is implemented, this would effectively result in a new non-persistent timer being created. However, there is now a phantom persistent timer that will continue to execute. Timer entries are indexed by component/method name, so we technically have a relatively inexpensive means of identifying it, should these be auto-cancelled?
What if the schedule annotation was removed altogether? Scanning for phantom timers on potential method that require cancellation would be relatively expensive.
What if the schedule annotation was removed *and* the method itself renamed? This would require a full cache entry scan and would be very expensive to attempt an auto-cancel.
Thoughts?
Paul