mirror of https://github.com/apache/lucene.git
SOLR-12668: Autoscaling trigger listeners should be executed in the order of their creation.
This commit is contained in:
parent
a661ebc6df
commit
9572e129f8
|
@ -241,6 +241,8 @@ Bug Fixes
|
||||||
|
|
||||||
* SOLR-12670: RecoveryStrategy logs wrong wait time when retrying recovery. (shalin)
|
* SOLR-12670: RecoveryStrategy logs wrong wait time when retrying recovery. (shalin)
|
||||||
|
|
||||||
|
* SOLR-12668: Autoscaling trigger listeners should be executed in the order of their creation. (ab)
|
||||||
|
|
||||||
Optimizations
|
Optimizations
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
|
|
@ -500,6 +500,7 @@ public class TriggerIntegrationTest extends SolrCloudTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Map<String, List<CapturedEvent>> listenerEvents = new HashMap<>();
|
static Map<String, List<CapturedEvent>> listenerEvents = new HashMap<>();
|
||||||
|
static List<CapturedEvent> allListenerEvents = new ArrayList<>();
|
||||||
static CountDownLatch listenerCreated = new CountDownLatch(1);
|
static CountDownLatch listenerCreated = new CountDownLatch(1);
|
||||||
static boolean failDummyAction = false;
|
static boolean failDummyAction = false;
|
||||||
|
|
||||||
|
@ -514,7 +515,9 @@ public class TriggerIntegrationTest extends SolrCloudTestCase {
|
||||||
public synchronized void onEvent(TriggerEvent event, TriggerEventProcessorStage stage, String actionName,
|
public synchronized void onEvent(TriggerEvent event, TriggerEventProcessorStage stage, String actionName,
|
||||||
ActionContext context, Throwable error, String message) {
|
ActionContext context, Throwable error, String message) {
|
||||||
List<CapturedEvent> lst = listenerEvents.computeIfAbsent(config.name, s -> new ArrayList<>());
|
List<CapturedEvent> lst = listenerEvents.computeIfAbsent(config.name, s -> new ArrayList<>());
|
||||||
lst.add(new CapturedEvent(timeSource.getTimeNs(), context, config, stage, actionName, event, message));
|
CapturedEvent ev = new CapturedEvent(timeSource.getTimeNs(), context, config, stage, actionName, event, message);
|
||||||
|
lst.add(ev);
|
||||||
|
allListenerEvents.add(ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,10 +630,28 @@ public class TriggerIntegrationTest extends SolrCloudTestCase {
|
||||||
|
|
||||||
assertEquals(TriggerEventProcessorStage.SUCCEEDED, capturedEvents.get(3).stage);
|
assertEquals(TriggerEventProcessorStage.SUCCEEDED, capturedEvents.get(3).stage);
|
||||||
|
|
||||||
|
// check global ordering of events (SOLR-12668)
|
||||||
|
int fooIdx = -1;
|
||||||
|
int barIdx = -1;
|
||||||
|
for (int i = 0; i < allListenerEvents.size(); i++) {
|
||||||
|
CapturedEvent ev = allListenerEvents.get(i);
|
||||||
|
if (ev.stage == TriggerEventProcessorStage.BEFORE_ACTION && ev.actionName.equals("test")) {
|
||||||
|
if (ev.config.name.equals("foo")) {
|
||||||
|
fooIdx = i;
|
||||||
|
} else if (ev.config.name.equals("bar")) {
|
||||||
|
barIdx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue("fooIdx not found", fooIdx != -1);
|
||||||
|
assertTrue("barIdx not found", barIdx != -1);
|
||||||
|
assertTrue("foo fired later than bar: fooIdx=" + fooIdx + ", barIdx=" + barIdx, fooIdx < barIdx);
|
||||||
|
|
||||||
// reset
|
// reset
|
||||||
triggerFired.set(false);
|
triggerFired.set(false);
|
||||||
triggerFiredLatch = new CountDownLatch(1);
|
triggerFiredLatch = new CountDownLatch(1);
|
||||||
listenerEvents.clear();
|
listenerEvents.clear();
|
||||||
|
allListenerEvents.clear();
|
||||||
failDummyAction = true;
|
failDummyAction = true;
|
||||||
|
|
||||||
newNode = cluster.startJettySolrRunner();
|
newNode = cluster.startJettySolrRunner();
|
||||||
|
|
|
@ -905,6 +905,7 @@ public class TestTriggerIntegration extends SimSolrCloudTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Map<String, List<CapturedEvent>> listenerEvents = new ConcurrentHashMap<>();
|
static Map<String, List<CapturedEvent>> listenerEvents = new ConcurrentHashMap<>();
|
||||||
|
static List<CapturedEvent> allListenerEvents = new ArrayList<>();
|
||||||
static CountDownLatch listenerCreated = new CountDownLatch(1);
|
static CountDownLatch listenerCreated = new CountDownLatch(1);
|
||||||
static boolean failDummyAction = false;
|
static boolean failDummyAction = false;
|
||||||
|
|
||||||
|
@ -919,7 +920,9 @@ public class TestTriggerIntegration extends SimSolrCloudTestCase {
|
||||||
public synchronized void onEvent(TriggerEvent event, TriggerEventProcessorStage stage, String actionName,
|
public synchronized void onEvent(TriggerEvent event, TriggerEventProcessorStage stage, String actionName,
|
||||||
ActionContext context, Throwable error, String message) {
|
ActionContext context, Throwable error, String message) {
|
||||||
List<CapturedEvent> lst = listenerEvents.computeIfAbsent(config.name, s -> new ArrayList<>());
|
List<CapturedEvent> lst = listenerEvents.computeIfAbsent(config.name, s -> new ArrayList<>());
|
||||||
lst.add(new CapturedEvent(cluster.getTimeSource().getTimeNs(), context, config, stage, actionName, event, message));
|
CapturedEvent ev = new CapturedEvent(cluster.getTimeSource().getTimeNs(), context, config, stage, actionName, event, message);
|
||||||
|
lst.add(ev);
|
||||||
|
allListenerEvents.add(ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1033,6 +1036,23 @@ public class TestTriggerIntegration extends SimSolrCloudTestCase {
|
||||||
|
|
||||||
assertEquals(TriggerEventProcessorStage.SUCCEEDED, testEvents.get(3).stage);
|
assertEquals(TriggerEventProcessorStage.SUCCEEDED, testEvents.get(3).stage);
|
||||||
|
|
||||||
|
// check global ordering of events (SOLR-12668)
|
||||||
|
int fooIdx = -1;
|
||||||
|
int barIdx = -1;
|
||||||
|
for (int i = 0; i < allListenerEvents.size(); i++) {
|
||||||
|
CapturedEvent ev = allListenerEvents.get(i);
|
||||||
|
if (ev.stage == TriggerEventProcessorStage.BEFORE_ACTION && ev.actionName.equals("test")) {
|
||||||
|
if (ev.config.name.equals("foo")) {
|
||||||
|
fooIdx = i;
|
||||||
|
} else if (ev.config.name.equals("bar")) {
|
||||||
|
barIdx = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertTrue("fooIdx not found", fooIdx != -1);
|
||||||
|
assertTrue("barIdx not found", barIdx != -1);
|
||||||
|
assertTrue("foo fired later than bar: fooIdx=" + fooIdx + ", barIdx=" + barIdx, fooIdx < barIdx);
|
||||||
|
|
||||||
// reset
|
// reset
|
||||||
triggerFired.set(false);
|
triggerFired.set(false);
|
||||||
triggerFiredLatch = new CountDownLatch(1);
|
triggerFiredLatch = new CountDownLatch(1);
|
||||||
|
|
|
@ -22,8 +22,8 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.HashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.HashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -72,7 +72,7 @@ public class AutoScalingConfig implements MapWriter {
|
||||||
if (properties == null) {
|
if (properties == null) {
|
||||||
this.properties = Collections.emptyMap();
|
this.properties = Collections.emptyMap();
|
||||||
} else {
|
} else {
|
||||||
this.properties = Collections.unmodifiableMap(new HashMap<>(properties));
|
this.properties = Collections.unmodifiableMap(new LinkedHashMap<>(properties));
|
||||||
}
|
}
|
||||||
trigger = (String)this.properties.get(AutoScalingParams.TRIGGER);
|
trigger = (String)this.properties.get(AutoScalingParams.TRIGGER);
|
||||||
List<Object> stageNames = getList(AutoScalingParams.STAGE, this.properties);
|
List<Object> stageNames = getList(AutoScalingParams.STAGE, this.properties);
|
||||||
|
@ -85,10 +85,10 @@ public class AutoScalingConfig implements MapWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
listenerClass = (String)this.properties.get(AutoScalingParams.CLASS);
|
listenerClass = (String)this.properties.get(AutoScalingParams.CLASS);
|
||||||
Set<String> bActions = new HashSet<>();
|
Set<String> bActions = new LinkedHashSet<>();
|
||||||
getList(AutoScalingParams.BEFORE_ACTION, this.properties).forEach(o -> bActions.add(String.valueOf(o)));
|
getList(AutoScalingParams.BEFORE_ACTION, this.properties).forEach(o -> bActions.add(String.valueOf(o)));
|
||||||
beforeActions = Collections.unmodifiableSet(bActions);
|
beforeActions = Collections.unmodifiableSet(bActions);
|
||||||
Set<String> aActions = new HashSet<>();
|
Set<String> aActions = new LinkedHashSet<>();
|
||||||
getList(AutoScalingParams.AFTER_ACTION, this.properties).forEach(o -> aActions.add(String.valueOf(o)));
|
getList(AutoScalingParams.AFTER_ACTION, this.properties).forEach(o -> aActions.add(String.valueOf(o)));
|
||||||
afterActions = Collections.unmodifiableSet(aActions);
|
afterActions = Collections.unmodifiableSet(aActions);
|
||||||
}
|
}
|
||||||
|
@ -161,7 +161,7 @@ public class AutoScalingConfig implements MapWriter {
|
||||||
public TriggerConfig(String name, Map<String, Object> properties) {
|
public TriggerConfig(String name, Map<String, Object> properties) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
if (properties != null) {
|
if (properties != null) {
|
||||||
this.properties = Collections.unmodifiableMap(new HashMap<>(properties));
|
this.properties = Collections.unmodifiableMap(new LinkedHashMap<>(properties));
|
||||||
} else {
|
} else {
|
||||||
this.properties = Collections.emptyMap();
|
this.properties = Collections.emptyMap();
|
||||||
}
|
}
|
||||||
|
@ -196,7 +196,7 @@ public class AutoScalingConfig implements MapWriter {
|
||||||
* @return modified copy of the configuration
|
* @return modified copy of the configuration
|
||||||
*/
|
*/
|
||||||
public TriggerConfig withEnabled(boolean enabled) {
|
public TriggerConfig withEnabled(boolean enabled) {
|
||||||
Map<String, Object> props = new HashMap<>(properties);
|
Map<String, Object> props = new LinkedHashMap<>(properties);
|
||||||
props.put(AutoScalingParams.ENABLED, String.valueOf(enabled));
|
props.put(AutoScalingParams.ENABLED, String.valueOf(enabled));
|
||||||
return new TriggerConfig(name, props);
|
return new TriggerConfig(name, props);
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ public class AutoScalingConfig implements MapWriter {
|
||||||
* @return modified copy of the configuration
|
* @return modified copy of the configuration
|
||||||
*/
|
*/
|
||||||
public TriggerConfig withProperty(String key, Object value) {
|
public TriggerConfig withProperty(String key, Object value) {
|
||||||
Map<String, Object> props = new HashMap<>(properties);
|
Map<String, Object> props = new LinkedHashMap<>(properties);
|
||||||
props.put(key, String.valueOf(value));
|
props.put(key, String.valueOf(value));
|
||||||
return new TriggerConfig(name, props);
|
return new TriggerConfig(name, props);
|
||||||
}
|
}
|
||||||
|
@ -264,7 +264,7 @@ public class AutoScalingConfig implements MapWriter {
|
||||||
*/
|
*/
|
||||||
public ActionConfig(Map<String, Object> properties) {
|
public ActionConfig(Map<String, Object> properties) {
|
||||||
if (properties != null) {
|
if (properties != null) {
|
||||||
this.properties = Collections.unmodifiableMap(new HashMap<>(properties));
|
this.properties = Collections.unmodifiableMap(new LinkedHashMap<>(properties));
|
||||||
} else {
|
} else {
|
||||||
this.properties = Collections.emptyMap();
|
this.properties = Collections.emptyMap();
|
||||||
}
|
}
|
||||||
|
@ -327,10 +327,10 @@ public class AutoScalingConfig implements MapWriter {
|
||||||
private AutoScalingConfig(Policy policy, Map<String, TriggerConfig> triggerConfigs, Map<String,
|
private AutoScalingConfig(Policy policy, Map<String, TriggerConfig> triggerConfigs, Map<String,
|
||||||
TriggerListenerConfig> listenerConfigs, Map<String, Object> properties, int zkVersion) {
|
TriggerListenerConfig> listenerConfigs, Map<String, Object> properties, int zkVersion) {
|
||||||
this.policy = policy;
|
this.policy = policy;
|
||||||
this.triggers = triggerConfigs != null ? Collections.unmodifiableMap(triggerConfigs) : null;
|
this.triggers = triggerConfigs != null ? Collections.unmodifiableMap(new LinkedHashMap<>(triggerConfigs)) : null;
|
||||||
this.listeners = listenerConfigs != null ? Collections.unmodifiableMap(listenerConfigs) : null;
|
this.listeners = listenerConfigs != null ? Collections.unmodifiableMap(new LinkedHashMap<>(listenerConfigs)) : null;
|
||||||
this.jsonMap = null;
|
this.jsonMap = null;
|
||||||
this.properties = properties != null ? Collections.unmodifiableMap(properties) : null;
|
this.properties = properties != null ? Collections.unmodifiableMap(new LinkedHashMap<>(properties)) : null;
|
||||||
this.zkVersion = zkVersion;
|
this.zkVersion = zkVersion;
|
||||||
this.empty = policy == null &&
|
this.empty = policy == null &&
|
||||||
(triggerConfigs == null || triggerConfigs.isEmpty()) &&
|
(triggerConfigs == null || triggerConfigs.isEmpty()) &&
|
||||||
|
@ -368,7 +368,7 @@ public class AutoScalingConfig implements MapWriter {
|
||||||
if (trigMap == null) {
|
if (trigMap == null) {
|
||||||
triggers = Collections.emptyMap();
|
triggers = Collections.emptyMap();
|
||||||
} else {
|
} else {
|
||||||
HashMap<String, TriggerConfig> newTriggers = new HashMap<>(trigMap.size());
|
Map<String, TriggerConfig> newTriggers = new LinkedHashMap<>(trigMap.size());
|
||||||
for (Map.Entry<String, Object> entry : trigMap.entrySet()) {
|
for (Map.Entry<String, Object> entry : trigMap.entrySet()) {
|
||||||
newTriggers.put(entry.getKey(), new TriggerConfig(entry.getKey(), (Map<String, Object>)entry.getValue()));
|
newTriggers.put(entry.getKey(), new TriggerConfig(entry.getKey(), (Map<String, Object>)entry.getValue()));
|
||||||
}
|
}
|
||||||
|
@ -411,7 +411,7 @@ public class AutoScalingConfig implements MapWriter {
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
listeners = Collections.emptyMap();
|
listeners = Collections.emptyMap();
|
||||||
} else {
|
} else {
|
||||||
HashMap<String, TriggerListenerConfig> newListeners = new HashMap<>(map.size());
|
Map<String, TriggerListenerConfig> newListeners = new LinkedHashMap<>(map.size());
|
||||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||||
newListeners.put(entry.getKey(), new TriggerListenerConfig(entry.getKey(), (Map<String, Object>)entry.getValue()));
|
newListeners.put(entry.getKey(), new TriggerListenerConfig(entry.getKey(), (Map<String, Object>)entry.getValue()));
|
||||||
}
|
}
|
||||||
|
@ -431,7 +431,7 @@ public class AutoScalingConfig implements MapWriter {
|
||||||
if (map == null) {
|
if (map == null) {
|
||||||
this.properties = Collections.emptyMap();
|
this.properties = Collections.emptyMap();
|
||||||
} else {
|
} else {
|
||||||
this.properties = new HashMap<>(map);
|
this.properties = new LinkedHashMap<>(map);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.properties = Collections.emptyMap();
|
this.properties = Collections.emptyMap();
|
||||||
|
@ -473,7 +473,7 @@ public class AutoScalingConfig implements MapWriter {
|
||||||
* @return modified copy of the configuration
|
* @return modified copy of the configuration
|
||||||
*/
|
*/
|
||||||
public AutoScalingConfig withTriggerConfig(TriggerConfig config) {
|
public AutoScalingConfig withTriggerConfig(TriggerConfig config) {
|
||||||
Map<String, TriggerConfig> configs = new HashMap<>(getTriggerConfigs());
|
Map<String, TriggerConfig> configs = new LinkedHashMap<>(getTriggerConfigs());
|
||||||
configs.put(config.name, config);
|
configs.put(config.name, config);
|
||||||
return withTriggerConfigs(configs);
|
return withTriggerConfigs(configs);
|
||||||
}
|
}
|
||||||
|
@ -484,7 +484,7 @@ public class AutoScalingConfig implements MapWriter {
|
||||||
* @return modified copy of the configuration, even if the specified config name didn't exist.
|
* @return modified copy of the configuration, even if the specified config name didn't exist.
|
||||||
*/
|
*/
|
||||||
public AutoScalingConfig withoutTriggerConfig(String name) {
|
public AutoScalingConfig withoutTriggerConfig(String name) {
|
||||||
Map<String, TriggerConfig> configs = new HashMap<>(getTriggerConfigs());
|
Map<String, TriggerConfig> configs = new LinkedHashMap<>(getTriggerConfigs());
|
||||||
configs.remove(name);
|
configs.remove(name);
|
||||||
return withTriggerConfigs(configs);
|
return withTriggerConfigs(configs);
|
||||||
}
|
}
|
||||||
|
@ -504,7 +504,7 @@ public class AutoScalingConfig implements MapWriter {
|
||||||
* @return modified copy of the configuration
|
* @return modified copy of the configuration
|
||||||
*/
|
*/
|
||||||
public AutoScalingConfig withTriggerListenerConfig(TriggerListenerConfig config) {
|
public AutoScalingConfig withTriggerListenerConfig(TriggerListenerConfig config) {
|
||||||
Map<String, TriggerListenerConfig> configs = new HashMap<>(getTriggerListenerConfigs());
|
Map<String, TriggerListenerConfig> configs = new LinkedHashMap<>(getTriggerListenerConfigs());
|
||||||
configs.put(config.name, config);
|
configs.put(config.name, config);
|
||||||
return withTriggerListenerConfigs(configs);
|
return withTriggerListenerConfigs(configs);
|
||||||
}
|
}
|
||||||
|
@ -515,7 +515,7 @@ public class AutoScalingConfig implements MapWriter {
|
||||||
* @return modified copy of the configuration, even if the specified config name didn't exist.
|
* @return modified copy of the configuration, even if the specified config name didn't exist.
|
||||||
*/
|
*/
|
||||||
public AutoScalingConfig withoutTriggerListenerConfig(String name) {
|
public AutoScalingConfig withoutTriggerListenerConfig(String name) {
|
||||||
Map<String, TriggerListenerConfig> configs = new HashMap<>(getTriggerListenerConfigs());
|
Map<String, TriggerListenerConfig> configs = new LinkedHashMap<>(getTriggerListenerConfigs());
|
||||||
configs.remove(name);
|
configs.remove(name);
|
||||||
return withTriggerListenerConfigs(configs);
|
return withTriggerListenerConfigs(configs);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue