Add automatic acquisition scheduler runtime
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
package com.litoralregas.backend;
|
||||
|
||||
import com.litoralregas.backend.acquisition.scheduler.AcquisitionSchedulerProperties;
|
||||
import com.litoralregas.backend.modbus.ModbusConnectionProperties;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableConfigurationProperties(ModbusConnectionProperties.class)
|
||||
@EnableConfigurationProperties({ModbusConnectionProperties.class, AcquisitionSchedulerProperties.class})
|
||||
public class BackendApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package com.litoralregas.backend.acquisition.scheduler;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
public class AcquisitionRuntimeStatus {
|
||||
|
||||
private boolean running;
|
||||
|
||||
private Instant lastStartedAt;
|
||||
|
||||
private Instant lastFinishedAt;
|
||||
|
||||
private Integer lastSuccessfulReads;
|
||||
|
||||
private Integer lastFailedReads;
|
||||
|
||||
private String lastError;
|
||||
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
public void setRunning(boolean running) {
|
||||
this.running = running;
|
||||
}
|
||||
|
||||
public Instant getLastStartedAt() {
|
||||
return lastStartedAt;
|
||||
}
|
||||
|
||||
public void setLastStartedAt(Instant lastStartedAt) {
|
||||
this.lastStartedAt = lastStartedAt;
|
||||
}
|
||||
|
||||
public Instant getLastFinishedAt() {
|
||||
return lastFinishedAt;
|
||||
}
|
||||
|
||||
public void setLastFinishedAt(Instant lastFinishedAt) {
|
||||
this.lastFinishedAt = lastFinishedAt;
|
||||
}
|
||||
|
||||
public Integer getLastSuccessfulReads() {
|
||||
return lastSuccessfulReads;
|
||||
}
|
||||
|
||||
public void setLastSuccessfulReads(Integer lastSuccessfulReads) {
|
||||
this.lastSuccessfulReads = lastSuccessfulReads;
|
||||
}
|
||||
|
||||
public Integer getLastFailedReads() {
|
||||
return lastFailedReads;
|
||||
}
|
||||
|
||||
public void setLastFailedReads(Integer lastFailedReads) {
|
||||
this.lastFailedReads = lastFailedReads;
|
||||
}
|
||||
|
||||
public String getLastError() {
|
||||
return lastError;
|
||||
}
|
||||
|
||||
public void setLastError(String lastError) {
|
||||
this.lastError = lastError;
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.litoralregas.backend.acquisition.scheduler;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
|
||||
@Configuration
|
||||
public class AcquisitionSchedulerConfig {
|
||||
|
||||
@Bean
|
||||
public TaskScheduler acquisitionTaskScheduler() {
|
||||
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
|
||||
scheduler.setPoolSize(1);
|
||||
scheduler.setThreadNamePrefix("acquisition-scheduler-");
|
||||
scheduler.initialize();
|
||||
return scheduler;
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.litoralregas.backend.acquisition.scheduler;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@ConfigurationProperties(prefix = "litoralregas.acquisition.scheduler")
|
||||
public class AcquisitionSchedulerProperties {
|
||||
|
||||
private boolean enabled = false;
|
||||
private long fixedDelayMillis = 3000;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public long getFixedDelayMillis() {
|
||||
return fixedDelayMillis;
|
||||
}
|
||||
|
||||
public void setFixedDelayMillis(long fixedDelayMillis) {
|
||||
this.fixedDelayMillis = fixedDelayMillis;
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
package com.litoralregas.backend.acquisition.scheduler;
|
||||
|
||||
import com.litoralregas.backend.acquisition.polling.AcquisitionPollResult;
|
||||
import com.litoralregas.backend.acquisition.block.BlockPollingService;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@Service
|
||||
public class AcquisitionSchedulerService {
|
||||
|
||||
private final BlockPollingService blockPollingService;
|
||||
private final AcquisitionSchedulerProperties properties;
|
||||
private final TaskScheduler taskScheduler;
|
||||
|
||||
private final AcquisitionRuntimeStatus runtimeStatus = new AcquisitionRuntimeStatus();
|
||||
|
||||
private final AtomicBoolean polling = new AtomicBoolean(false);
|
||||
|
||||
public AcquisitionSchedulerService(
|
||||
BlockPollingService blockPollingService,
|
||||
AcquisitionSchedulerProperties properties,
|
||||
TaskScheduler taskScheduler
|
||||
) {
|
||||
this.blockPollingService = blockPollingService;
|
||||
this.properties = properties;
|
||||
this.taskScheduler = taskScheduler;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void startScheduler() {
|
||||
if (!properties.isEnabled()) {
|
||||
System.out.println("Acquisition scheduler disabled.");
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("Starting acquisition scheduler.");
|
||||
|
||||
taskScheduler.scheduleWithFixedDelay(
|
||||
this::safePoll,
|
||||
properties.getFixedDelayMillis()
|
||||
);
|
||||
}
|
||||
|
||||
public AcquisitionRuntimeStatus getRuntimeStatus() {
|
||||
return runtimeStatus;
|
||||
}
|
||||
|
||||
private void safePoll() {
|
||||
if (!polling.compareAndSet(false, true)) {
|
||||
System.out.println("Skipping acquisition cycle because previous cycle is still running.");
|
||||
return;
|
||||
}
|
||||
|
||||
runtimeStatus.setRunning(true);
|
||||
runtimeStatus.setLastStartedAt(Instant.now());
|
||||
runtimeStatus.setLastError(null);
|
||||
|
||||
try {
|
||||
AcquisitionPollResult result = blockPollingService.pollOnceByBlocks();
|
||||
|
||||
runtimeStatus.setLastSuccessfulReads(result.successfulReads());
|
||||
runtimeStatus.setLastFailedReads(result.failedReads());
|
||||
|
||||
} catch (Exception exception) {
|
||||
runtimeStatus.setLastError(exception.getMessage());
|
||||
|
||||
exception.printStackTrace();
|
||||
|
||||
} finally {
|
||||
runtimeStatus.setRunning(false);
|
||||
runtimeStatus.setLastFinishedAt(Instant.now());
|
||||
|
||||
polling.set(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,4 +21,8 @@ litoralregas:
|
||||
port: 533
|
||||
timeout-millis: 500
|
||||
max-attempts: 3
|
||||
retry-delay-millis: 1000
|
||||
retry-delay-millis: 1000
|
||||
acquisition:
|
||||
scheduler:
|
||||
enabled: true
|
||||
fixed-delay-millis: 3000
|
||||
Reference in New Issue
Block a user