"Ai"와 "Ai 정보들을 이용할 대시보드"를 SSE를 이용하여 실시간으로 처리하려고 합니다.
publish, subscribe 패턴을 사용하여 대시보드를 publish 하려고 합니다.
동기식으로 처리한다면 subscribe 중 인 다른 클라이언트로 인해 지연이 발생합니다.
비동기로 처리하려고 합니다.
하지만, MySql DB에 저장을 하고 사용한다면 다음과 같은 에러를 발생합니다.
Possibly blocking call in non-blocking context could lead to thread starvation
// 1. RedisConfig
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String host; // (1)
@Value("${spring.redis.port}")
private int port; // (2)
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(host, port); // (3)
}
@Bean
public RedisTemplate<?, ?> redisTemplate() { // (4)
RedisTemplate<?, ?> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
return redisTemplate;
}
}
// 2. Entity
@RedisHash(value = "bashboard", timeToLive = -1L)
public class Dashboard implements Serializable {
@Id
private String id;
private Long totalUser;
private Long todayUser;
private Timestamp updatedAt;
}
// 3. Repository, Service
@Service
public class DashboardRedisService {
@Autowired
private RedisTemplate<String, Dashboard> dashboardRedisRepository; // (1)
public Dashboard getDashboard(Dashboard dashboard) { // (2)
ValueOperations<String, Dashboard> valueOperations = dashboardRedisRepository.opsForValue();
return valueOperations.get(dashboard.getId());
}
}
// 4. DashboardService
@Service
public class DashboardService {
private final DashboardRedisService dashboardRedisService;
private static final Long refreshTime = 2L;
public Flux<ServerSentEvent<DashboardResponseDto>> publish() { // (1)
...
Dashboard dashboard = dashboardRedisService.getDashboard(); // (2)
...
return Flux.interval(Duration.ofSeconds(refreshTime))
.map(sequence -> ServerSentEvent.<DashboardResponseDto> builder()
.id("/dashboard")
.event("periodic-event")
.data(dashboardResponseDto)
.retry(Duration.ofSeconds(refreshTime))
.build());
}
}