-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A concurrency issue #190
Comments
What do you think about this issue? @enricostara |
@enricostara Please tell me if you are solving this problem Solving this problem seems difficult. |
Hi @endison1986, this code method in
together with the following method in
I see concurrent tests are already passing for the add and remove of comps however, there are no proper tests yet for the change of states, even if the synchronised code I see should be fine for this specific case as well. |
Hi, @enricostara In the following example, the final output count is 60 because the first 20 entities created were traversed twice. EntityRepository entityRepository = (EntityRepository) new EntityRepository.Factory().create("test");
for (int i = 0; i < 20; i++) {
entityRepository.createEntity(new A(i));
}
for (int i = 0; i < 20; i++) {
entityRepository.createEntity(new A(i + 30), new B(i + 30));
}
var count = new AtomicInteger(0);
entityRepository.findEntitiesWith(A.class).stream().forEach(rs -> {
if(!rs.entity().has(B.class)) {
rs.entity().add(new B(rs.comp().id()));
}
count.incrementAndGet();
});
System.out.println(count); The result is With1[comp=A[id=19], entity=Entity={id=|0:2:20|-> [A[id=19], B[id=19]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=18], entity=Entity={id=|0:2:21|-> [A[id=18], B[id=18]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=17], entity=Entity={id=|0:2:22|-> [A[id=17], B[id=17]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=16], entity=Entity={id=|0:2:23|-> [A[id=16], B[id=16]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=15], entity=Entity={id=|0:2:24|-> [A[id=15], B[id=15]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=14], entity=Entity={id=|0:2:25|-> [A[id=14], B[id=14]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=13], entity=Entity={id=|0:2:26|-> [A[id=13], B[id=13]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=12], entity=Entity={id=|0:2:27|-> [A[id=12], B[id=12]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=11], entity=Entity={id=|0:2:28|-> [A[id=11], B[id=11]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=10], entity=Entity={id=|0:2:29|-> [A[id=10], B[id=10]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=9], entity=Entity={id=|0:2:30|-> [A[id=9], B[id=9]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=8], entity=Entity={id=|0:2:31|-> [A[id=8], B[id=8]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=7], entity=Entity={id=|0:2:32|-> [A[id=7], B[id=7]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=6], entity=Entity={id=|0:2:33|-> [A[id=6], B[id=6]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=5], entity=Entity={id=|0:2:34|-> [A[id=5], B[id=5]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=4], entity=Entity={id=|0:2:35|-> [A[id=4], B[id=4]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=3], entity=Entity={id=|0:2:36|-> [A[id=3], B[id=3]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=2], entity=Entity={id=|0:2:37|-> [A[id=2], B[id=2]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=1], entity=Entity={id=|0:2:38|-> [A[id=1], B[id=1]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=0], entity=Entity={id=|0:2:39|-> [A[id=0], B[id=0]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=0], entity=Entity={id=|0:2:39|-> [A[id=0], B[id=0]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=1], entity=Entity={id=|0:2:38|-> [A[id=1], B[id=1]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=2], entity=Entity={id=|0:2:37|-> [A[id=2], B[id=2]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=3], entity=Entity={id=|0:2:36|-> [A[id=3], B[id=3]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=4], entity=Entity={id=|0:2:35|-> [A[id=4], B[id=4]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=5], entity=Entity={id=|0:2:34|-> [A[id=5], B[id=5]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=6], entity=Entity={id=|0:2:33|-> [A[id=6], B[id=6]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=7], entity=Entity={id=|0:2:32|-> [A[id=7], B[id=7]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=8], entity=Entity={id=|0:2:31|-> [A[id=8], B[id=8]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=9], entity=Entity={id=|0:2:30|-> [A[id=9], B[id=9]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=10], entity=Entity={id=|0:2:29|-> [A[id=10], B[id=10]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=11], entity=Entity={id=|0:2:28|-> [A[id=11], B[id=11]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=12], entity=Entity={id=|0:2:27|-> [A[id=12], B[id=12]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=13], entity=Entity={id=|0:2:26|-> [A[id=13], B[id=13]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=14], entity=Entity={id=|0:2:25|-> [A[id=14], B[id=14]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=15], entity=Entity={id=|0:2:24|-> [A[id=15], B[id=15]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=16], entity=Entity={id=|0:2:23|-> [A[id=16], B[id=16]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=17], entity=Entity={id=|0:2:22|-> [A[id=17], B[id=17]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=18], entity=Entity={id=|0:2:21|-> [A[id=18], B[id=18]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=19], entity=Entity={id=|0:2:20|-> [A[id=19], B[id=19]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=49], entity=Entity={id=|0:2:19|-> [A[id=49], B[id=49]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=48], entity=Entity={id=|0:2:18|-> [A[id=48], B[id=48]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=47], entity=Entity={id=|0:2:17|-> [A[id=47], B[id=47]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=46], entity=Entity={id=|0:2:16|-> [A[id=46], B[id=46]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=45], entity=Entity={id=|0:2:15|-> [A[id=45], B[id=45]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=44], entity=Entity={id=|0:2:14|-> [A[id=44], B[id=44]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=43], entity=Entity={id=|0:2:13|-> [A[id=43], B[id=43]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=42], entity=Entity={id=|0:2:12|-> [A[id=42], B[id=42]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=41], entity=Entity={id=|0:2:11|-> [A[id=41], B[id=41]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=40], entity=Entity={id=|0:2:10|-> [A[id=40], B[id=40]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=39], entity=Entity={id=|0:2:9|-> [A[id=39], B[id=39]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=38], entity=Entity={id=|0:2:8|-> [A[id=38], B[id=38]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=37], entity=Entity={id=|0:2:7|-> [A[id=37], B[id=37]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=36], entity=Entity={id=|0:2:6|-> [A[id=36], B[id=36]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=35], entity=Entity={id=|0:2:5|-> [A[id=35], B[id=35]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=34], entity=Entity={id=|0:2:4|-> [A[id=34], B[id=34]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=33], entity=Entity={id=|0:2:3|-> [A[id=33], B[id=33]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=32], entity=Entity={id=|0:2:2|-> [A[id=32], B[id=32]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=31], entity=Entity={id=|0:2:1|-> [A[id=31], B[id=31]], stateId=|1:0:0|, enabled=true}]
With1[comp=A[id=30], entity=Entity={id=|0:2:0|-> [A[id=30], B[id=30]], stateId=|1:0:0|, enabled=true}]
60 In the following example, when traversing the Entity containing components A and B, and delete the B component of the Entity in other thread. EntityRepository entityRepository = (EntityRepository) new EntityRepository.Factory().create("test");
final var list = new ArrayList<Entity>(100);
for (int i = 0; i < 100; i++) {
list.add(entityRepository.createEntity(new A(i), new B(i)));
}
Scheduler scheduler = entityRepository.createScheduler();
scheduler.schedule(() -> entityRepository.findEntitiesWith(A.class, B.class).forEach(rs -> {
try {
System.out.println(rs);
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}));
new Thread(() -> {
try {
TimeUnit.MILLISECONDS.sleep(10);
for (int i = 0; i < 100; i++) {
list.get(i).removeType(B.class);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
scheduler.tick(); The result is With2[comp1=A[id=99], comp2=B[id=99], entity=Entity={id=|0:2:99|-> [A[id=99]], stateId=|1:0:0|, enabled=true}]
With2[comp1=A[id=98], comp2=B[id=98], entity=null]
With2[comp1=A[id=97], comp2=B[id=97], entity=null]
With2[comp1=A[id=96], comp2=B[id=96], entity=null]
With2[comp1=A[id=95], comp2=B[id=95], entity=null]
With2[comp1=A[id=94], comp2=B[id=94], entity=null]
With2[comp1=A[id=93], comp2=B[id=93], entity=null]
With2[comp1=A[id=92], comp2=B[id=92], entity=null]
With2[comp1=A[id=91], comp2=B[id=91], entity=null]
With2[comp1=A[id=90], comp2=B[id=90], entity=null]
With2[comp1=A[id=89], comp2=B[id=89], entity=null]
With2[comp1=A[id=88], comp2=B[id=88], entity=null]
With2[comp1=A[id=87], comp2=B[id=87], entity=null]
With2[comp1=A[id=86], comp2=B[id=86], entity=null]
With2[comp1=A[id=85], comp2=B[id=85], entity=null]
With2[comp1=A[id=84], comp2=B[id=84], entity=null]
With2[comp1=A[id=83], comp2=B[id=83], entity=null]
With2[comp1=A[id=82], comp2=B[id=82], entity=null]
With2[comp1=A[id=81], comp2=B[id=81], entity=null]
With2[comp1=A[id=80], comp2=B[id=80], entity=null]
With2[comp1=A[id=79], comp2=B[id=79], entity=null]
With2[comp1=A[id=78], comp2=B[id=78], entity=null]
With2[comp1=A[id=77], comp2=B[id=77], entity=null]
With2[comp1=A[id=76], comp2=B[id=76], entity=null]
With2[comp1=A[id=75], comp2=B[id=75], entity=null]
With2[comp1=A[id=74], comp2=B[id=74], entity=null]
With2[comp1=A[id=73], comp2=B[id=73], entity=null]
With2[comp1=A[id=72], comp2=B[id=72], entity=null]
With2[comp1=A[id=71], comp2=B[id=71], entity=null]
With2[comp1=A[id=70], comp2=B[id=70], entity=null]
With2[comp1=A[id=69], comp2=B[id=69], entity=null]
With2[comp1=A[id=68], comp2=B[id=68], entity=null]
With2[comp1=A[id=67], comp2=B[id=67], entity=null]
With2[comp1=A[id=66], comp2=B[id=66], entity=null]
With2[comp1=A[id=65], comp2=B[id=65], entity=null]
With2[comp1=A[id=64], comp2=B[id=64], entity=null]
With2[comp1=A[id=63], comp2=B[id=63], entity=null]
With2[comp1=A[id=62], comp2=B[id=62], entity=null]
With2[comp1=A[id=61], comp2=B[id=61], entity=null]
With2[comp1=A[id=60], comp2=B[id=60], entity=null]
With2[comp1=A[id=59], comp2=B[id=59], entity=null]
With2[comp1=A[id=58], comp2=B[id=58], entity=null]
With2[comp1=A[id=57], comp2=B[id=57], entity=null]
With2[comp1=A[id=56], comp2=B[id=56], entity=null]
With2[comp1=A[id=55], comp2=B[id=55], entity=null]
With2[comp1=A[id=54], comp2=B[id=54], entity=null]
With2[comp1=A[id=53], comp2=B[id=53], entity=null]
With2[comp1=A[id=52], comp2=B[id=52], entity=null]
With2[comp1=A[id=51], comp2=B[id=51], entity=null]
With2[comp1=A[id=50], comp2=B[id=50], entity=null]
With2[comp1=A[id=50], comp2=B[id=50], entity=null]
With2[comp1=A[id=51], comp2=B[id=51], entity=null]
With2[comp1=A[id=52], comp2=B[id=52], entity=null]
With2[comp1=A[id=53], comp2=B[id=53], entity=null]
With2[comp1=A[id=54], comp2=B[id=54], entity=null]
With2[comp1=A[id=55], comp2=B[id=55], entity=null]
With2[comp1=A[id=56], comp2=B[id=56], entity=null]
With2[comp1=A[id=57], comp2=B[id=57], entity=null]
With2[comp1=A[id=58], comp2=B[id=58], entity=null]
With2[comp1=A[id=59], comp2=B[id=59], entity=null]
With2[comp1=A[id=60], comp2=B[id=60], entity=null]
With2[comp1=A[id=61], comp2=B[id=61], entity=null]
With2[comp1=A[id=62], comp2=B[id=62], entity=null]
With2[comp1=A[id=63], comp2=B[id=63], entity=null]
With2[comp1=A[id=64], comp2=B[id=64], entity=null]
With2[comp1=A[id=65], comp2=B[id=65], entity=null]
With2[comp1=A[id=66], comp2=B[id=66], entity=null]
With2[comp1=A[id=67], comp2=B[id=67], entity=null]
With2[comp1=A[id=68], comp2=B[id=68], entity=null]
With2[comp1=A[id=69], comp2=B[id=69], entity=null]
With2[comp1=A[id=70], comp2=B[id=70], entity=null]
With2[comp1=A[id=71], comp2=B[id=71], entity=null]
With2[comp1=A[id=72], comp2=B[id=72], entity=null]
With2[comp1=A[id=73], comp2=B[id=73], entity=null]
With2[comp1=A[id=74], comp2=B[id=74], entity=null]
With2[comp1=A[id=75], comp2=B[id=75], entity=null]
With2[comp1=A[id=76], comp2=B[id=76], entity=null]
With2[comp1=A[id=77], comp2=B[id=77], entity=null]
With2[comp1=A[id=78], comp2=B[id=78], entity=null]
With2[comp1=A[id=79], comp2=B[id=79], entity=null]
With2[comp1=A[id=80], comp2=B[id=80], entity=null]
With2[comp1=A[id=81], comp2=B[id=81], entity=null]
With2[comp1=A[id=82], comp2=B[id=82], entity=null]
With2[comp1=A[id=83], comp2=B[id=83], entity=null]
With2[comp1=A[id=84], comp2=B[id=84], entity=null]
With2[comp1=A[id=85], comp2=B[id=85], entity=null]
With2[comp1=A[id=86], comp2=B[id=86], entity=null]
With2[comp1=A[id=87], comp2=B[id=87], entity=null]
With2[comp1=A[id=88], comp2=B[id=88], entity=null]
With2[comp1=A[id=89], comp2=B[id=89], entity=null]
With2[comp1=A[id=90], comp2=B[id=90], entity=null]
With2[comp1=A[id=91], comp2=B[id=91], entity=null]
With2[comp1=A[id=92], comp2=B[id=92], entity=null]
With2[comp1=A[id=93], comp2=B[id=93], entity=null]
With2[comp1=A[id=94], comp2=B[id=94], entity=null]
With2[comp1=A[id=95], comp2=B[id=95], entity=null]
With2[comp1=A[id=96], comp2=B[id=96], entity=null]
With2[comp1=A[id=97], comp2=B[id=97], entity=null]
With2[comp1=A[id=98], comp2=B[id=98], entity=null]
With2[comp1=A[id=99], comp2=B[id=99], entity=null] |
is this a bug? @enricostara |
Any updates here? |
During development, I got an exception log that looked like it was looping to a null value. So I wrote a piece of test code to try to restore the error. Judging from the test code, this should be a concurrency issue.
Is this result expected?
Test code:
The text was updated successfully, but these errors were encountered: