Skip to content

Commit a07a307

Browse files
committed
Use repeating task to update change count service property
On startup SCR will blast change count updates for each component it satisfies and activates etc. This resulted in a very large number of task being submitted to the scheduled executor. Prior to using an executor a Timer was used. In both cases the tasks would wait a default of 5 seconds before updating the change count service property. Every task submitted would be a no-op except the very last one which had the "final" change count value. This behavior is to avoid flooding the system with service modified events. The issue is that now we are flooding the scheduled executor with a significant number of task that most all do nothing. Since moving to an executor we noticed a non-trivial bump in our CPU usage when the default 5 seconds passes to run all the queued tasks. It turns out that on the JVM we are using the Timer is actually more efficient than the scheduled executor for popping off all the tasks and running them when the delay timeout is hit. The overall design here is sub-optimal regardless. Flooding a queue with all but one task that do nothing is not efficient. This change moves to using a simple repeating task that just updates the change count service property, if needed, every delay period (defaults to every 5 seconds).
1 parent 4d68c01 commit a07a307

1 file changed

Lines changed: 30 additions & 30 deletions

File tree

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

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -706,8 +706,6 @@ public void unregisterRegionConfigurationSupport(
706706

707707
private final AtomicLong changeCount = new AtomicLong();
708708

709-
private volatile ServiceRegistration<ServiceComponentRuntime> registration;
710-
711709
public Dictionary<String, Object> getServiceRegistrationProperties()
712710
{
713711
final Dictionary<String, Object> props = new Hashtable<>();
@@ -718,42 +716,44 @@ public Dictionary<String, Object> getServiceRegistrationProperties()
718716

719717
public void setRegistration(final ServiceRegistration<ServiceComponentRuntime> reg)
720718
{
721-
this.registration = reg;
719+
long delay = m_configuration.serviceChangecountTimeout();
720+
m_componentActor.scheduleWithFixedDelay(new UpdateChangeCountProperty(reg), delay, delay, TimeUnit.MILLISECONDS);
722721
}
723722

724-
public void updateChangeCount()
725-
{
726-
if ( registration != null )
723+
class UpdateChangeCountProperty implements Runnable {
724+
private final ServiceRegistration<ServiceComponentRuntime> registration;
725+
726+
public UpdateChangeCountProperty(ServiceRegistration<ServiceComponentRuntime> registration)
727727
{
728-
final long count = this.changeCount.incrementAndGet();
728+
this.registration = registration;
729+
}
729730

730-
try
731-
{
732-
m_componentActor.schedule(new Runnable()
731+
@Override
732+
public void run()
733+
{
734+
try {
735+
Long registeredChangeCount = (Long) registration.getReference().getProperty(PROP_CHANGECOUNT);
736+
if (registeredChangeCount == null || registeredChangeCount.longValue() != changeCount.get()) {
737+
try
733738
{
734-
735-
@Override
736-
public void run()
737-
{
738-
if ( changeCount.get() == count )
739-
{
740-
try
741-
{
742-
registration.setProperties(getServiceRegistrationProperties());
743-
}
744-
catch ( final IllegalStateException ise)
745-
{
746-
// we ignore this as this might happen on shutdown
747-
}
748-
}
749-
}
750-
}, m_configuration.serviceChangecountTimeout(), TimeUnit.MILLISECONDS);
751-
}
752-
catch (Exception e) {
739+
registration.setProperties(getServiceRegistrationProperties());
740+
}
741+
catch ( final IllegalStateException ise)
742+
{
743+
// we ignore this as this might happen on shutdown
744+
}
745+
}
746+
} catch (Exception e) {
753747
m_logger.log(Level.WARN,
754-
"Service changecount Timer for {0} had a problem", e,
748+
"Service changecount update for {0} had a problem", e,
755749
registration.getReference());
756750
}
757751
}
752+
753+
}
754+
755+
public void updateChangeCount()
756+
{
757+
this.changeCount.incrementAndGet();
758758
}
759759
}

0 commit comments

Comments
 (0)