gama-platform / gama

Main repository for developing the 2024+ versions of GAMA
https://gama-platform.org
GNU General Public License v3.0
12 stars 5 forks source link

Some models in the library throw ConcurrentModificationException #150

Closed lesquoyb closed 1 month ago

lesquoyb commented 3 months ago

Describe the bug

It is a recurrent issue that some models throw ConcurrentModificationException when running for no apparent reason (no real modification in the code of the aspect).

Usually it's pretty random and some models are more prone to it than others but it's hard to reproduce consistently. I found a model in the library for which the issue arises all the time (on my computer): Graph From Bug (Mirror Graph).gaml Typically it would throw a few errors while running normally:

1 occurence in edge_agent814 (dead) at cycle 121: Cannot evaluate target as the target agent is dead
in Simulation 0
in geometry ss <- line([point(self.source.location.x,self.source.location.y,self.source.location.z),point(self.target.location.x,self.target.location.y,self.target.location.z)]);
when applying the point operator on [self.target.location.x, self.target.location.y, self.target.location.z]
in geometry ss <- line([point(self.source.location.x,self.source.location.y,self.source.location.z),point(self.target.location.x,self.target.location.y,self.target.location.z)]);
in agent edge_agent814 (dead)

Then after some time and playing with the Distance parameter the ConcurrentModificationException appears and stops the execution:

1 occurence in Simulation 0 at cycle 2154: Java error: ConcurrentModificationException
in Simulation 0
in aspect dynamic  {
    int degree <- degree_of(my_graph,self);
    draw sphere(1 + (degree / 5.0)) delegate: gama.gaml.statements.draw.ShapeDrawer@6b5db2c4 color: #blue ;
}

ConcurrentModificationException: null
java.base/java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:1023)
java.base/java.util.LinkedHashMap$LinkedKeyIterator.next(LinkedHashMap.java:1046)
gama.core.util.graph.GamaGraph.mapValue(GamaGraph.java:1094)
gama.core.util.graph.GamaGraph.serializeToGaml(GamaGraph.java:1085)
gama.core.common.util.StringUtils.toGaml(StringUtils.java:378)
gama.gaml.expressions.operators.BinaryOperator._value(BinaryOperator.java:155)
gama.gaml.expressions.AbstractExpression.value(AbstractExpression.java:87)
in agent Simulation 0

Expected behavior Get rid of those ConcurrentModificationException (not just in this example model)

Additional context I guess that the issue is that drawing being independent from the engine, the code in the aspect can be executed during a change of the variables in the simulation resulting in that issue. Maybe the "simplest" currently to get rid of this would be to have the draws executed on a fixed state of the simulation and not accessing live variables ? But it's probably going to have a cost on performances. Maybe we could use the already existing serialization to work on the previous step btw ?

AlexisDrogoul commented 3 months ago

Two solutions here :

1) The solution you propose is more or less exactly what the synchronised: true already does, so you can use this. 2) If you don't want to synchronise the simulation and the display, then you expose yourself to these errors (no real way to avoid them), and in that case, you have to accept that some display steps may be missed or wrong, which is why the preference pref_display_show_errors exists. Turning it to false will get rid of the errors.

Monosnap 2024-04-03 13-41-42