|
37 | 37 | import java.util.Set; |
38 | 38 |
|
39 | 39 | /** |
40 | | - * Registry for built-in Java plugins (not installed via logstash-plugin) |
41 | | - */ |
| 40 | + * Registry for built-in Java plugins (not installed via logstash-plugin). |
| 41 | + * This is singleton ofr two reasons: |
| 42 | + * <ul> |
| 43 | + * <li>it's a registry so no need for multiple instances</li> |
| 44 | + * <li>the Reflections library used need to run in single thread during discovery phase</li> |
| 45 | + * </ul> |
| 46 | + * */ |
42 | 47 | public final class PluginRegistry { |
43 | 48 |
|
44 | 49 | private final Map<String, Class<Input>> inputs = new HashMap<>(); |
45 | 50 | private final Map<String, Class<Filter>> filters = new HashMap<>(); |
46 | 51 | private final Map<String, Class<Output>> outputs = new HashMap<>(); |
47 | 52 | private final Map<String, Class<Codec>> codecs = new HashMap<>(); |
| 53 | + private static final Object lock = new Object(); |
| 54 | + private static PluginRegistry instance; |
48 | 55 |
|
49 | | - public PluginRegistry() { |
| 56 | + private PluginRegistry() { |
50 | 57 | discoverPlugins(); |
51 | 58 | } |
| 59 | + |
| 60 | + public static PluginRegistry getInstance() { |
| 61 | + if (instance == null) { |
| 62 | + synchronized (lock) { |
| 63 | + if (instance == null) { |
| 64 | + instance = new PluginRegistry(); |
| 65 | + } |
| 66 | + } |
| 67 | + } |
| 68 | + return instance; |
| 69 | + } |
52 | 70 |
|
53 | 71 | @SuppressWarnings("unchecked") |
54 | 72 | private void discoverPlugins() { |
| 73 | + // the constructor of Reflection must be called only by one thread, else there is a |
| 74 | + // risk that the first thread that completes close the Zip files for the others. |
55 | 75 | Reflections reflections = new Reflections("org.logstash.plugins"); |
56 | 76 | Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(LogstashPlugin.class); |
57 | 77 | for (final Class<?> cls : annotated) { |
|
0 commit comments