feat: query cancellation via `CancellationToken` on `SessionContext`
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 5/5
- Temps estimé
- Plus d'une semaine
- Accessibilité débutants
- 45/100
- Type d'issue
- Fonctionnalité
- Clarté
- Plutôt claire
- Activité
- Calme
- Domaine
- api, backend-api-design
Piste de recherche
Commencez par les points de blocage JNI dans native/src/lib.rs et examinez les points d’entrée Java de SessionContext, DataFrame et des resource handles. Comparez le cycle de vie des tokens proposé et les surcharges de collect/executeStream avec les références dans cancellation.rs et query_tracker.rs. Le travail est considéré comme terminé lorsque les API listées prennent en charge l’annulation et le nettoyage sans modifier les méthodes existantes sans token, l’annulation devant être observable pendant la collecte et le streaming.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Is your feature request related to a problem or challenge?
A long-running DataFrame.collect(allocator) or DataFrame.executeStream(allocator) call blocks the calling Java thread for the entire duration of the query. Thread.interrupt() does nothing — the JNI thread is parked inside runtime().block_on(...) (native/src/lib.rs), and the interrupt flag is ignored by the Tokio runtime. There is no way to abort an in-flight query, free its native resources early, or unblock the calling thread short of waiting for the query to finish.
For any embedder running multi-tenant workloads — request timeouts, user-cancel actions, node shutdown, leader-election handover — this is a hard operational gap. The OpenSearch analytics backend (OpenSearch/sandbox/plugins/analytics-backend-datafusion/rust/src/cancellation.rs and query_tracker.rs) carries a CancellationToken-based wrapper precisely because upstream offers nothing.
This is complementary to issue #40 (close()/JNI use-after-free race) but distinct: #40 is about safely tearing down a finished handle; this is about signalling an in-flight future to stop. Both eventually share the atomic-handle scaffolding from #40's option 2, so coordination is worthwhile, but the surface lands cleanly without #40 having to merge first.
Describe the solution you'd like
A token-based cancellation API on SessionContext, modeled on Spark 4.0's interruptTag shape (cancel lives on the session, not on the DataFrame). The token is a separate handle from the DataFrame so cancel can fire from a thread that does not hold the DataFrame.
v1 surface
try (SessionContext ctx = new SessionContext();
CancellationToken token = ctx.newCancellationToken();
DataFrame df = ctx.sql("SELECT ... FROM big_table")) {
Future<ArrowReader> fut = pool.submit(() -> df.collect(allocator, token));
// from another thread (timeout watcher, user-cancel handler, ...):
token.cancel();
// fut completes with CancellationException
}
New methods:
SessionContext.newCancellationToken()-- returns a freshCancellationTokenbound to this session.CancellationToken.cancel()-- fires the token; idempotent.CancellationToken.isCancelled()-- non-blocking check.CancellationToken.close()-- releases the native handle; the token isAutoCloseableso try-with-resources handles cleanup.DataFrame.collect(BufferAllocator, CancellationToken)-- overload that takes a token. The existing zero-tokencollect(BufferAllocator)is unchanged.DataFrame.executeStream(BufferAllocator, CancellationToken)-- same overload pattern. Token is held by the returnedArrowReaderfor its full lifetime; cancel mid-stream aborts the nextloadNextBatch().
Describe alternatives you've considered
No response
Additional context
Out of scope
- Tag form. Ship the token primitive first; tag is sugar that can land in a follow-up if a user actually asks for it.
- Sync-API breakage.
df.collect(allocator)keeps working unchanged; the new method isdf.collect(allocator, token)(overload). - Per-operator cancel granularity. Today the cancel point is each
block_onsite; sub-operator cancellation is upstream-DataFusion territory.
- Langage dominant
- Java
- Étoiles
- 32
- Forks
- 12
- Métriques de merge des PR
- Aucune PR mergée en 30 j
Guide de contribution
Ouvrir le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de apache/datafusion-java
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 35/100
apache/datafusion-java#116 ·
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 25/100
apache/datafusion-java#112 ·
-
enhancement
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 42/100
apache/datafusion-java#96 ·
-
enhancement
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 38/100
apache/datafusion-java#95 ·
-
Create first release Ouverteenhancement
Difficulté 4/5 3-5 jours Accessibilité débutants 35/100
apache/datafusion-java#86 · 3 commentaires ·
Toutes les issues de apache/datafusion-java
Issues similaires
-
awaiting triage bug Causes friction Hop Gui P1 P2 Transforms
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100
-
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100
apache/flink-agents#1152 ·
-
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100
-
Difficulté 2/5 1-3 heures Accessibilité débutants 70/100
jenkinsci/blueocean-plugin#5417 ·
-
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100
objectionary/eo-graphs#75 ·