Skip to content

Commit

Permalink
Add CustomerService with virtual threads and update test classes
Browse files Browse the repository at this point in the history
Introduced CustomerService using virtual threads for efficient customer data fetching. Renamed existing test and main classes to reflect their use of virtual threads. Added comprehensive test for CustomerService to validate functionality and performance.
  • Loading branch information
kousen committed Aug 6, 2024
1 parent 8c79d8f commit 53647d3
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 3 deletions.
46 changes: 46 additions & 0 deletions src/main/java/com/kousenit/virtualthreads/CustomerService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.kousenit.virtualthreads;

import java.util.List;
import java.util.concurrent.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class CustomerService {

public List<Customer> fetchCustomerData(List<Integer> customerIds) {
try (ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor()) {
List<CompletableFuture<Customer>> futures = customerIds.stream()
.map(id -> CompletableFuture.supplyAsync(() -> fetchCustomer(id), executor))
.toList();

return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.toList())
.join();
}
}

private Customer fetchCustomer(int id) {
try {
// Simulate API call or database query
Thread.sleep(1000);
return new Customer(id, "Customer " + id, "customer" + id + "@example.com");
} catch (InterruptedException e) {
throw new RuntimeException("Thread interrupted while fetching customer " + id, e);
}
}

// Customer as a record
public record Customer(int id, String name, String email) {}

// Main method for demonstration
public static void main(String[] args) {
CustomerService service = new CustomerService();
List<Integer> customerIds = IntStream.rangeClosed(1, 5)
.boxed()
.collect(Collectors.toList());
List<Customer> customers = service.fetchCustomerData(customerIds);
customers.forEach(System.out::println);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import java.util.stream.IntStream;

// Example from: https://openjdk.org/jeps/444 (Virtual Threads)
public class Demo {
public class VirtualThreadsDemo {
public static void main(String[] args) {
long startTime = System.nanoTime();
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import static org.hamcrest.Matchers.arrayContaining;
import static org.junit.jupiter.api.Assertions.assertThrows;

class SafeVaragsDemoTest {
class SafeVaragsVirtualThreadsDemoTest {
private final SafeVaragsDemo demo = new SafeVaragsDemo();
private final LocalDate now = LocalDate.now();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import static org.junit.jupiter.api.Assertions.assertEquals;

public class PrivateDemoTest {
public class PrivateVirtualThreadsDemoTest {
private final PrivateDemo demo = new PrivateDemo();

@Test
Expand Down
46 changes: 46 additions & 0 deletions src/test/java/com/kousenit/virtualthreads/CustomerServiceTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.kousenit.virtualthreads;

import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.stream.IntStream;

import static com.kousenit.virtualthreads.CustomerService.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

class CustomerServiceTest {

@Test
void testFetchCustomerData() {
CustomerService service = new CustomerService();
List<Integer> customerIds = IntStream.rangeClosed(1, 500)
.boxed()
.toList();

long startTime = System.currentTimeMillis();
var customers = service.fetchCustomerData(customerIds);
long endTime = System.currentTimeMillis();

// Check if we got the correct number of customers
assertEquals(500, customers.size(), "Should fetch 500 customers");

// Verify first and last customer data
Customer firstCustomer = customers.getFirst();
Customer lastCustomer = customers.getLast();

assertEquals(1, firstCustomer.id(), "First customer ID should be 1");
assertEquals("Customer 1", firstCustomer.name(), "First customer name should match");
assertEquals("[email protected]", firstCustomer.email(), "First customer email should match");

assertEquals(500, lastCustomer.id(), "Last customer ID should be 500");
assertEquals("Customer 500", lastCustomer.name(), "Last customer name should match");
assertEquals("[email protected]", lastCustomer.email(), "Last customer email should match");

// Check if the execution time is close to 1 second (allowing some margin)
long executionTime = endTime - startTime;
assertTrue(executionTime >= 1000 && executionTime < 1500,
"Execution time should be close to 1 second, but was " + executionTime + " ms");
System.out.println("Execution time: " + executionTime + " ms");
}
}

0 comments on commit 53647d3

Please sign in to comment.