Skip to content
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

Concurrent modification exception in Timetable #5933

Closed
vpaturet opened this issue Jun 27, 2024 · 1 comment · Fixed by #5941
Closed

Concurrent modification exception in Timetable #5933

vpaturet opened this issue Jun 27, 2024 · 1 comment · Fixed by #5941
Labels
Bug Real-Time Update The issue/PR is related to RealTime updates

Comments

@vpaturet
Copy link
Contributor

vpaturet commented Jun 27, 2024

We see occasionally in our production environment a concurrent access issue on a Timetable object.
It seems that a reader thread (GraphQL API call) iterates over the TripTimes collection of a Timetable object while this collection is being modified concurrently by another thread.
In theory this should not happen since the TimetableSnapshot should ensure that all write operations on Timetable objects happen before the Timetables are handed over to reader threads.

Exception while fetching data (/stopPlaces[0]/estimatedCalls) : null
java.util.ConcurrentModificationException: null
	at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1095)
	at java.base/java.util.ArrayList$Itr.next(ArrayList.java:1049)
	at org.opentripplanner.routing.stoptimes.StopTimesHelper.listTripTimeShortsForPatternAtStop(StopTimesHelper.java:247)
	at org.opentripplanner.routing.stoptimes.StopTimesHelper.stopTimesForStop(StopTimesHelper.java:65)
	at org.opentripplanner.transit.service.DefaultTransitService.stopTimesForStop(DefaultTransitService.java:325)
	at org.opentripplanner.apis.transmodel.model.stop.StopPlaceType.getTripTimesForStop(StopPlaceType.java:438)
	at org.opentripplanner.apis.transmodel.model.stop.StopPlaceType.lambda$create$16(StopPlaceType.java:378)
	at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:273)
	at java.base/java.util.HashMap$KeySpliterator.tryAdvance(HashMap.java:1736)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
	at org.opentripplanner.apis.transmodel.model.stop.StopPlaceType.lambda$create$17(StopPlaceType.java:400)
	at graphql.execution.ExecutionStrategy.invokeDataFetcher(ExecutionStrategy.java:329)
	at graphql.execution.ExecutionStrategy.fetchField(ExecutionStrategy.java:305)
s	at graphql.execution.ExecutionStrategy.fetchField(ExecutionStrategy.java:243)
	at graphql.execution.ExecutionStrategy.resolveFieldWithInfo(ExecutionStrategy.java:214)
	at graphql.execution.AsyncExecutionStrategy.execute(AsyncExecutionStrategy.java:63)
	at graphql.execution.ExecutionStrategy.completeValueForObject(ExecutionStrategy.java:729)
	at graphql.execution.ExecutionStrategy.completeValue(ExecutionStrategy.java:502)
	at graphql.execution.ExecutionStrategy.completeValueForList(ExecutionStrategy.java:613)
	at graphql.execution.ExecutionStrategy.completeValueForList(ExecutionStrategy.java:561)
	at graphql.execution.ExecutionStrategy.completeValue(ExecutionStrategy.java:487)
	at graphql.execution.ExecutionStrategy.completeField(ExecutionStrategy.java:453)
	at graphql.execution.ExecutionStrategy.lambda$resolveFieldWithInfo$1(ExecutionStrategy.java:216)
	at java.base/java.util.concurrent.CompletableFuture.uniApplyNow(CompletableFuture.java:684)
	at java.base/java.util.concurrent.CompletableFuture.uniApplyStage(CompletableFuture.java:662)
	at java.base/java.util.concurrent.CompletableFuture.thenApply(CompletableFuture.java:2200)
	at graphql.execution.ExecutionStrategy.resolveFieldWithInfo(ExecutionStrategy.java:215)
	at graphql.execution.AsyncExecutionStrategy.execute(AsyncExecutionStrategy.java:63)
	at graphql.execution.Execution.executeOperation(Execution.java:162)
	at graphql.execution.Execution.execute(Execution.java:104)
	at graphql.GraphQL.execute(GraphQL.java:568)
	at graphql.GraphQL.lambda$parseValidateAndExecute$13(GraphQL.java:487)
	at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187)
	at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2341)
	at graphql.GraphQL.parseValidateAndExecute(GraphQL.java:482)
	at graphql.GraphQL.lambda$executeAsync$9(GraphQL.java:440)
	at java.base/java.util.concurrent.CompletableFuture.uniComposeStage(CompletableFuture.java:1187)
	at java.base/java.util.concurrent.CompletableFuture.thenCompose(CompletableFuture.java:2341)
	at graphql.GraphQL.executeAsync(GraphQL.java:428)
	at graphql.GraphQL.execute(GraphQL.java:366)
	at org.opentripplanner.apis.transmodel.TransmodelGraph.executeGraphQL(TransmodelGraph.java:66)
	at org.opentripplanner.apis.transmodel.TransmodelAPI.getGraphQL(TransmodelAPI.java:113)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.glassfish.jersey.server.model.internal.ResourceMethodInvocationHandlerFactory.lambda$static$0(ResourceMethodInvocationHandlerFactory.java:52)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher$1.run(AbstractJavaResourceMethodDispatcher.java:146)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.invoke(AbstractJavaResourceMethodDispatcher.java:189)
	at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$ResponseOutInvoker.doDispatch(JavaResourceMethodDispatcherProvider.java:176)
	at org.glassfish.jersey.server.model.internal.AbstractJavaResourceMethodDispatcher.dispatch(AbstractJavaResourceMethodDispatcher.java:93)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:478)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:400)
	at org.glassfish.jersey.server.model.ResourceMethodInvoker.apply(ResourceMethodInvoker.java:81)
	at org.glassfish.jersey.server.ServerRuntime$1.run(ServerRuntime.java:274)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:248)
	at org.glassfish.jersey.internal.Errors$1.call(Errors.java:244)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:292)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:274)
	at org.glassfish.jersey.internal.Errors.process(Errors.java:244)
	at org.glassfish.jersey.process.internal.RequestScope.runInScope(RequestScope.java:266)
	at org.glassfish.jersey.server.ServerRuntime.process(ServerRuntime.java:253)
	at org.glassfish.jersey.server.ApplicationHandler.handle(ApplicationHandler.java:696)
	at org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpContainer.service(GrizzlyHttpContainer.java:367)
	at org.glassfish.grizzly.http.server.HttpHandler$1.run(HttpHandler.java:190)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:535)
	at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:515)
	at java.base/java.lang.Thread.run(Thread.java:1583)

@vpaturet
Copy link
Contributor Author

vpaturet commented Aug 5, 2024

Confirmed fixed with #5941

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Real-Time Update The issue/PR is related to RealTime updates
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant