1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.logging.log4j.core.async;
19
20 import java.util.concurrent.Callable;
21 import java.util.concurrent.ExecutorService;
22 import java.util.concurrent.Future;
23
24 import org.apache.logging.log4j.Logger;
25 import org.apache.logging.log4j.core.util.Integers;
26 import org.apache.logging.log4j.status.StatusLogger;
27 import org.apache.logging.log4j.util.PropertiesUtil;
28
29 import com.lmax.disruptor.BlockingWaitStrategy;
30 import com.lmax.disruptor.ExceptionHandler;
31 import com.lmax.disruptor.SleepingWaitStrategy;
32 import com.lmax.disruptor.WaitStrategy;
33 import com.lmax.disruptor.YieldingWaitStrategy;
34
35
36
37
38 final class DisruptorUtil {
39 private static final Logger LOGGER = StatusLogger.getLogger();
40 private static final int RINGBUFFER_MIN_SIZE = 128;
41 private static final int RINGBUFFER_DEFAULT_SIZE = 256 * 1024;
42
43 private DisruptorUtil() {
44 }
45
46 static WaitStrategy createWaitStrategy(final String propertyName) {
47 final String strategy = PropertiesUtil.getProperties().getStringProperty(propertyName);
48 if (strategy != null) {
49 LOGGER.trace("property {}={}", propertyName, strategy);
50 if ("Sleep".equalsIgnoreCase(strategy)) {
51 return new SleepingWaitStrategy();
52 } else if ("Yield".equalsIgnoreCase(strategy)) {
53 return new YieldingWaitStrategy();
54 } else if ("Block".equalsIgnoreCase(strategy)) {
55 return new BlockingWaitStrategy();
56 }
57 }
58 return new BlockingWaitStrategy();
59 }
60
61 static int calculateRingBufferSize(final String propertyName) {
62 int ringBufferSize = RINGBUFFER_DEFAULT_SIZE;
63 final String userPreferredRBSize = PropertiesUtil.getProperties().getStringProperty(propertyName,
64 String.valueOf(ringBufferSize));
65 try {
66 int size = Integer.parseInt(userPreferredRBSize);
67 if (size < RINGBUFFER_MIN_SIZE) {
68 size = RINGBUFFER_MIN_SIZE;
69 LOGGER.warn("Invalid RingBufferSize {}, using minimum size {}.", userPreferredRBSize,
70 RINGBUFFER_MIN_SIZE);
71 }
72 ringBufferSize = size;
73 } catch (final Exception ex) {
74 LOGGER.warn("Invalid RingBufferSize {}, using default size {}.", userPreferredRBSize, ringBufferSize);
75 }
76 return Integers.ceilingNextPowerOfTwo(ringBufferSize);
77 }
78
79 static <T> ExceptionHandler<T> getExceptionHandler(final String propertyName, Class<T> type) {
80 final String cls = PropertiesUtil.getProperties().getStringProperty(propertyName);
81 if (cls == null) {
82 return null;
83 }
84 try {
85 @SuppressWarnings("unchecked")
86 final Class<? extends ExceptionHandler<T>> klass = (Class<? extends ExceptionHandler<T>>) Class
87 .forName(cls);
88 return klass.newInstance();
89 } catch (final Exception ignored) {
90 LOGGER.debug("Invalid {} value: error creating {}: ", propertyName, cls, ignored);
91 return null;
92 }
93 }
94
95
96
97
98
99
100
101
102 public static long getExecutorThreadId(final ExecutorService executor) {
103 Future<Long> result = executor.submit(new Callable<Long>() {
104 @Override
105 public Long call() {
106 return Thread.currentThread().getId();
107 }
108 });
109 try {
110 return result.get();
111 } catch (final Exception ex) {
112 final String msg = "Could not obtain executor thread Id. "
113 + "Giving up to avoid the risk of application deadlock.";
114 throw new IllegalStateException(msg, ex);
115 }
116 }
117
118 }