Thomas Vachuska
Committed by Gerrit Code Review

Made time limit for event processing configurable; cleaned-up duplicate code.

Change-Id: I08e7f1c9f4cdbd6404f1eb5e3544989e7a728d92
...@@ -20,4 +20,19 @@ package org.onosproject.event; ...@@ -20,4 +20,19 @@ package org.onosproject.event;
20 * then dispatching them to the appropriate event sink. 20 * then dispatching them to the appropriate event sink.
21 */ 21 */
22 public interface EventDeliveryService extends EventDispatcher, EventSinkRegistry { 22 public interface EventDeliveryService extends EventDispatcher, EventSinkRegistry {
23 +
24 + /**
25 + * Sets the number of millis that an event sink has to process an event.
26 + *
27 + * @param millis number of millis allowed per sink per event
28 + */
29 + void setDispatchTimeLimit(long millis);
30 +
31 + /**
32 + * Returns the number of millis that an event sink has to process an event.
33 + *
34 + * @return number of millis allowed per sink per event
35 + */
36 + long getDispatchTimeLimit();
37 +
23 } 38 }
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 -package org.onosproject.event.impl; 16 +package org.onosproject.common.event.impl;
17 17
18 import org.onosproject.event.DefaultEventSinkRegistry; 18 import org.onosproject.event.DefaultEventSinkRegistry;
19 import org.onosproject.event.Event; 19 import org.onosproject.event.Event;
...@@ -37,4 +37,12 @@ public class TestEventDispatcher extends DefaultEventSinkRegistry ...@@ -37,4 +37,12 @@ public class TestEventDispatcher extends DefaultEventSinkRegistry
37 sink.process(event); 37 sink.process(event);
38 } 38 }
39 39
40 + @Override
41 + public void setDispatchTimeLimit(long millis) {
42 + }
43 +
44 + @Override
45 + public long getDispatchTimeLimit() {
46 + return 0;
47 + }
40 } 48 }
......
...@@ -17,12 +17,12 @@ package org.onosproject.core.impl; ...@@ -17,12 +17,12 @@ package org.onosproject.core.impl;
17 17
18 import org.apache.felix.scr.annotations.Activate; 18 import org.apache.felix.scr.annotations.Activate;
19 import org.apache.felix.scr.annotations.Component; 19 import org.apache.felix.scr.annotations.Component;
20 +import org.apache.felix.scr.annotations.Deactivate;
21 +import org.apache.felix.scr.annotations.Modified;
22 +import org.apache.felix.scr.annotations.Property;
20 import org.apache.felix.scr.annotations.Reference; 23 import org.apache.felix.scr.annotations.Reference;
21 import org.apache.felix.scr.annotations.ReferenceCardinality; 24 import org.apache.felix.scr.annotations.ReferenceCardinality;
22 import org.apache.felix.scr.annotations.Service; 25 import org.apache.felix.scr.annotations.Service;
23 -import org.apache.felix.scr.annotations.Property;
24 -import org.apache.felix.scr.annotations.Deactivate;
25 -import org.apache.felix.scr.annotations.Modified;
26 import org.onlab.util.SharedExecutors; 26 import org.onlab.util.SharedExecutors;
27 import org.onlab.util.Tools; 27 import org.onlab.util.Tools;
28 import org.onosproject.cfg.ComponentConfigService; 28 import org.onosproject.cfg.ComponentConfigService;
...@@ -32,9 +32,11 @@ import org.onosproject.core.CoreService; ...@@ -32,9 +32,11 @@ import org.onosproject.core.CoreService;
32 import org.onosproject.core.IdBlockStore; 32 import org.onosproject.core.IdBlockStore;
33 import org.onosproject.core.IdGenerator; 33 import org.onosproject.core.IdGenerator;
34 import org.onosproject.core.Version; 34 import org.onosproject.core.Version;
35 +import org.onosproject.event.EventDeliveryService;
35 import org.osgi.service.component.ComponentContext; 36 import org.osgi.service.component.ComponentContext;
36 import org.slf4j.Logger; 37 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory; 38 import org.slf4j.LoggerFactory;
39 +
38 import java.io.File; 40 import java.io.File;
39 import java.util.Dictionary; 41 import java.util.Dictionary;
40 import java.util.List; 42 import java.util.List;
...@@ -64,9 +66,18 @@ public class CoreManager implements CoreService { ...@@ -64,9 +66,18 @@ public class CoreManager implements CoreService {
64 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 66 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
65 protected ComponentConfigService cfgService; 67 protected ComponentConfigService cfgService;
66 68
67 - @Property(name = "sharedThreadPoolSize", intValue = 30, 69 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
70 + protected EventDeliveryService eventDeliveryService;
71 +
72 + private static final int DEFAULT_POOL_SIZE = 30;
73 + @Property(name = "sharedThreadPoolSize", intValue = DEFAULT_POOL_SIZE,
68 label = "Configure shared pool maximum size ") 74 label = "Configure shared pool maximum size ")
69 - private int sharedThreadPoolSize = 30; 75 + private int sharedThreadPoolSize = DEFAULT_POOL_SIZE;
76 +
77 + private static final int DEFAULT_EVENT_TIME = 2000;
78 + @Property(name = "maxEventTimeLimit", intValue = DEFAULT_EVENT_TIME,
79 + label = "Maximum number of millis an event sink has to process an event")
80 + private int maxEventTimeLimit = DEFAULT_EVENT_TIME;
70 81
71 @Activate 82 @Activate
72 public void activate() { 83 public void activate() {
...@@ -121,30 +132,33 @@ public class CoreManager implements CoreService { ...@@ -121,30 +132,33 @@ public class CoreManager implements CoreService {
121 @Modified 132 @Modified
122 public void modified(ComponentContext context) { 133 public void modified(ComponentContext context) {
123 Dictionary<?, ?> properties = context.getProperties(); 134 Dictionary<?, ?> properties = context.getProperties();
124 - Integer sharedThreadPoolSizeConfig = 135 + Integer poolSize = getIntegerProperty(properties, "sharedThreadPoolSize");
125 - getIntegerProperty(properties, "sharedThreadPoolSize"); 136 +
126 - if (sharedThreadPoolSizeConfig == null) { 137 + if (poolSize != null && poolSize > 1) {
127 - log.info("Shared Pool Size is not configured, default value is {}", 138 + sharedThreadPoolSize = poolSize;
128 - sharedThreadPoolSize); 139 + SharedExecutors.setPoolSize(sharedThreadPoolSize);
129 - } else { 140 + } else if (poolSize != null) {
130 - if (sharedThreadPoolSizeConfig > 0) { 141 + log.warn("sharedThreadPoolSize must be greater than 1");
131 - sharedThreadPoolSize = sharedThreadPoolSizeConfig;
132 - SharedExecutors.setPoolSize(sharedThreadPoolSize);
133 - log.info("Configured. Shared Pool Size is configured to {}",
134 - sharedThreadPoolSize);
135 - } else {
136 - log.warn("Shared Pool Size size must be greater than 0");
137 - }
138 } 142 }
139 - }
140 143
144 + Integer timeLimit = getIntegerProperty(properties, "maxEventTimeLimit");
145 + if (timeLimit != null && timeLimit > 1) {
146 + maxEventTimeLimit = timeLimit;
147 + eventDeliveryService.setDispatchTimeLimit(maxEventTimeLimit);
148 + } else if (timeLimit != null) {
149 + log.warn("maxEventTimeLimit must be greater than 1");
150 + }
151 +
152 + log.info("Settings: sharedThreadPoolSize={}, maxEventTimeLimit={}",
153 + sharedThreadPoolSize, maxEventTimeLimit);
154 + }
141 155
142 156
143 /** 157 /**
144 * Get Integer property from the propertyName 158 * Get Integer property from the propertyName
145 * Return null if propertyName is not found. 159 * Return null if propertyName is not found.
146 * 160 *
147 - * @param properties properties to be looked up 161 + * @param properties properties to be looked up
148 * @param propertyName the name of the property to look up 162 * @param propertyName the name of the property to look up
149 * @return value when the propertyName is defined or return null 163 * @return value when the propertyName is defined or return null
150 */ 164 */
......
...@@ -33,6 +33,7 @@ import java.util.concurrent.ExecutorService; ...@@ -33,6 +33,7 @@ import java.util.concurrent.ExecutorService;
33 import java.util.concurrent.Future; 33 import java.util.concurrent.Future;
34 import java.util.concurrent.LinkedBlockingQueue; 34 import java.util.concurrent.LinkedBlockingQueue;
35 35
36 +import static com.google.common.base.Preconditions.checkArgument;
36 import static java.util.concurrent.Executors.newSingleThreadExecutor; 37 import static java.util.concurrent.Executors.newSingleThreadExecutor;
37 import static org.onlab.util.Tools.groupedThreads; 38 import static org.onlab.util.Tools.groupedThreads;
38 import static org.slf4j.LoggerFactory.getLogger; 39 import static org.slf4j.LoggerFactory.getLogger;
...@@ -45,12 +46,12 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -45,12 +46,12 @@ import static org.slf4j.LoggerFactory.getLogger;
45 public class CoreEventDispatcher extends DefaultEventSinkRegistry 46 public class CoreEventDispatcher extends DefaultEventSinkRegistry
46 implements EventDeliveryService { 47 implements EventDeliveryService {
47 48
48 - // Maximum number of millis a sink can take to process an event.
49 - private static final long MAX_EXECUTE_MS = 1_000;
50 - private static final long WATCHDOG_MS = MAX_EXECUTE_MS / 4;
51 -
52 private final Logger log = getLogger(getClass()); 49 private final Logger log = getLogger(getClass());
53 50
51 + // Default number of millis a sink can take to process an event.
52 + private static final long DEFAULT_EXECUTE_MS = 2_000; // ms
53 + private static final long WATCHDOG_MS = 250; // ms
54 +
54 private final BlockingQueue<Event> events = new LinkedBlockingQueue<>(); 55 private final BlockingQueue<Event> events = new LinkedBlockingQueue<>();
55 56
56 private final ExecutorService executor = 57 private final ExecutorService executor =
...@@ -61,6 +62,7 @@ public class CoreEventDispatcher extends DefaultEventSinkRegistry ...@@ -61,6 +62,7 @@ public class CoreEventDispatcher extends DefaultEventSinkRegistry
61 }; 62 };
62 63
63 private DispatchLoop dispatchLoop; 64 private DispatchLoop dispatchLoop;
65 + private long maxProcessMillis = DEFAULT_EXECUTE_MS;
64 66
65 // Means to detect long-running sinks 67 // Means to detect long-running sinks
66 private TimerTask watchdog; 68 private TimerTask watchdog;
...@@ -92,6 +94,18 @@ public class CoreEventDispatcher extends DefaultEventSinkRegistry ...@@ -92,6 +94,18 @@ public class CoreEventDispatcher extends DefaultEventSinkRegistry
92 log.info("Stopped"); 94 log.info("Stopped");
93 } 95 }
94 96
97 + @Override
98 + public void setDispatchTimeLimit(long millis) {
99 + checkArgument(millis >= WATCHDOG_MS,
100 + "Time limit must be greater than %s", WATCHDOG_MS);
101 + maxProcessMillis = millis;
102 + }
103 +
104 + @Override
105 + public long getDispatchTimeLimit() {
106 + return maxProcessMillis;
107 + }
108 +
95 // Auxiliary event dispatching loop that feeds off the events queue. 109 // Auxiliary event dispatching loop that feeds off the events queue.
96 private class DispatchLoop implements Runnable { 110 private class DispatchLoop implements Runnable {
97 private volatile boolean stopped; 111 private volatile boolean stopped;
...@@ -126,7 +140,7 @@ public class CoreEventDispatcher extends DefaultEventSinkRegistry ...@@ -126,7 +140,7 @@ public class CoreEventDispatcher extends DefaultEventSinkRegistry
126 lastStart = 0; 140 lastStart = 0;
127 } else { 141 } else {
128 log.warn("No sink registered for event class {}", 142 log.warn("No sink registered for event class {}",
129 - event.getClass()); 143 + event.getClass().getName());
130 } 144 }
131 } 145 }
132 146
...@@ -140,7 +154,7 @@ public class CoreEventDispatcher extends DefaultEventSinkRegistry ...@@ -140,7 +154,7 @@ public class CoreEventDispatcher extends DefaultEventSinkRegistry
140 @Override 154 @Override
141 public void run() { 155 public void run() {
142 long delta = System.currentTimeMillis() - lastStart; 156 long delta = System.currentTimeMillis() - lastStart;
143 - if (lastStart > 0 && delta > MAX_EXECUTE_MS) { 157 + if (lastStart > 0 && delta > maxProcessMillis) {
144 log.error("Event sink {} exceeded execution time limit: {} ms", 158 log.error("Event sink {} exceeded execution time limit: {} ms",
145 lastSink.getClass().getName(), delta); 159 lastSink.getClass().getName(), delta);
146 160
......
...@@ -28,7 +28,7 @@ import org.onosproject.core.Application; ...@@ -28,7 +28,7 @@ import org.onosproject.core.Application;
28 import org.onosproject.core.ApplicationId; 28 import org.onosproject.core.ApplicationId;
29 import org.onosproject.core.DefaultApplication; 29 import org.onosproject.core.DefaultApplication;
30 import org.onosproject.core.DefaultApplicationId; 30 import org.onosproject.core.DefaultApplicationId;
31 -import org.onosproject.event.impl.TestEventDispatcher; 31 +import org.onosproject.common.event.impl.TestEventDispatcher;
32 32
33 import java.io.InputStream; 33 import java.io.InputStream;
34 import java.net.URI; 34 import java.net.URI;
......
...@@ -26,7 +26,7 @@ import org.onosproject.cluster.ClusterServiceAdapter; ...@@ -26,7 +26,7 @@ import org.onosproject.cluster.ClusterServiceAdapter;
26 import org.onosproject.cluster.ControllerNode; 26 import org.onosproject.cluster.ControllerNode;
27 import org.onosproject.cluster.DefaultControllerNode; 27 import org.onosproject.cluster.DefaultControllerNode;
28 import org.onosproject.cluster.NodeId; 28 import org.onosproject.cluster.NodeId;
29 -import org.onosproject.event.impl.TestEventDispatcher; 29 +import org.onosproject.common.event.impl.TestEventDispatcher;
30 import org.onosproject.mastership.MastershipService; 30 import org.onosproject.mastership.MastershipService;
31 import org.onosproject.mastership.MastershipStore; 31 import org.onosproject.mastership.MastershipStore;
32 import org.onosproject.mastership.MastershipTermService; 32 import org.onosproject.mastership.MastershipTermService;
......
...@@ -31,7 +31,7 @@ import org.onosproject.cluster.ControllerNode; ...@@ -31,7 +31,7 @@ import org.onosproject.cluster.ControllerNode;
31 import org.onosproject.cluster.DefaultControllerNode; 31 import org.onosproject.cluster.DefaultControllerNode;
32 import org.onosproject.cluster.NodeId; 32 import org.onosproject.cluster.NodeId;
33 import org.onosproject.event.Event; 33 import org.onosproject.event.Event;
34 -import org.onosproject.event.impl.TestEventDispatcher; 34 +import org.onosproject.common.event.impl.TestEventDispatcher;
35 import org.onosproject.mastership.MastershipServiceAdapter; 35 import org.onosproject.mastership.MastershipServiceAdapter;
36 import org.onosproject.mastership.MastershipTerm; 36 import org.onosproject.mastership.MastershipTerm;
37 import org.onosproject.mastership.MastershipTermService; 37 import org.onosproject.mastership.MastershipTermService;
......
...@@ -29,7 +29,7 @@ import org.onosproject.core.ApplicationId; ...@@ -29,7 +29,7 @@ import org.onosproject.core.ApplicationId;
29 import org.onosproject.core.CoreServiceAdapter; 29 import org.onosproject.core.CoreServiceAdapter;
30 import org.onosproject.core.DefaultApplicationId; 30 import org.onosproject.core.DefaultApplicationId;
31 import org.onosproject.core.IdGenerator; 31 import org.onosproject.core.IdGenerator;
32 -import org.onosproject.event.impl.TestEventDispatcher; 32 +import org.onosproject.common.event.impl.TestEventDispatcher;
33 import org.onosproject.net.DefaultDevice; 33 import org.onosproject.net.DefaultDevice;
34 import org.onosproject.net.Device; 34 import org.onosproject.net.Device;
35 import org.onosproject.net.Device.Type; 35 import org.onosproject.net.Device.Type;
......
...@@ -35,7 +35,7 @@ import org.onosproject.core.ApplicationId; ...@@ -35,7 +35,7 @@ import org.onosproject.core.ApplicationId;
35 import org.onosproject.core.DefaultApplicationId; 35 import org.onosproject.core.DefaultApplicationId;
36 import org.onosproject.core.DefaultGroupId; 36 import org.onosproject.core.DefaultGroupId;
37 import org.onosproject.core.GroupId; 37 import org.onosproject.core.GroupId;
38 -import org.onosproject.event.impl.TestEventDispatcher; 38 +import org.onosproject.common.event.impl.TestEventDispatcher;
39 import org.onosproject.net.DeviceId; 39 import org.onosproject.net.DeviceId;
40 import org.onosproject.net.PortNumber; 40 import org.onosproject.net.PortNumber;
41 import org.onosproject.net.device.impl.DeviceManager; 41 import org.onosproject.net.device.impl.DeviceManager;
......
...@@ -36,7 +36,7 @@ import org.onlab.packet.IpPrefix; ...@@ -36,7 +36,7 @@ import org.onlab.packet.IpPrefix;
36 import org.onlab.packet.MacAddress; 36 import org.onlab.packet.MacAddress;
37 import org.onlab.packet.VlanId; 37 import org.onlab.packet.VlanId;
38 import org.onosproject.event.Event; 38 import org.onosproject.event.Event;
39 -import org.onosproject.event.impl.TestEventDispatcher; 39 +import org.onosproject.common.event.impl.TestEventDispatcher;
40 import org.onosproject.net.ConnectPoint; 40 import org.onosproject.net.ConnectPoint;
41 import org.onosproject.net.DeviceId; 41 import org.onosproject.net.DeviceId;
42 import org.onosproject.net.Host; 42 import org.onosproject.net.Host;
......
...@@ -30,7 +30,7 @@ import org.onosproject.TestApplicationId; ...@@ -30,7 +30,7 @@ import org.onosproject.TestApplicationId;
30 import org.onosproject.cfg.ComponentConfigAdapter; 30 import org.onosproject.cfg.ComponentConfigAdapter;
31 import org.onosproject.core.ApplicationId; 31 import org.onosproject.core.ApplicationId;
32 import org.onosproject.core.impl.TestCoreManager; 32 import org.onosproject.core.impl.TestCoreManager;
33 -import org.onosproject.event.impl.TestEventDispatcher; 33 +import org.onosproject.common.event.impl.TestEventDispatcher;
34 import org.onosproject.net.NetworkResource; 34 import org.onosproject.net.NetworkResource;
35 import org.onosproject.net.intent.FlowRuleIntent; 35 import org.onosproject.net.intent.FlowRuleIntent;
36 import org.onosproject.net.intent.Intent; 36 import org.onosproject.net.intent.Intent;
......
...@@ -37,7 +37,7 @@ import org.onosproject.net.link.LinkProviderService; ...@@ -37,7 +37,7 @@ import org.onosproject.net.link.LinkProviderService;
37 import org.onosproject.net.link.LinkService; 37 import org.onosproject.net.link.LinkService;
38 import org.onosproject.net.provider.AbstractProvider; 38 import org.onosproject.net.provider.AbstractProvider;
39 import org.onosproject.net.provider.ProviderId; 39 import org.onosproject.net.provider.ProviderId;
40 -import org.onosproject.event.impl.TestEventDispatcher; 40 +import org.onosproject.common.event.impl.TestEventDispatcher;
41 import org.onosproject.net.device.impl.DeviceManager; 41 import org.onosproject.net.device.impl.DeviceManager;
42 import org.onosproject.store.trivial.impl.SimpleLinkStore; 42 import org.onosproject.store.trivial.impl.SimpleLinkStore;
43 43
......
...@@ -22,7 +22,7 @@ import org.junit.Before; ...@@ -22,7 +22,7 @@ import org.junit.Before;
22 import org.junit.Test; 22 import org.junit.Test;
23 import org.onosproject.cfg.ComponentConfigAdapter; 23 import org.onosproject.cfg.ComponentConfigAdapter;
24 import org.onosproject.event.Event; 24 import org.onosproject.event.Event;
25 -import org.onosproject.event.impl.TestEventDispatcher; 25 +import org.onosproject.common.event.impl.TestEventDispatcher;
26 import org.onosproject.net.Device; 26 import org.onosproject.net.Device;
27 import org.onosproject.net.Link; 27 import org.onosproject.net.Link;
28 import org.onosproject.net.device.DeviceEvent; 28 import org.onosproject.net.device.DeviceEvent;
......
...@@ -19,7 +19,7 @@ import org.junit.After; ...@@ -19,7 +19,7 @@ import org.junit.After;
19 import org.junit.Before; 19 import org.junit.Before;
20 import org.junit.Test; 20 import org.junit.Test;
21 import org.onosproject.event.Event; 21 import org.onosproject.event.Event;
22 -import org.onosproject.event.impl.TestEventDispatcher; 22 +import org.onosproject.common.event.impl.TestEventDispatcher;
23 import org.onosproject.net.ConnectPoint; 23 import org.onosproject.net.ConnectPoint;
24 import org.onosproject.net.Device; 24 import org.onosproject.net.Device;
25 import org.onosproject.net.Link; 25 import org.onosproject.net.Link;
......
...@@ -22,10 +22,7 @@ import org.junit.Before; ...@@ -22,10 +22,7 @@ import org.junit.Before;
22 import org.junit.Test; 22 import org.junit.Test;
23 import org.onosproject.cluster.NodeId; 23 import org.onosproject.cluster.NodeId;
24 import org.onosproject.cluster.RoleInfo; 24 import org.onosproject.cluster.RoleInfo;
25 -import org.onosproject.event.DefaultEventSinkRegistry; 25 +import org.onosproject.common.event.impl.TestEventDispatcher;
26 -import org.onosproject.event.Event;
27 -import org.onosproject.event.EventDeliveryService;
28 -import org.onosproject.event.EventSink;
29 import org.onosproject.event.ListenerRegistry; 26 import org.onosproject.event.ListenerRegistry;
30 import org.onosproject.mastership.MastershipEvent; 27 import org.onosproject.mastership.MastershipEvent;
31 import org.onosproject.mastership.MastershipEvent.Type; 28 import org.onosproject.mastership.MastershipEvent.Type;
...@@ -44,7 +41,6 @@ import java.util.Map; ...@@ -44,7 +41,6 @@ import java.util.Map;
44 import java.util.concurrent.CountDownLatch; 41 import java.util.concurrent.CountDownLatch;
45 import java.util.concurrent.TimeUnit; 42 import java.util.concurrent.TimeUnit;
46 43
47 -import static com.google.common.base.Preconditions.checkState;
48 import static org.junit.Assert.assertEquals; 44 import static org.junit.Assert.assertEquals;
49 import static org.junit.Assert.assertTrue; 45 import static org.junit.Assert.assertTrue;
50 46
...@@ -168,21 +164,4 @@ public class ReplicaInfoManagerTest { ...@@ -168,21 +164,4 @@ public class ReplicaInfoManagerTest {
168 } 164 }
169 } 165 }
170 166
171 -
172 - // code clone
173 - /**
174 - * Implements event delivery system that delivers events synchronously, or
175 - * in-line with the post method invocation.
176 - */
177 - private static class TestEventDispatcher extends DefaultEventSinkRegistry
178 - implements EventDeliveryService {
179 -
180 - @SuppressWarnings({ "rawtypes", "unchecked" })
181 - @Override
182 - public void post(Event event) {
183 - EventSink sink = getSink(event.getClass());
184 - checkState(sink != null, "No sink for event %s", event);
185 - sink.process(event);
186 - }
187 - }
188 } 167 }
......