I have a problem. My project in spring boot receives a JSON (mapped to pojo with JACKSON) of options and an XML that we will call XML ORIGINAL.
Each option comes with a series of tags that must be modified on the original XML.
Suppose a JSON with:
Opcion 1 = N valores;
Opcion 2 = M valores;
Opcion 3 = K valores;
.....
Opcion X = R valores
Each option must generate X variations based on the values I have. Eg: For the ORIGINAL XML I must generate N variations for the Option 1, Option 2 must generate M variations of the documents resulting from Option 1, Option 3 must generate K variations of the resulting documents of Option 2, Option X must generate R variations of documents resulting from Option 3.
In synthesis, you should give me variations of NxMxKxR
XML ORIGINALS.
Following my algorithm, I get the following error:
2018-12-04 11: 37: 55.125 WARN 7296 --- [l-1 housekeeper] com.zaxxer.hikari.pool.HikariPool: HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta = 49s823ms348μs491ns)
My variation is generated in the following way:
package com.example.restproyect.states;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import javax.persistence.Transient;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.example.restproyect.Documento;
import com.example.restproyect.filtros.FiltroAbs;
import com.example.restproyect.filtros.FiltroNombre;
import com.example.restproyect.hilos.Tarea;
import com.example.restproyect.hilos.TareaRastrojo;
import com.example.restproyect.states.objetosinternos.Pastura;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "digestibilidadVariaciones", "rindeVariaciones" })
public class Rastrojo implements Serializable{
@JsonProperty("digestibilidadVariaciones")
private List<Pastura> digestibilidadVariaciones = null;
@JsonProperty("rindeVariaciones")
private List<Pastura> rindeVariaciones = null;
@Transient
private FiltroAbs filtro = new FiltroNombre("crop_stubbles");
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
public List<Pastura> getDigestibilidadVariaciones() {
return digestibilidadVariaciones;
}
public void setDigestibilidadVariaciones(List<Pastura> digestibilidadVariaciones) {
this.digestibilidadVariaciones = digestibilidadVariaciones;
}
public List<Pastura> getRindeVariaciones() {
return rindeVariaciones;
}
public void setRindeVariaciones(List<Pastura> rindeVariaciones) {
this.rindeVariaciones = rindeVariaciones;
}
public void setAdditionalProperties(Map<String, Object> additionalProperties) {
this.additionalProperties = additionalProperties;
}
@Override
public String toString() {
return "Rastrojo [digestibilidadVariaciones=" + digestibilidadVariaciones + ", rindeVariaciones="
+ rindeVariaciones + ", additionalProperties=" + additionalProperties + "]"+"\n";
}
public static ArrayList<Pastura> cloneList( List<Pastura> list) {
ArrayList<Pastura> clone = new ArrayList<Pastura>(list.size());
for (Pastura item : list)
clone.add(item.clone());
return clone;
}
public Hashtable<Integer, Documento> generarEscenarios(Hashtable<Integer, Documento> escenarios) {
Hashtable<Integer, Documento> newEscenarios = new Hashtable<Integer, Documento>();
//Numero de threads
ExecutorService executor = Executors.newFixedThreadPool(100);
ArrayList<Future<ArrayList<Documento>>> listFuture = new ArrayList<>();
//Por cada escenario que entre. Los escenarios arrancan en 1
for(int indexEscenarios = 0; indexEscenarios < escenarios.size(); indexEscenarios++) {
//Generar para ese escenario, la variacion correspondiente
listFuture.add(executor.submit(new TareaRastrojo(
cloneList(digestibilidadVariaciones),
cloneList(rindeVariaciones), filtro,escenarios.get(indexEscenarios), indexEscenarios)));
}
while(!executor.isTerminated()) {
}
int count = 1;
for(Future<ArrayList<Documento>> resultado:listFuture){
if(resultado.isDone()){
try {
for(Documento doc:resultado.get()) {
System.out.println("---------------------------AGREGANDO ESCENARIO["+count+"]---------------------------------------");
count++;
//newEscenarios.put(newEscenarios.size(), doc);
}
//System.out.println("-------CANTIDAD DE ESCENARIOS------["+newEscenarios.size()+"]");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
System.out.println("-------CANTIDAD DE ESCENARIOS------");
System.out.println("-------CANTIDAD DE ESCENARIOS------["+newEscenarios.size()+"]");
return newEscenarios;
}
}
Cada TareaRastrojo es un Objeto que se comporta asi:
package com.example.restproyect.hilos;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.concurrent.Callable;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.example.restproyect.Documento;
import com.example.restproyect.filtros.FiltroAbs;
import com.example.restproyect.states.objetosinternos.Pastura;
public class TareaRastrojo implements Callable<ArrayList<Documento>>{
private ArrayList<Pastura> digestibilidadVariaciones;
private ArrayList<Pastura> rindeVariaciones;
private FiltroAbs filtro;
private Documento doc;
private int numero;
public TareaRastrojo(ArrayList<Pastura> digestibilidadVariaciones, ArrayList<Pastura> rindeVariaciones, FiltroAbs filtro,
Documento doc, int numero) {
super();
this.digestibilidadVariaciones = digestibilidadVariaciones;
this.rindeVariaciones = rindeVariaciones;
this.filtro = filtro;
this.doc = doc;
this.numero = numero;
}
public ArrayList<Documento> call() {
ArrayList<Documento> documentosGenerados = new ArrayList<>();
System.out.println("***************************************************************************************");
System.out.println("Documento numero ="+this.numero);
for(int indexVariaciones = 0; indexVariaciones < digestibilidadVariaciones.get(0).getPasturas().size(); indexVariaciones++) {
Document newDocument = this.doc.getDocumento();
System.out.println("Variacion numero["+indexVariaciones+"] de la tarea numero ["+this.numero+"]");
Documento doc = new Documento(newDocument);
Document insertDoc = doc.clonarDocumento();
newDocument = null;
doc.setDocumento(insertDoc);
//Para cada tag dentro del tag <escenario> Busco los tags que tienen las variaciones
NodeList node = doc.getDocumento().getChildNodes().item(0).getChildNodes();
for(int j=0; j < node.getLength(); j++) {
/*
* indice par es un text dentro de los tags, solo
* se trabaja con los elementos impares
* que son los TAGS
*/
if(j%2 != 0) {
Node nodo = node.item(j);
if(filtro.cumple(nodo)) {
//Obtengo la pastura a variar
NodeList nodePastura = node.item(j).getChildNodes();
for(int indexPastura = 0; indexPastura < digestibilidadVariaciones.size(); indexPastura++) {
//Formula para obtener la pastura que va a variar
System.out.println("Variacion numero["+indexVariaciones+"] de la tarea numero ["+this.numero+"] de la PASTURA ["+indexPastura+"]");
Node nodoPastura = nodePastura.item(indexPastura*2+1);
nodoPastura.getAttributes().getNamedItem("crop_stubbleDigest").setNodeValue(String.valueOf(digestibilidadVariaciones.get(indexPastura).next()));
nodoPastura.getAttributes().getNamedItem("yield").setNodeValue(String.valueOf(rindeVariaciones.get(indexPastura).next()));
System.out.println("FIN DE LA Variacion numero["+indexVariaciones+"] de la tarea numero ["+this.numero+"] de la PASTURA ["+indexPastura+"]");
}
System.err.print("FIN DE LA Variacion numero["+indexVariaciones+"] de la tarea numero ["+this.numero+"]");
documentosGenerados.add(doc);
}
}
}
}
for(int indexPastura = 0; indexPastura < digestibilidadVariaciones.size(); indexPastura++) {
digestibilidadVariaciones.get(indexPastura).resetUltimaSeleccion();
rindeVariaciones.get(indexPastura).resetUltimaSeleccion();
}
System.err.println("Finalizando Documento numero ="+this.numero);
System.out.println("***************************************************************************************");
return documentosGenerados;
}
}
package com.example.restproyect.states.objetosinternos;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ "pasturas" })
public class Pastura implements Serializable,Cloneable{
@JsonProperty("pastura")
private List<Integer> pasturas = null;
private int ultimaSeleccion = 0;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
public Pastura(ArrayList<Integer> pasturas) {
super();
this.pasturas = pasturas;
}
public Pastura(List<Integer> pasturas, Map<String, Object> additionalProperties) {
super();
this.pasturas = pasturas;
this.additionalProperties = additionalProperties;
}
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
public List<Integer> getPasturas() {
return pasturas;
}
public void setPasturas(List<Integer> pasturas) {
this.pasturas = pasturas;
}
public void setAdditionalProperties(Map<String, Object> additionalProperties) {
this.additionalProperties = additionalProperties;
}
public float next() {
float valor = this.pasturas.get(this.ultimaSeleccion);
this.ultimaSeleccion = this.ultimaSeleccion + 1;
return valor;
}
public void resetUltimaSeleccion() {
this.ultimaSeleccion = 0;
}
@Override
public String toString() {
return "Pastura [pasturas=" + pasturas + ", additionalProperties=" + additionalProperties + "]";
}
public Pastura clone(){
return new Pastura(new ArrayList<Integer>(this.pasturas)); //new ArrayList<Integer>(this.pasturas);
}
}
The context switching of the threads work well, where I can see how the messages appear in disorder
The problem is that the CPU goes to 100% and does not finish its execution, missing 500 scenarios to be generated.
It should be noted that I am trying to generate 5 ^ 5 documents = 3125 and generate them well, but by generating the next level that would give 5 ^ 6 = 15625 in the generation of scenario 11000 to 12000, the CPU is stuck. It does not end in the same scenario but it varies. Any idea why it may be hanging?
100% CPU