Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
123 changes: 118 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,19 @@
<updatePolicy>daily</updatePolicy>
</snapshots>
</repository>
<repository>
<id>sonatype-ossrh-snapshots</id>
<name>Sonatype OSSRH Snapshots</name>
<url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>

</repositories>

<dependencies>
Expand Down Expand Up @@ -97,6 +110,23 @@
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>

<!-- Jedis Dependencies -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>7.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-circuitbreaker</artifactId>
<version>1.7.1</version>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-retry</artifactId>
<version>1.7.1</version>
</dependency>
</dependencies>

<build>
Expand All @@ -121,10 +151,93 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>


</plugins>
</build>
</project>
<profiles>
<profile>
<id>lettuce</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<finalName>lettuce-test-app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>io.lettuce.test.LettuceTestApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>jedis</id>
<build>
<finalName>jedis-test-app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>redis.clients.jedis.test.JedisTestApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>all</id>
<build>
<finalName>lettuce-test-app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>io.lettuce.test.LettuceTestApplication</mainClass>
</configuration>
<executions>
<execution>
<id>repackage-jedis</id>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<mainClass>redis.clients.jedis.test.JedisTestApplication</mainClass>
<classifier>jedis</classifier>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>rename-artifacts</id>
<phase>package</phase>
<configuration>
<target>
<copy file="${project.build.directory}/lettuce-test-app-jedis.jar" tofile="${project.build.directory}/jedis-test-app.jar" overwrite="true"/>
<delete file="${project.build.directory}/lettuce-test-app-jedis.jar"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>

</plugins>
</build>
</profile>

</profiles>

</project>
4 changes: 2 additions & 2 deletions src/main/java/io/lettuce/test/config/TestRunProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ public class TestRunProperties {
private String instanceId;

/**
* Application name for identification purposes. Defaults to "lettuce-test-app".
* Application name for identification purposes. Defaults to spring.application.name.
*/
@Value("${appName:lettuce-test-app}")
@Value("${appName:${spring.application.name}}")
private String appName;

public String getRunId() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

@Configuration
@ConfigurationProperties(prefix = "runner")
@PropertySource(value = "classpath:runner-config-defaults.yaml", factory = YamlPropertySourceFactory.class)
@PropertySource(value = "classpath:${runner.defaults:runner-config-defaults.yaml}", factory = YamlPropertySourceFactory.class)
@PropertySource(value = "file:${runner.config:runner-config.yaml}", factory = YamlPropertySourceFactory.class, ignoreResourceNotFound = true)
public class WorkloadRunnerConfig {

Expand Down
6 changes: 3 additions & 3 deletions src/main/java/io/lettuce/test/metrics/MetricsReporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public Timer.Sample startTimer() {
return Timer.start(meterRegistry);
}

Timer.Sample startCommandTimer() {
public Timer.Sample startCommandTimer() {
return Timer.start(meterRegistry);
}

Expand All @@ -152,7 +152,7 @@ public record CommandKey(String commandName, OperationStatus status) {

}

void recordCommandLatency(CommandKey commandKey, Timer.Sample sample) {
public void recordCommandLatency(CommandKey commandKey, Timer.Sample sample) {
Timer timer = commandLatencyTimers.computeIfAbsent(commandKey, this::createCommandLatencyTimer);
long timeNs = sample.stop(timer);

Expand All @@ -162,7 +162,7 @@ void recordCommandLatency(CommandKey commandKey, Timer.Sample sample) {
counter.increment();
}

void incrementCommandError(String commandName) {
public void incrementCommandError(String commandName) {
commandErrorCounters.computeIfAbsent(commandName, this::createCommandErrorCounter).increment();
commandErrorTotalCounter.increment();
}
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/io/lettuce/test/workloads/BaseWorkload.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ public enum Status {

protected MetricsReporter metricsReporter;

private final CommonWorkloadOptions options;
protected final CommonWorkloadOptions options;

private final KeyGenerator keyGenerator;
protected final KeyGenerator keyGenerator;

public BaseWorkload() {
options = DefaultWorkloadOptions.DEFAULT;
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/redis/clients/jedis/test/JedisRunner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package redis.clients.jedis.test;

public interface JedisRunner extends AutoCloseable {

void run();

}
37 changes: 37 additions & 0 deletions src/main/java/redis/clients/jedis/test/JedisTestApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package redis.clients.jedis.test;

import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.HashMap;
import java.util.Map;

@SpringBootApplication(scanBasePackages = { "io.lettuce.test.metrics", "io.lettuce.test.config", "redis.clients.jedis.test" })
public class JedisTestApplication implements ApplicationRunner {

private final JedisWorkloadRunner runner;

public JedisTestApplication(JedisWorkloadRunner runner) {
this.runner = runner;
}

public static void main(String[] args) {
// Ensure Jedis-specific app name overrides application.properties
System.setProperty("spring.application.name", "jedis-test-app");
// Ensure appName property (used in metrics tags) aligns with the app name
System.setProperty("appName", "jedis-test-app");

SpringApplication app = new SpringApplication(JedisTestApplication.class);
Map<String, Object> defaults = new HashMap<>();
defaults.put("runner.defaults", "runner-config-defaults-jedis.yaml");
app.setDefaultProperties(defaults);
app.run(args);
}

@Override
public void run(ApplicationArguments args) {
runner.run();
}

}
50 changes: 50 additions & 0 deletions src/main/java/redis/clients/jedis/test/JedisWorkloadRunner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package redis.clients.jedis.test;

import io.lettuce.test.config.WorkloadRunnerConfig;
import io.lettuce.test.metrics.MetricsReporter;
import jakarta.annotation.PreDestroy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class JedisWorkloadRunner {

private static final Logger log = LoggerFactory.getLogger(JedisWorkloadRunner.class);

private final MetricsReporter metricsReporter;

private final WorkloadRunnerConfig config;

private JedisRunner runner;

public JedisWorkloadRunner(MetricsReporter metricsReporter, WorkloadRunnerConfig config) {
this.metricsReporter = metricsReporter;
this.config = config;
}

public void run() {
switch (config.getTest().getMode().toUpperCase()) {
case "STANDALONE" -> {
runner = new StandaloneJedisWorkloadRunner(config, metricsReporter);
log.info("Running standalone workload (Jedis/UnifiedJedis)");
}
default -> throw new IllegalArgumentException("Unsupported mode for Jedis app: " + config.getTest().getMode()
+ ". Only STANDALONE is supported for Jedis right now.");
}
runner.run();
}

@PreDestroy
private void shutdown() {
log.info("Shutting down (Jedis app)...");
if (runner != null) {
try {
runner.close();
} catch (Exception e) {
log.warn("Error closing Jedis runner", e);
}
}
}

}
24 changes: 24 additions & 0 deletions src/main/java/redis/clients/jedis/test/SchedulerConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package redis.clients.jedis.test;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

@Configuration
@EnableScheduling
public class SchedulerConfig {

@Bean
@Qualifier("metricReporterScheduler")
public TaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(1); // Set pool size to 1 for a single thread
scheduler.setDaemon(true); // Make the thread a daemon thread
scheduler.setThreadNamePrefix("metrics-reporter-");
return scheduler;
}

}
Loading