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

No one assigned

    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