Skip to content

Guarantee serialization of calls to the session #2494

@yrodiere

Description

@yrodiere

A user can write this:

return sessionFactory.withSession(s -> {
   return Uni.combine().combine().all().unis(s.doSomething(), s.doSomethingElse()).asTuple();
});

It is incorrect, because it could result in interleaved uses of the session, messing up its state: doSomething() could set up some temporary state, do some IO so release control of the event loop, then doSomethingElse() would start executing, mess up the temporary state, and we're in a bad place.

This section of the docs explains a related problem -- not the same one, but the explanations are relevant.

Unfortunately -- on contrary to the problem mentioned in the docs -- this problem is not detected and will be very hard to debug.

More importantly... it's probably just as easy to fix as it is to detect. We could simply make sure that all operations in the session start running after the previous one finished.

E.g. this code in ReactiveSessionImpl:

	@Override
	public <T> CompletionStage<T> reactiveFind(
			Class<T> entityClass,
			Object id,
			LockOptions lockOptions,
			EntityGraph<T> fetchGraph) {
		checkOpen();
		return supplyStage( () -> {
			...
		} );

Could become:

	@Override
	public <T> CompletionStage<T> reactiveFind(
			Class<T> entityClass,
			Object id,
			LockOptions lockOptions,
			EntityGraph<T> fetchGraph) {
		checkOpen();
		this.previousOperation = this.previousOperation.thenCompose(ignored -> supplyStage( () -> {
			...
		} ) );
		return previousOperation;

(Or better yet, we'd integrate this with supplyStage, which seems to be doing something similar with a voidFuture)

previousOperation would just be a field in the session, initialized to a completed future.

We could do this for StatelessSession as well, though it will be harder to explain why state can be a problem with a "stateless" session...

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions