Jian Li
Committed by Gerrit Code Review

Add SharedScheduledExecutors for ease of using ScheduledExecutors

- LogScheduledExecutorService -> SharedScheduledExecutorService
- Add a utility classs for SharedScheduledExecutorService
- Add unit test for SharedScheduledExecutors
- Revise the control message provider to use
  SharedScheduledExecutorService

Change-Id: Ia4dea245543b4751e6edcce1aaab4991d897cc77
...@@ -22,6 +22,7 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -22,6 +22,7 @@ import org.apache.felix.scr.annotations.Deactivate;
22 import org.apache.felix.scr.annotations.Reference; 22 import org.apache.felix.scr.annotations.Reference;
23 import org.apache.felix.scr.annotations.ReferenceCardinality; 23 import org.apache.felix.scr.annotations.ReferenceCardinality;
24 import org.onlab.metrics.MetricsService; 24 import org.onlab.metrics.MetricsService;
25 +import org.onlab.util.SharedScheduledExecutors;
25 import org.onosproject.cpman.message.ControlMessageProvider; 26 import org.onosproject.cpman.message.ControlMessageProvider;
26 import org.onosproject.cpman.message.ControlMessageProviderRegistry; 27 import org.onosproject.cpman.message.ControlMessageProviderRegistry;
27 import org.onosproject.cpman.message.ControlMessageProviderService; 28 import org.onosproject.cpman.message.ControlMessageProviderService;
...@@ -43,9 +44,6 @@ import java.util.concurrent.ScheduledExecutorService; ...@@ -43,9 +44,6 @@ import java.util.concurrent.ScheduledExecutorService;
43 import java.util.concurrent.ScheduledFuture; 44 import java.util.concurrent.ScheduledFuture;
44 import java.util.concurrent.TimeUnit; 45 import java.util.concurrent.TimeUnit;
45 46
46 -import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
47 -import static org.onlab.util.Tools.groupedThreads;
48 -import static org.onlab.util.Tools.loggableScheduledExecutor;
49 import static org.onosproject.net.DeviceId.deviceId; 47 import static org.onosproject.net.DeviceId.deviceId;
50 import static org.onosproject.openflow.controller.Dpid.uri; 48 import static org.onosproject.openflow.controller.Dpid.uri;
51 import static org.slf4j.LoggerFactory.getLogger; 49 import static org.slf4j.LoggerFactory.getLogger;
...@@ -106,9 +104,7 @@ public class OpenFlowControlMessageProvider extends AbstractProvider ...@@ -106,9 +104,7 @@ public class OpenFlowControlMessageProvider extends AbstractProvider
106 // listens all OpenFlow outgoing message events 104 // listens all OpenFlow outgoing message events
107 controller.getSwitches().forEach(sw -> sw.addEventListener(outMsgListener)); 105 controller.getSwitches().forEach(sw -> sw.addEventListener(outMsgListener));
108 106
109 - executor = loggableScheduledExecutor( 107 + executor = SharedScheduledExecutors.getSingleThreadExecutor();
110 - newSingleThreadScheduledExecutor(groupedThreads("onos/provider",
111 - "aggregator")));
112 108
113 connectInitialDevices(); 109 connectInitialDevices();
114 log.info("Started"); 110 log.info("Started");
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
16 16
17 package org.onlab.util; 17 package org.onlab.util;
18 18
19 +import com.google.common.base.Throwables;
19 import org.slf4j.Logger; 20 import org.slf4j.Logger;
20 21
21 import java.util.Collection; 22 import java.util.Collection;
...@@ -33,7 +34,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -33,7 +34,7 @@ import static org.slf4j.LoggerFactory.getLogger;
33 /** 34 /**
34 * A new scheduled executor service that does not eat exception. 35 * A new scheduled executor service that does not eat exception.
35 */ 36 */
36 -class LogScheduledExecutorService implements ScheduledExecutorService { 37 +class SharedScheduledExecutorService implements ScheduledExecutorService {
37 38
38 private static final String NOT_ALLOWED = "Shutdown of scheduled executor is not allowed"; 39 private static final String NOT_ALLOWED = "Shutdown of scheduled executor is not allowed";
39 private final Logger log = getLogger(getClass()); 40 private final Logger log = getLogger(getClass());
...@@ -45,7 +46,7 @@ class LogScheduledExecutorService implements ScheduledExecutorService { ...@@ -45,7 +46,7 @@ class LogScheduledExecutorService implements ScheduledExecutorService {
45 * 46 *
46 * @param executor executor service to wrap 47 * @param executor executor service to wrap
47 */ 48 */
48 - LogScheduledExecutorService(ScheduledExecutorService executor) { 49 + SharedScheduledExecutorService(ScheduledExecutorService executor) {
49 this.executor = executor; 50 this.executor = executor;
50 } 51 }
51 52
...@@ -191,7 +192,7 @@ class LogScheduledExecutorService implements ScheduledExecutorService { ...@@ -191,7 +192,7 @@ class LogScheduledExecutorService implements ScheduledExecutorService {
191 runnable.run(); 192 runnable.run();
192 } catch (Exception e) { 193 } catch (Exception e) {
193 log.error("Uncaught exception on " + runnable.getClass().getSimpleName(), e); 194 log.error("Uncaught exception on " + runnable.getClass().getSimpleName(), e);
194 - throw new RuntimeException(e); 195 + throw Throwables.propagate(e);
195 } 196 }
196 } 197 }
197 } 198 }
......
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.util;
17 +
18 +import java.util.concurrent.ScheduledExecutorService;
19 +
20 +import static com.google.common.base.Preconditions.checkArgument;
21 +import static java.util.concurrent.Executors.newScheduledThreadPool;
22 +import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
23 +import static org.onlab.util.Tools.groupedThreads;
24 +
25 +/**
26 + * Utility for managing a set of shared execution resources, such as a single
27 + * thread scheduled executor and thread pool scheduled executor for use by
28 + * various parts of the platform or by applications.
29 + * <p>
30 + * Whenever possible, use of these shared resources is encouraged over creating
31 + * separate ones.
32 + * </p>
33 + */
34 +public final class SharedScheduledExecutors {
35 +
36 + public static final int DEFAULT_POOL_SIZE = 30;
37 +
38 + private static SharedScheduledExecutorService singleThreadExecutor =
39 + new SharedScheduledExecutorService(
40 + newSingleThreadScheduledExecutor(
41 + groupedThreads("onos/shared/scheduled",
42 + "onos-single-executor")));
43 +
44 + private static SharedScheduledExecutorService poolThreadExecutor =
45 + new SharedScheduledExecutorService(
46 + newScheduledThreadPool(DEFAULT_POOL_SIZE,
47 + groupedThreads("onos/shared/scheduled",
48 + "onos-pool-executor-%d")));
49 +
50 + // Ban public construction
51 + private SharedScheduledExecutors() {
52 + }
53 +
54 + /**
55 + * Returns the shared scheduled single thread executor.
56 + *
57 + * @return shared scheduled single thread executor
58 + */
59 + public static ScheduledExecutorService getSingleThreadExecutor() {
60 + return singleThreadExecutor;
61 + }
62 +
63 + /**
64 + * Returns the shared scheduled thread pool executor.
65 + *
66 + * @return shared scheduled executor pool
67 + */
68 + public static ScheduledExecutorService getPoolThreadExecutor() {
69 + return poolThreadExecutor;
70 + }
71 +
72 + /**
73 + * Configures the shared scheduled thread pool size.
74 + *
75 + * @param poolSize new pool size
76 + */
77 + public static void setPoolSize(int poolSize) {
78 + checkArgument(poolSize > 0, "Shared pool size size must be greater than 0");
79 + poolThreadExecutor.setBackingExecutor(
80 + newScheduledThreadPool(poolSize, groupedThreads("onos/shared/scheduled",
81 + "onos-pool-executor-%d")));
82 + }
83 +
84 + /**
85 + * Shuts down all shared scheduled executors.
86 + * This is not intended to be called by application directly.
87 + */
88 + public static void shutdown() {
89 + singleThreadExecutor.backingExecutor().shutdown();
90 + poolThreadExecutor.backingExecutor().shutdown();
91 + }
92 +}
...@@ -15,10 +15,11 @@ ...@@ -15,10 +15,11 @@
15 */ 15 */
16 package org.onlab.util; 16 package org.onlab.util;
17 17
18 -import static java.nio.file.Files.delete; 18 +import com.google.common.base.Charsets;
19 -import static java.nio.file.Files.walkFileTree; 19 +import com.google.common.base.Strings;
20 -import static org.onlab.util.GroupedThreadFactory.groupedThreadFactory; 20 +import com.google.common.primitives.UnsignedLongs;
21 -import static org.slf4j.LoggerFactory.getLogger; 21 +import com.google.common.util.concurrent.ThreadFactoryBuilder;
22 +import org.slf4j.Logger;
22 23
23 import java.io.BufferedReader; 24 import java.io.BufferedReader;
24 import java.io.File; 25 import java.io.File;
...@@ -45,7 +46,6 @@ import java.util.Set; ...@@ -45,7 +46,6 @@ import java.util.Set;
45 import java.util.concurrent.CompletableFuture; 46 import java.util.concurrent.CompletableFuture;
46 import java.util.concurrent.ExecutionException; 47 import java.util.concurrent.ExecutionException;
47 import java.util.concurrent.Future; 48 import java.util.concurrent.Future;
48 -import java.util.concurrent.ScheduledExecutorService;
49 import java.util.concurrent.ThreadFactory; 49 import java.util.concurrent.ThreadFactory;
50 import java.util.concurrent.TimeUnit; 50 import java.util.concurrent.TimeUnit;
51 import java.util.concurrent.TimeoutException; 51 import java.util.concurrent.TimeoutException;
...@@ -55,12 +55,10 @@ import java.util.stream.Collectors; ...@@ -55,12 +55,10 @@ import java.util.stream.Collectors;
55 import java.util.stream.Stream; 55 import java.util.stream.Stream;
56 import java.util.stream.StreamSupport; 56 import java.util.stream.StreamSupport;
57 57
58 -import org.slf4j.Logger; 58 +import static java.nio.file.Files.delete;
59 - 59 +import static java.nio.file.Files.walkFileTree;
60 -import com.google.common.base.Charsets; 60 +import static org.onlab.util.GroupedThreadFactory.groupedThreadFactory;
61 -import com.google.common.base.Strings; 61 +import static org.slf4j.LoggerFactory.getLogger;
62 -import com.google.common.primitives.UnsignedLongs;
63 -import com.google.common.util.concurrent.ThreadFactoryBuilder;
64 62
65 /** 63 /**
66 * Miscellaneous utility methods. 64 * Miscellaneous utility methods.
...@@ -130,17 +128,6 @@ public abstract class Tools { ...@@ -130,17 +128,6 @@ public abstract class Tools {
130 } 128 }
131 129
132 /** 130 /**
133 - * Returns a loggable scheduled executor service that allows to capture and
134 - * log any exceptions if the scheduled tasks are failed during execution.
135 - *
136 - * @param executor scheduled executor service
137 - * @return loggable scheduled executor service
138 - */
139 - public static ScheduledExecutorService loggableScheduledExecutor(ScheduledExecutorService executor) {
140 - return new LogScheduledExecutorService(executor);
141 - }
142 -
143 - /**
144 * Returns a thread factory that produces threads with MIN_PRIORITY. 131 * Returns a thread factory that produces threads with MIN_PRIORITY.
145 * 132 *
146 * @param factory backing ThreadFactory 133 * @param factory backing ThreadFactory
......
1 +/*
2 + * Copyright 2016 Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onlab.util;
17 +
18 +import org.junit.Test;
19 +
20 +import java.util.concurrent.ScheduledExecutorService;
21 +
22 +import static org.junit.Assert.assertNotNull;
23 +import static org.junit.Assert.assertSame;
24 +
25 +/**
26 + * Tests of the SharedScheduledExecutors.
27 + */
28 +public class SharedScheduledExecutorsTest {
29 +
30 + @Test
31 + public void singleThread() {
32 + ScheduledExecutorService a = SharedScheduledExecutors.getSingleThreadExecutor();
33 + assertNotNull("ScheduledExecutorService must not be null", a);
34 + ScheduledExecutorService b = SharedScheduledExecutors.getSingleThreadExecutor();
35 + assertSame("factories should be same", a, b);
36 + }
37 +
38 + @Test
39 + public void poolThread() {
40 + ScheduledExecutorService a = SharedScheduledExecutors.getPoolThreadExecutor();
41 + assertNotNull("ScheduledExecutorService must not be null", a);
42 + ScheduledExecutorService b = SharedScheduledExecutors.getPoolThreadExecutor();
43 + assertSame("factories should be same", a, b);
44 + }
45 +}