com.dream.configs.ObjectSSEEmitter Maven / Gradle / Ivy
package com.dream.configs;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import com.dream.dtos.DreamDTO;
import com.dream.exceptions.NotFoundException;
import com.dream.mappers.CommentMapper;
import com.dream.mappers.DreamMapper;
import com.dream.models.Comment;
import com.dream.models.Dream;
import com.dream.services.CommentService;
import com.dream.services.DreamService;
import com.dream.utils.ObjectType;
import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
public class ObjectSSEEmitter{
@Lazy
@Autowired
private DreamService dreamService;
@Lazy
@Autowired
private CommentService commentService;
private long lastSentObjectID;
private long lastRun;
@Value("${sse_timeout}")
private long timeout;
@Value("${sse_interval}")
private long interval;
private final List emitters = new CopyOnWriteArrayList<>();
List timeoutedEmitters = new ArrayList<>();
List deadEmitters = new ArrayList<>();
@Scheduled(fixedRate = 10000)
public void sendTimeoutEventAndClose() {
emitters.forEach(emitter -> {
try {
if(TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis() - emitter.getAge()) > timeout) {
emitter.send(MySSEEmitter.event().
name("timeout").
data("Timeout occured. Reconnect the client!"));
timeoutedEmitters.add(emitter);
}
} catch (Exception e) {
timeoutedEmitters.add(emitter);
}
});
disconnectEmitters(timeoutedEmitters);
log.debug("{} clients were diconnected from SSE after reaching timeout limit.", timeoutedEmitters.size());
timeoutedEmitters.clear();
}
/**
* Prepares the object and sends it over SSE
* @param objectId
* @param objectType
*/
@Async
public void prepareAndSend(long objectId, String objectType){
//Get number of seconds since the last run
long diff = (System.currentTimeMillis() - lastRun) / 1000;
if(diff >= interval && objectId != lastSentObjectID) {
Optional