Equivalent to while loop in reactive paradigm, Spring WebFlux

Viewed 75
@PostMapping("/httpush")
public Mono<ResponseEntity<HttpushResponseUtil>> httpush(@RequestParam("timestamp") String timestamp, @RequestParam("token") String token) throws InterruptedException{
    Thread t = new Thread( ()-> {
    long fecha_actual = 0;
    long fecha_bd = 0;
    
    fecha_actual = (timestamp.equals("null")) ? 0: Long.parseLong(timestamp);

    long elapsedTime = 0;
    int i = 0;
    while (fecha_bd <= fecha_actual) {
        List<HuellaTemp> updateTime =  service.ObtenerUpdateTimePorSerial(token, "update_time").block();

       if (updateTime.size() > 0) {
           
           if(updateTime.get(0).getStatusPlantilla()=="Muestras Restantes: 0") {
               break;
           }
           else if(updateTime.get(0).getUpdate_time() != null) {                   
               fecha_bd = updateTime.get(0).getUpdate_time().getTime() / 1000;
           }

       }
       
       elapsedTime = elapsedTime + 1;
        if (elapsedTime == 600) {
            break;
        }
       i++;
    }
    });
    
    t.start(); 
    t.join(); 
    
    return service.ObtenerHuellaHttpush()
            .map(httpush -> ResponseEntity
                .ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(httpush)
            );
    
    
}

The code works but my goal is not to create blocking processes, and remove the extra thread. which was placed because the main thread does not allow blocking.

I need to consult a date stored in the database, for each iteration of while; This date updates each time the sensor captures a new state; For this reason, I must verify the date until it is greater than the one registered by url. Finally, when you are sure that the date has just been registered, check the status of the fingerprint in the database.

How can I achieve the same imperative behavior with reactive operators?

1 Answers

I have come up with two possible solutions, and therefore I want to know which of them would be more efficient, and how could I improve?

I just discussed this solution with the help of the comment on this question.

    long fecha_actual = 0;
    long fecha_bd = 0;
    
    
    fecha_actual = (timestamp.equals("null")) ? 0: Long.parseLong(timestamp);

    Map<String, Long> Estado = new HashMap<String, Long>();
    Estado.put("fecha_actual", fecha_actual);
    Estado.put("fecha_bd", fecha_bd);
    Estado.put("tiempo_transcurrido", (long) 0);
    

    return service.ObtenerUpdateTimePorSerial(token,"fecha_creacion")
            .expand(fechaCreacion -> {
                if (fechaCreacion.size() > 0) {            
                    Estado.put("fecha_bd", fechaCreacion.get(0).getFecha_creacion().getTime() / 1000);
                    
                }
                if(Estado.get("fecha_bd") <= Estado.get("fecha_actual")) {
                    
                    return service.ObtenerUpdateTimePorSerial(token,"fecha_creacion");
                }
                return Mono.empty();
            })
            .last().flatMap(e -> {
                return service.HabilitarSensor(token)
                        .map(response -> ResponseEntity
                            .ok() // indica el status code de respuesta
                            .contentType(MediaType.APPLICATION_JSON)
                            .body(response)
                        );
            });

This was the first solution I was able to come up with.

return Flux.generate( (SynchronousSink<Integer> sink) -> {
        System.out.println(Estado);
        sink.next(1);
        if (!(Estado.get("fecha_bd") <= Estado.get("fecha_actual"))) {
            
            sink.complete();
            
        }
        Estado.put("tiempo_transcurrido", Estado.get("tiempo_transcurrido")+1);
        if (Estado.get("tiempo_transcurrido") == 1500) {//modificar aqui si se requiere reiniciar em menos tiempo
            sink.complete();
        }
        
        
    }).flatMap(e -> {
        return service.ObtenerUpdateTimePorSerial(token,"fecha_creacion")
                .map(fechaCreacion -> {
                    
                    if (fechaCreacion.size() > 0) {            
                            Estado.put("fecha_bd", fechaCreacion.get(0).getFecha_creacion().getTime() / 1000);
                            
                        }
                    return Estado;
                });
    }).last()
    .flatMap(e -> {
        return service.HabilitarSensor(token)
                .map(response -> ResponseEntity
                    .ok() // indica el status code de respuesta
                    .contentType(MediaType.APPLICATION_JSON)
                    .body(response)
                );
    });
Related