1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.esigate.extension.parallelesi;
16
17 import java.util.Properties;
18 import java.util.concurrent.Executor;
19 import java.util.concurrent.LinkedBlockingQueue;
20 import java.util.concurrent.ThreadPoolExecutor;
21 import java.util.concurrent.TimeUnit;
22
23 import org.apache.commons.lang3.StringUtils;
24 import org.esigate.Driver;
25 import org.esigate.events.Event;
26 import org.esigate.events.EventDefinition;
27 import org.esigate.events.EventManager;
28 import org.esigate.events.IEventListener;
29 import org.esigate.events.impl.RenderEvent;
30 import org.esigate.extension.Extension;
31 import org.esigate.extension.surrogate.CapabilitiesEvent;
32 import org.esigate.extension.surrogate.Surrogate;
33 import org.esigate.util.Parameter;
34 import org.esigate.util.ParameterInteger;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 public class Esi implements Extension, IEventListener {
58 private static final Logger LOG = LoggerFactory.getLogger(Esi.class);
59
60 public static final Parameter<Integer> MAX_THREADS = new ParameterInteger("esi_max_threads", 0);
61 public static final Parameter<Integer> MIN_THREADS = new ParameterInteger("esi_min_threads", 0);
62 public static final Parameter<Integer> IDLE = new ParameterInteger("esi_max_idle", 60);
63 public static final Parameter<Integer> MAX_QUEUE = new ParameterInteger("esi_max_queue", 10000);
64 private Executor executor;
65 public static final String[] CAPABILITIES = new String[] {"ESI/1.0", "ESI-Inline/1.0", "X-ESI-Fragment/1.0",
66 "X-ESI-Replace/1.0", "X-ESI-XSLT/1.0", "ESIGATE/4.0"};
67
68 @Override
69 public boolean event(EventDefinition id, Event event) {
70 RenderEvent renderEvent = (RenderEvent) event;
71
72 boolean doEsi = true;
73
74
75 if (renderEvent.getHttpResponse() != null
76 && renderEvent.getHttpResponse().containsHeader(Surrogate.H_X_ENABLED_CAPABILITIES)) {
77 String enabledCapabilities =
78 renderEvent.getHttpResponse().getFirstHeader(Surrogate.H_X_ENABLED_CAPABILITIES).getValue();
79
80 doEsi = false;
81 for (String capability : CAPABILITIES) {
82 if (StringUtils.contains(enabledCapabilities, capability)) {
83 doEsi = true;
84 break;
85 }
86 }
87
88 }
89
90 if (doEsi) {
91 renderEvent.getRenderers().add(new EsiRenderer(this.executor));
92 }
93
94
95 return true;
96 }
97
98 @Override
99 public void init(Driver driver, Properties properties) {
100 driver.getEventManager().register(EventManager.EVENT_RENDER_PRE, this);
101
102 driver.getEventManager().register(Surrogate.EVENT_SURROGATE_CAPABILITIES, new IEventListener() {
103 @Override
104 public boolean event(EventDefinition id, Event event) {
105 CapabilitiesEvent capEvent = (CapabilitiesEvent) event;
106 for (String capability : CAPABILITIES) {
107 capEvent.getCapabilities().add(capability);
108 }
109 return true;
110 }
111 });
112
113
114 int maxThreads = MAX_THREADS.getValue(properties);
115 int minThreads = MIN_THREADS.getValue(properties);
116 int idle = IDLE.getValue(properties);
117 int maxQueue = MAX_QUEUE.getValue(properties);
118
119 if (maxThreads == 0) {
120 this.executor = null;
121 LOG.info("Linear ESI processing enabled.");
122 } else {
123 this.executor =
124 new ThreadPoolExecutor(minThreads, maxThreads, idle, TimeUnit.SECONDS,
125 new LinkedBlockingQueue<Runnable>(maxQueue));
126
127 LOG.info("Multi-threaded ESI processing enabled. Thread limit: {}, max idle {}.",
128 String.valueOf(maxThreads), String.valueOf(idle));
129 }
130
131 }
132
133 }