Skip to content

Commit 8f639ad

Browse files
artembilangaryrussell
authored andcommitted
Move LeaderInitiators to later phase
There is a race condition when Zookeeper `LeaderInitiator` may start earlier than `CuratorFramework` it depends on. This is because both of them are configured for the same default `phase` (`0`) * Make `LeaderInitiator` and `LockRegistryLeaderInitiator` to be started in the `Integer.MAX_VALUE - 1000` phase by default - as late as possible * Make `CuratorFrameworkFactoryBean` to start in the `Integer.MIN_VALUE + 1000` phase - as early as possible * Alight lifecycle properties from the `LeaderInitiatorFactoryBean` with defaults in the `LeaderInitiator` * Simplify a `LeaderListenerParser` to rely on the `LeaderInitiatorFactoryBean` **Cherry-pick to 5.0.x**
1 parent 5e47a6a commit 8f639ad

File tree

5 files changed

+28
-34
lines changed

5 files changed

+28
-34
lines changed

spring-integration-core/src/main/java/org/springframework/integration/support/leader/LockRegistryLeaderInitiator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public String getRole() {
151151
/**
152152
* @see SmartLifecycle which is an extension of org.springframework.context.Phased
153153
*/
154-
private int phase;
154+
private int phase = Integer.MAX_VALUE - 1000;
155155

156156
/**
157157
* Flag that indicates whether the leadership election for this {@link #candidate} is

spring-integration-zookeeper/src/main/java/org/springframework/integration/zookeeper/config/CuratorFrameworkFactoryBean.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2016 the original author or authors.
2+
* Copyright 2015-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,10 +27,11 @@
2727
import org.springframework.util.Assert;
2828

2929
/**
30-
* A spring-friendly way to build a {@link CuratorFramework} and implementing {@link SmartLifecycle}.
30+
* A Spring-friendly way to build a {@link CuratorFramework} and implementing {@link SmartLifecycle}.
3131
*
3232
* @author Gary Russell
3333
* @author Artem Bilan
34+
*
3435
* @since 4.2
3536
*/
3637
public class CuratorFrameworkFactoryBean implements FactoryBean<CuratorFramework>, SmartLifecycle {
@@ -42,17 +43,17 @@ public class CuratorFrameworkFactoryBean implements FactoryBean<CuratorFramework
4243
/**
4344
* @see SmartLifecycle
4445
*/
45-
private volatile boolean autoStartup = true;
46+
private boolean autoStartup = true;
4647

4748
/**
4849
* @see SmartLifecycle
4950
*/
50-
private volatile boolean running;
51+
private int phase = Integer.MIN_VALUE + 1000;
5152

5253
/**
5354
* @see SmartLifecycle
5455
*/
55-
private volatile int phase;
56+
private volatile boolean running;
5657

5758

5859
/**
@@ -135,7 +136,7 @@ public void stop(Runnable runnable) {
135136
}
136137

137138
@Override
138-
public CuratorFramework getObject() throws Exception {
139+
public CuratorFramework getObject() {
139140
return this.client;
140141
}
141142

spring-integration-zookeeper/src/main/java/org/springframework/integration/zookeeper/config/LeaderInitiatorFactoryBean.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2016 the original author or authors.
2+
* Copyright 2015-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -36,6 +36,7 @@
3636
*
3737
* @author Gary Russell
3838
* @author Artem Bilan
39+
*
3940
* @since 4.2
4041
*/
4142
public class LeaderInitiatorFactoryBean
@@ -51,7 +52,7 @@ public class LeaderInitiatorFactoryBean
5152

5253
private boolean autoStartup = true;
5354

54-
private int phase;
55+
private int phase = Integer.MAX_VALUE - 1000;
5556

5657
private ApplicationEventPublisher applicationEventPublisher;
5758

@@ -136,11 +137,11 @@ public int getPhase() {
136137
if (this.leaderInitiator != null) {
137138
return this.leaderInitiator.getPhase();
138139
}
139-
return 0;
140+
return this.phase;
140141
}
141142

142143
@Override
143-
public void afterPropertiesSet() throws Exception {
144+
public void afterPropertiesSet() {
144145
if (this.leaderInitiator == null) {
145146
this.leaderInitiator = new LeaderInitiator(this.client, this.candidate, this.path);
146147
this.leaderInitiator.setPhase(this.phase);
@@ -156,7 +157,7 @@ else if (this.applicationEventPublisher != null) {
156157
}
157158

158159
@Override
159-
public synchronized LeaderInitiator getObject() throws Exception {
160+
public synchronized LeaderInitiator getObject() {
160161
return this.leaderInitiator;
161162
}
162163

spring-integration-zookeeper/src/main/java/org/springframework/integration/zookeeper/config/xml/LeaderListenerParser.java

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2015-2016 the original author or authors.
2+
* Copyright 2015-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,42 +16,34 @@
1616

1717
package org.springframework.integration.zookeeper.config.xml;
1818

19-
import java.util.UUID;
20-
2119
import org.w3c.dom.Element;
2220

2321
import org.springframework.beans.factory.support.AbstractBeanDefinition;
2422
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2523
import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
2624
import org.springframework.beans.factory.xml.ParserContext;
2725
import org.springframework.integration.config.xml.IntegrationNamespaceUtils;
28-
import org.springframework.integration.leader.DefaultCandidate;
29-
import org.springframework.integration.leader.event.DefaultLeaderEventPublisher;
30-
import org.springframework.integration.zookeeper.leader.LeaderInitiator;
26+
import org.springframework.integration.zookeeper.config.LeaderInitiatorFactoryBean;
3127

3228
/**
3329
* @author Gary Russell
30+
* @author Artem Bilan
31+
*
3432
* @since 4.2
3533
*
3634
*/
3735
public class LeaderListenerParser extends AbstractBeanDefinitionParser {
3836

3937
@Override
4038
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
41-
BeanDefinitionBuilder candidateBuilder = BeanDefinitionBuilder.genericBeanDefinition(DefaultCandidate.class);
42-
candidateBuilder.addConstructorArgValue(UUID.randomUUID().toString());
43-
candidateBuilder.addConstructorArgValue(element.getAttribute("role"));
44-
45-
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(LeaderInitiator.class);
46-
builder.addConstructorArgReference(element.getAttribute("client"));
47-
builder.addConstructorArgValue(candidateBuilder.getBeanDefinition());
48-
builder.addConstructorArgValue(element.getAttribute("path"));
49-
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "auto-startup");
50-
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "phase");
51-
52-
BeanDefinitionBuilder publisherBuilder = BeanDefinitionBuilder
53-
.genericBeanDefinition(DefaultLeaderEventPublisher.class);
54-
builder.addPropertyValue("leaderEventPublisher", publisherBuilder.getBeanDefinition());
39+
BeanDefinitionBuilder builder =
40+
BeanDefinitionBuilder.genericBeanDefinition(LeaderInitiatorFactoryBean.class)
41+
.addPropertyReference("client", element.getAttribute("client"))
42+
.addPropertyValue("role", element.getAttribute(IntegrationNamespaceUtils.ROLE))
43+
.addPropertyValue("path", element.getAttribute("path"));
44+
45+
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, IntegrationNamespaceUtils.AUTO_STARTUP);
46+
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, IntegrationNamespaceUtils.PHASE);
5547

5648
return builder.getBeanDefinition();
5749
}

spring-integration-zookeeper/src/main/java/org/springframework/integration/zookeeper/leader/LeaderInitiator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014-2017 the original author or authors.
2+
* Copyright 2014-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -88,7 +88,7 @@ public String getRole() {
8888
/**
8989
* @see SmartLifecycle which is an extension of org.springframework.context.Phased
9090
*/
91-
private volatile int phase;
91+
private volatile int phase = Integer.MAX_VALUE - 1000;
9292

9393
/**
9494
* Flag that indicates whether the leadership election for

0 commit comments

Comments
 (0)