Skip to content

Commit 51de0a8

Browse files
committed
Cancel scheduled task for change count update when inactive
After at least 10 seconds of inactivity this will cancel the ScheduledFuture for updating the change count service property. If later the change count is updated then a new ScheduledFuture is submitted.
1 parent a07a307 commit 51de0a8

1 file changed

Lines changed: 52 additions & 8 deletions

File tree

scr/src/main/java/org/apache/felix/scr/impl/ComponentRegistry.java

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.util.concurrent.ConcurrentHashMap;
3232
import java.util.concurrent.ConcurrentMap;
3333
import java.util.concurrent.ScheduledExecutorService;
34+
import java.util.concurrent.ScheduledFuture;
3435
import java.util.concurrent.TimeUnit;
3536
import java.util.concurrent.atomic.AtomicLong;
3637

@@ -132,9 +133,12 @@ public class ComponentRegistry
132133

133134
private final ScheduledExecutorService m_componentActor;
134135

136+
private final UpdateChangeCountProperty m_updateChangeCountPropertyTask;
137+
135138
public ComponentRegistry(final ScrConfiguration scrConfiguration, final ScrLogger logger, final ScheduledExecutorService componentActor )
136139
{
137140
m_configuration = scrConfiguration;
141+
m_updateChangeCountPropertyTask = new UpdateChangeCountProperty(m_configuration.serviceChangecountTimeout());
138142
m_logger = logger;
139143
m_componentActor = componentActor;
140144
m_componentHoldersByName = new HashMap<>();
@@ -716,44 +720,84 @@ public Dictionary<String, Object> getServiceRegistrationProperties()
716720

717721
public void setRegistration(final ServiceRegistration<ServiceComponentRuntime> reg)
718722
{
719-
long delay = m_configuration.serviceChangecountTimeout();
720-
m_componentActor.scheduleWithFixedDelay(new UpdateChangeCountProperty(reg), delay, delay, TimeUnit.MILLISECONDS);
723+
m_updateChangeCountPropertyTask.setRegistration(reg);
724+
m_updateChangeCountPropertyTask.schedule();
721725
}
722726

723727
class UpdateChangeCountProperty implements Runnable {
724-
private final ServiceRegistration<ServiceComponentRuntime> registration;
728+
private volatile ServiceRegistration<ServiceComponentRuntime> registration;
729+
private final long maxNumberOfNoChanges;
730+
private final long delay;
731+
732+
// guarded by this
733+
private int noChangesCount = 0;
734+
// guarded by this
735+
private ScheduledFuture<?> scheduledFuture = null;
725736

726-
public UpdateChangeCountProperty(ServiceRegistration<ServiceComponentRuntime> registration)
737+
public UpdateChangeCountProperty(long delay)
727738
{
728-
this.registration = registration;
739+
this.delay = delay;
740+
// calculate the max number of no changes; must be at least 1 to avoid missing events
741+
maxNumberOfNoChanges = Long.max(10000 / delay, 1);
742+
}
743+
744+
public void setRegistration(ServiceRegistration<ServiceComponentRuntime> reg)
745+
{
746+
this.registration = reg;
747+
}
748+
749+
public synchronized void schedule()
750+
{
751+
// reset noChangesCount to ensure task runs at least once more if it exists
752+
noChangesCount = 0;
753+
if (scheduledFuture != null) {
754+
return;
755+
}
756+
scheduledFuture = m_componentActor.scheduleWithFixedDelay(this , delay, delay, TimeUnit.MILLISECONDS);
729757
}
730758

731759
@Override
732760
public void run()
733761
{
762+
ServiceRegistration<ServiceComponentRuntime> currentReg = registration;
763+
if (currentReg == null) {
764+
return;
765+
}
734766
try {
735-
Long registeredChangeCount = (Long) registration.getReference().getProperty(PROP_CHANGECOUNT);
767+
Long registeredChangeCount = (Long) currentReg.getReference().getProperty(PROP_CHANGECOUNT);
736768
if (registeredChangeCount == null || registeredChangeCount.longValue() != changeCount.get()) {
737769
try
738770
{
739-
registration.setProperties(getServiceRegistrationProperties());
771+
currentReg.setProperties(getServiceRegistrationProperties());
740772
}
741773
catch ( final IllegalStateException ise)
742774
{
743775
// we ignore this as this might happen on shutdown
744776
}
777+
} else {
778+
synchronized (this) {
779+
noChangesCount++;
780+
if (noChangesCount > maxNumberOfNoChanges) {
781+
// haven't had any changes for max number of tries;
782+
// cancel the scheduled future if it exists.
783+
if (scheduledFuture != null) {
784+
scheduledFuture.cancel(false);
785+
scheduledFuture = null;
786+
}
787+
}
788+
}
745789
}
746790
} catch (Exception e) {
747791
m_logger.log(Level.WARN,
748792
"Service changecount update for {0} had a problem", e,
749793
registration.getReference());
750794
}
751795
}
752-
753796
}
754797

755798
public void updateChangeCount()
756799
{
757800
this.changeCount.incrementAndGet();
801+
m_updateChangeCountPropertyTask.schedule();
758802
}
759803
}

0 commit comments

Comments
 (0)