refactor Ttl scheduler with joda; use ConfProperties fully

This commit is contained in:
nicu marasoiu
2015-03-13 12:37:38 +02:00
parent a2879eae4c
commit 88d98de7ae
3 changed files with 39 additions and 19 deletions

View File

@@ -118,7 +118,7 @@
<dependency>
<groupId>com.ecwid.consul</groupId>
<artifactId>consul-api</artifactId>
<version>1.0</version>
<version>1.0.8</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
@@ -177,6 +177,11 @@
<artifactId>ribbon-httpclient</artifactId>
<version>${ribbon.version}</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

View File

@@ -47,6 +47,10 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -5,9 +5,15 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.PostConstruct;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.Period;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -20,34 +26,39 @@ import com.ecwid.consul.v1.agent.model.NewService;
* Created by nicu on 11.03.2015.
*/
@Slf4j
@ConfigurationProperties
@ConfigurationProperties(prefix = "consul.heartbeat")
public class TtlScheduler {
private final Map<String, Long> serviceHeartbeats = new ConcurrentHashMap<>();
public static final DateTime EXPIRED_DATE = new DateTime(0);
private final Map<String, DateTime> serviceHeartbeats = new ConcurrentHashMap<>();
private final AtomicBoolean heartbeatingNow = new AtomicBoolean();
@Value("${consul.ttl:3}")
private volatile int ttl;
@Min(1)
@Max(10)
private volatile int ttl = 3;
@Value("${consul.heartbeatIntervalRatio:0.66}")
private volatile float heartbeatIntervalRatio;
@DecimalMin("0.1")
@DecimalMax("0.9")
private volatile double intervalRatio = 2.0/3.0;
private volatile int heartbeatInterval;
private volatile Period heartbeatInterval;
@Autowired
private ConsulClient client;
@PostConstruct
public void computeHeartbeatInterval() {
// heartbeat rate at ratio * ttl, but no later than ttl -1s and, (under lesser priority), no sooner than 1s from now
heartbeatInterval = Math.round(Math.max(ttl - 1, Math.min(ttl * heartbeatIntervalRatio, 1)));
}
public void computeHeartbeatInterval() {
// heartbeat rate at ratio * ttl, but no later than ttl -1s and, (under lesser
// priority), no sooner than 1s from now
heartbeatInterval = new Period(Math.round(1000 * Math.max(ttl - 1,
Math.min(ttl * intervalRatio, 1))));
}
/**
* Add a service to the checks loop.
*/
public void add(final NewService service) {
serviceHeartbeats.put(service.getId(), 0L);
serviceHeartbeats.put(service.getId(), EXPIRED_DATE);
}
public void remove(String serviceId) {
@@ -58,15 +69,15 @@ public class TtlScheduler {
return ttl;
}
@Scheduled(initialDelay = 0, fixedRate = 100)
@Scheduled(initialDelay = 0, fixedRateString = "${consul.heartbeat.fixedRate:201000}")
private void heartbeatServices() {
if (heartbeatingNow.compareAndSet(false, true)) {
for (String serviceId : serviceHeartbeats.keySet()) {
long latestHeartbeatDoneForService = serviceHeartbeats.get(serviceId);
if (latestHeartbeatDoneForService + heartbeatInterval <= System
.currentTimeMillis()) {
DateTime latestHeartbeatDoneForService = serviceHeartbeats.get(serviceId);
if (latestHeartbeatDoneForService.plus(heartbeatInterval).isBefore(
new DateTime())) {
client.agentCheckPass(serviceId);
serviceHeartbeats.put(serviceId, System.currentTimeMillis());
serviceHeartbeats.put(serviceId, new DateTime());
}
}
}