All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.neo4j.driver.internal.reactive.InternalRxSession Maven / Gradle / Ivy

There is a newer version: 5.21.0
Show newest version
/*
 * Copyright (c) "Neo4j"
 * Neo4j Sweden AB [http://neo4j.com]
 *
 * This file is part of Neo4j.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.neo4j.driver.internal.reactive;

import java.util.Map;
import java.util.concurrent.CompletableFuture;
import org.neo4j.driver.AccessMode;
import org.neo4j.driver.Bookmark;
import org.neo4j.driver.Query;
import org.neo4j.driver.TransactionConfig;
import org.neo4j.driver.exceptions.TransactionNestingException;
import org.neo4j.driver.internal.InternalBookmark;
import org.neo4j.driver.internal.async.NetworkSession;
import org.neo4j.driver.internal.async.UnmanagedTransaction;
import org.neo4j.driver.internal.cursor.RxResultCursor;
import org.neo4j.driver.internal.util.Futures;
import org.neo4j.driver.reactive.RxResult;
import org.neo4j.driver.reactive.RxSession;
import org.neo4j.driver.reactive.RxTransaction;
import org.neo4j.driver.reactive.RxTransactionWork;
import org.reactivestreams.Publisher;

@Deprecated
public class InternalRxSession extends AbstractReactiveSession implements RxSession {
    public InternalRxSession(NetworkSession session) {
        super(session);
    }

    @Override
    RxTransaction createTransaction(UnmanagedTransaction unmanagedTransaction) {
        return new InternalRxTransaction(unmanagedTransaction);
    }

    @Override
    Publisher closeTransaction(RxTransaction transaction, boolean commit) {
        return ((InternalRxTransaction) transaction).close(commit);
    }

    @Override
    public Publisher beginTransaction(TransactionConfig config) {
        return doBeginTransaction(config);
    }

    @Override
    public  Publisher readTransaction(RxTransactionWork> work) {
        return readTransaction(work, TransactionConfig.empty());
    }

    @Override
    public  Publisher readTransaction(RxTransactionWork> work, TransactionConfig config) {
        return runTransaction(AccessMode.READ, work::execute, config);
    }

    @Override
    public  Publisher writeTransaction(RxTransactionWork> work) {
        return writeTransaction(work, TransactionConfig.empty());
    }

    @Override
    public  Publisher writeTransaction(RxTransactionWork> work, TransactionConfig config) {
        return runTransaction(AccessMode.WRITE, work::execute, config);
    }

    @Override
    public RxResult run(String query, TransactionConfig config) {
        return run(new Query(query), config);
    }

    @Override
    public RxResult run(String query, Map parameters, TransactionConfig config) {
        return run(new Query(query, parameters), config);
    }

    @Override
    public RxResult run(Query query) {
        return run(query, TransactionConfig.empty());
    }

    @Override
    public RxResult run(Query query, TransactionConfig config) {
        return new InternalRxResult(() -> {
            CompletableFuture resultCursorFuture = new CompletableFuture<>();
            session.runRx(query, config).whenComplete((cursor, completionError) -> {
                if (cursor != null) {
                    resultCursorFuture.complete(cursor);
                } else {
                    releaseConnectionBeforeReturning(resultCursorFuture, completionError);
                }
            });
            return resultCursorFuture;
        });
    }

    private  void releaseConnectionBeforeReturning(CompletableFuture returnFuture, Throwable completionError) {
        // We failed to create a result cursor so we cannot rely on result cursor to cleanup resources.
        // Therefore we will first release the connection that might have been created in the session and then notify
        // the error.
        // The logic here shall be the same as `SessionPullResponseHandler#afterFailure`.
        // The reason we need to release connection in session is that we made `rxSession.close()` optional;
        // Otherwise, session.close shall handle everything for us.
        Throwable error = Futures.completionExceptionCause(completionError);
        if (error instanceof TransactionNestingException) {
            returnFuture.completeExceptionally(error);
        } else {
            session.releaseConnectionAsync()
                    .whenComplete((ignored, closeError) ->
                            returnFuture.completeExceptionally(Futures.combineErrors(error, closeError)));
        }
    }

    @Override
    public Bookmark lastBookmark() {
        return InternalBookmark.from(session.lastBookmarks());
    }

    @Override
    public  Publisher close() {
        return doClose();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy