Hi Romain,

I do not really understand the interplay between quartz, TimerStore and
EjbTimerServiceImpl. As far as I understand, EjbTimerServiceImpl writes
all Timers into quartz and TimerStore. TimerStore contains the Timers
that are visible to the EJB and quartz contains the Timers that are
actually executed. Reading
https://issues.apache.org/jira/browse/OPENEJB-1867 I assume, that using
persistent quartz timers is allowed and even wanted in TomEE, but the
persisted timers are neglected by TimerStore during startup. My ugly
patch (see attached file) copies the Timers persisted by quartz into
TimerStore.

But I do not understand the need for the TimerStore itself. In my
opinion one could avoid the duplicate storage of Timers and retrieve
everything from quartz itself, especially when using different
GroupNames for different deployments. Is there any reason for that?
Otherwise I would like to adjust EjbTimerServiceImpl in a way that does
not need a TimerStore, or at least try a "QuartzTimerStore". But
modifiying the group name would be nice for that.

Bodo


On 09.03.2017 15:00, Romain Manni-Bucau wrote:
> Hi
>
> needs a custom timerstore I think (see
> https://issues.apache.org/jira/browse/TOMEE-785)
>
>
> Romain Manni-Bucau
> @rmannibucau <https://twitter.com/rmannibucau> |  Blog
> <https://blog-rmannibucau.rhcloud.com> | Old Blog
> <http://rmannibucau.wordpress.com> | Github <https://github.com/rmannibucau> |
> LinkedIn <https://www.linkedin.com/in/rmannibucau> | JavaEE Factory
> <https://javaeefactory-rmannibucau.rhcloud.com>
>
> 2017-03-09 14:44 GMT+01:00 Bodo Pfelzer <[email protected]>:
>
>> I tried to configure persistent timers in TomEE-1.7.4 by adding:
>>
>> org.apache.openejb.quartz.jobStore.class
>> org.apache.openejb.quartz.impl.jdbcjobstore.JobStoreCMT
>> org.apache.openejb.quartz.jobStore.driverDelegateClass
>> org.apache.openejb.quartz.impl.jdbcjobstore.StdJDBCDelegate
>> org.apache.openejb.quartz.jobStore.dataSource             ActiveDataSource
>> org.apache.openejb.quartz.jobStore.nonManagedTXDataSource
>> NoTxActiveDataSource
>> org.apache.openejb.quartz.dataSource.ActiveDataSource.jndiURL
>> openejb:Resource/ActiveDataSource
>> org.apache.openejb.quartz.dataSource.NoTxActiveDataSource.jndiURL
>> openejb:Resource/NoTxActiveDataSource
>>
>> to my system.properties. And yes, my EJB method annotated with @Timeout
>> gets called, even if TomEE was restarted during the creation of the
>> timer and its expiration. But two things do not work as expected:
>>
>> timerServer.getTimers() returns an empty collection after restart though
>> active timers exist. And perhaps even worse: Old timers get overwritten
>> by new ones, since MemoryTimerStore.counter always starts from zero
>> after restart.
>>
>> Am I missing something in my configuration? How could I replace
>> MemoryTimerStore?
>>
>> Best regards,
>> Bodo
>>
>>

diff -r openejb-4.7.4/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EjbTimerServiceImpl.java openejb-4.7.4-bodo/container/openejb-core/src/main/java/org/apache/openejb/core/timer/EjbTimerServiceImpl.java
40a41
> import org.apache.openejb.quartz.impl.matchers.GroupMatcher;
67a69
> import java.util.HashSet;
69a72
> import java.util.Set;
484,489c487,516
< 
<         // load saved timers
<         final Collection<TimerData> timerDatas = timerStore.loadTimers(this, (String) deployment.getDeploymentID());
<         // schedule the saved timers
<         for (final TimerData timerData : timerDatas) {
<             initializeNewTimer(timerData);
---
>         final String deploymentID=(String) deployment.getDeploymentID();
>         Set<TriggerKey> toAdd=new HashSet<TriggerKey>();
>         try {
>             final String start=TimerData.OPEN_EJB_TIMEOUT_TRIGGER_NAME_PREFIX+deploymentID+'_';
>             Set<TriggerKey> keys;
>             keys=scheduler.getTriggerKeys(GroupMatcher.triggerGroupEquals(TimerData.OPEN_EJB_TIMEOUT_TRIGGER_GROUP_NAME));
>             for (TriggerKey key:keys) {
>                 if (key.getName().startsWith(start)) toAdd.add(key);
>             }
> 
>             // load saved timers
>             final Collection<TimerData> timerDatas = timerStore.loadTimers(this,deploymentID);
>             // schedule the saved timers
>             for (final TimerData timerData : timerDatas) {
>                 initializeNewTimer(timerData);
>             }
> 
>             /* Add persisted timers from quartz */
>             for (TriggerKey key:toAdd) {
>                 Trigger t=scheduler.getTrigger(key);
>                 if (t!=null) {
>                     JobDataMap map=t.getJobDataMap();
>                     TimerData td=(TimerData) map.get(EjbTimeoutJob.TIMER_DATA);
>                     if (td!=null && td.getNextTimeout().getTime()>System.currentTimeMillis()) {
>                         timerStore.addTimerData(td);
>                     }
>                 }
>             }
>         } catch (SchedulerException e) {
>             throw new TimerStoreException(e);
diff -r openejb-4.7.4/container/openejb-core/src/main/java/org/apache/openejb/core/timer/MemoryTimerStore.java openejb-4.7.4-bodo/container/openejb-core/src/main/java/org/apache/openejb/core/timer/MemoryTimerStore.java
95a96,102
>         /* During reload we may encounter greater ids. */
>         final long newId=timerData.getId();
>         long counterId=counter.get();
>         while (newId>counterId) {
>             if (counter.compareAndSet(counterId,newId)) break;
>             counterId=counter.get();
>         }

Reply via email to