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

RFC Elide 5.0 - TransactionRegistry #1292

Closed
aklish opened this issue Apr 27, 2020 · 2 comments
Closed

RFC Elide 5.0 - TransactionRegistry #1292

aklish opened this issue Apr 27, 2020 · 2 comments

Comments

@aklish
Copy link
Member

aklish commented Apr 27, 2020

Elide needs a way to kill/cancel long running, asynchronous queries. The proper way to cancel a transaction is to let the DataStoreTransaction handle it.

A new TransactionRegistry interface will surface transaction details to other parts of Elide (like Elide async):

public interface TransactionRegistry {
    @Data
    public static class TransactionEntry {
        RequestScope request;
        DataStoreTransaction transaction;
    }

    Set<TransactionEntry> getRunningTransactions();

    Set<TransactionEntry> getRunningTransaction(String requestId);

    void addRunningTransaction(TransactionEntry transactionEntry);

    void removeRunningTransaction(TransactionEntry transactionEntry);
}

The TransactionRegistry is intended to be thread safe.

The InMemoryDataStore currently wraps all transaction interactions in Elide - so it is a good candidate to hook into this interface. Its transactions can add and remove themselves from the registry.

Also, the RequestScope would benefit from having a request ID added to it. Elide (for JSON-API) and QueryRunner (for GraphQL) methods should be modified to accept this new identifier.

The AsyncQuery should store this request ID in its model to aid in locating corresponding TransactionEntry objects.

Finally, the DataStoreTransaction needs a new cancel interface added:

public void cancel();

This interface should be fully thread safe, and is intended to safely interrupt a running query. Each existing data store should attempt to implement this interface in a reasonable way.

The AggregationDataStore transactions will call into Hibernate's session to cancel the query:

https://docs.jboss.org/hibernate/orm/5.0/javadocs/org/hibernate/Session.html#cancelQuery--

@sgarfinkel
Copy link

@aklish What actually backs the async transactions? Java’s CompletableFuture, RxJava Single, Project Reactor Mono? I ask mainly because this is a really useful feature, particularly with the rise of Kotlin coroutines.

All of these interfaces are cancellable, FWIW.

I’m primarily a Kotlin dev these days, so being able to just use suspendible functions directly for implementing the transactions is very tantalizing.

@aklish
Copy link
Member Author

aklish commented May 4, 2020

The primary purpose of exposing the transaction registry is to support Elide 5.0's async API (which will allow a request to be cancelled). Ideally, a cancel will not simply interrupt the running thread, but will actually cancel the JDBC session which can release resources in the database as well.

Elide 5.0 will also change the Spring controller to use their Async interface counterparts:
https://github.com/yahoo/elide/blob/elide-5.x/elide-spring/elide-spring-boot-autoconfigure/src/main/java/com/yahoo/elide/spring/controllers/JsonApiController.java#L63

This will allow request timeouts to interrupt the underlying request thread.

Elide transactions themselves are synchronous, but require a thread-safe cancel method. This mirrors concepts in the ORMs for how to interrupt a running session, entity manager, or JDBC connection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants