Skip to content

feat(sdks): taskito executor subcommand for Python, Node and Java - #595

Merged
kartikeya-27 merged 46 commits into
ByteVeda:masterfrom
stromanni:feat/546-executor-attach-sdks
Aug 1, 2026
Merged

feat(sdks): taskito executor subcommand for Python, Node and Java#595
kartikeya-27 merged 46 commits into
ByteVeda:masterfrom
stromanni:feat/546-executor-attach-sdks

Conversation

@stromanni

@stromanni stromanni commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Implements the three SDK executor subcommands — the S5–S7 phases of #546.

Closes #551
Closes #552
Closes #553

One client in core, three thin CLIs

tasks/executor-attach.md says "only the concrete stream changes", and that turned out to be literally true, so it sets the shape:

taskito-server                     app container
RemoteDispatcher ←── socket ──→ ExecutorClient (taskito-core)
                                      ↓ Job   ↑ JobResult
                           PreforkPool │ NodeDispatcher │ JavaDispatcher

WorkerDispatcher was already the seam every SDK pool implements, and its signature — run(job_rx, result_tx) + shutdown() + notify_cancel() — is exactly what an executor needs. Worker::dispatcher() even documented the mirror case. So ExecutorClient is Worker::spawn with storage swapped for a socket, and each SDK's subcommand is a wrapper over the pool it already had.

Writing that client three times would have tripled the subtle parts — handshake ordering, exactly-once result accounting, drain sequencing, cancel routing — with nothing gained. The JSON-header wire is unchanged, so a third-party SDK can still write an executor with its standard library alone.

The executor opens no storage

An executor imports the user's app to find its handlers, and that import used to construct a Queue — which connected eagerly, putting the database credentials straight back into the app image that #546 exists to keep them out of.

TASKITO_DETACHED_EXECUTOR=1 is now set by each CLI before it imports the app, and the native queue is replaced by a stand-in. Python's prefork children inherit the variable, so they open nothing either; Java already took no QueueBackend. One rule decides every method:

  • Reads answer emptyNone/null is what a queue with no such row returns anyway, and callers already handle it. Not optional: Queue.__init__ reads settings (webhook subscriptions), so a stand-in that refused them could not build a Queue at all.
  • Writes throw — an enqueue that quietly vanished would be worse than one that failed.
  • Job-scoped conveniences degrade with one warning — a task calling set_progress must not fail because it happens to be running detached.

What that costs — progress, task logs, published partials, dashboard middleware toggles — is tracked in #589 with per-layer sub-issues; closing it needs new protocol frames.

Four things the tests caught that reading the docs did not

  • The Java ServiceLoader mechanism in Java: executor subcommand plus classpath handler discovery #553 cannot work. On the classpath a listed class must be a subtype of the service with a public no-arg constructor; the static provider() form only applies to modules on the module path. The first attempt generated provider() and died with ServiceConfigurationError: demo.GreeterTasks not a subtype. A new HandlerRegistryProvider interface is now the service, and the processor generates a nested <Class>Tasks$Provider implementing it. Owners with no accessible no-arg constructor are skipped with a compiler note rather than silently — only their own code knows how to build them.
  • startExecutor blocked the Node event loop for the whole handshake timeout. Now async. Found because the in-process test deadlocked against its own fake scheduler.
  • A local stop() hung forever. stop() cannot unpark the frame reader, which is parked on a read only the scheduler could satisfy, so the session never ended and any shell that stopped and then waited deadlocked. Fixed in core with a regression test.
  • Node cancels would have silently stopped working once storage was gone: the AbortSignal a cooperative task watches is driven by a storage poll. JsExecutor.isCancelRequested now exposes the state the cancel frames land in. The test asserts the result frame comes back cancelled, not failure — proving both that the handler aborted and that the native side reclassified the throw.

Verification

Rust cargo test --workspace clean, clippy --all-targets -D warnings clean, --features postgres and --features redis check
Python 1377 passed / 12 skipped, no regressions; 19 executor tests, 5 of them against the real taskito-server binary; ruff + mypy clean
Node 545 passed (baseline 524), zero lost; 4 gated tests against the real server; biome + tsc clean
Java 9 executor tests; plus a job enqueued through the CLI ran on an executor whose handlers came only from META-INF/services, with no user main

Each SDK has two test layers: a hermetic scheduler speaking the wire (so they run with no Rust build, in every CI job) and the same assertions against the real taskito-server behind TASKITO_SERVER_BIN. That pairing is what keeps the fakes honest.

Two environment notes, both reproduced on a clean tree and unrelated to this branch: Java's :compileTestJava is skipped here, so its tests were run through the JUnit platform launcher directly; and 10 test/dashboard/** Node files fail on a missing SPA build.

Reviewing

The first three commits (feat(server): authenticate the attach listener handshake and the two storage fixes) are the #584 review follow-ups this branch was cut from, not part of this work — they are unmerged and unreviewed, so say the word if you would rather they went up as their own PR and this one rebased onto master.

The remaining 25 split cleanly by layer: core (7), Python (5), Node (7), Java (6). S5/S6/S7 were meant to be separate PRs, so this can be split per SDK if you prefer that shape.

Summary by CodeRabbit

  • New Features

    • Added detached scheduler executors for Java, Node.js, and Python with configurable tasks, concurrency, authentication, identity, heartbeats, and shutdown handling.
    • Added executor lifecycle controls, status and connection details, cancellation, retries, and graceful draining.
    • Added executor commands to the Java, Node.js, and Python CLIs.
    • Added detached-mode queue behavior for storage-independent task execution.
    • Added automatic Java handler discovery and registration support.
  • Bug Fixes

    • Improved handling of unavailable storage, cancelled jobs, connection failures, and malformed scheduler responses.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@pratyush618, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 50 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 58928d11-76f8-4f73-8fe9-e5b99a5a3e67

📥 Commits

Reviewing files that changed from the base of the PR and between fab6f68 and 42be90b.

📒 Files selected for processing (7)
  • crates/taskito-core/src/worker/protocol.rs
  • crates/taskito-python/src/executor.rs
  • sdks/java/processor/src/main/java/org/byteveda/taskito/processor/TaskHandlerProcessor.java
  • sdks/java/src/main/java/org/byteveda/taskito/cli/Cli.java
  • sdks/node/src/detached.ts
  • sdks/python/taskito/detached.py
  • sdks/python/tests/worker/test_executor_attach_server.py
📝 Walkthrough

Walkthrough

The PR adds a shared scheduler-attachment executor to the Rust core and exposes it through Node.js, Python, and Java SDKs. It adds detached storage and cancellation handling, lifecycle controls, CLIs, Java handler discovery, protocol conversion, and end-to-end tests.

Changes

Core executor attachment

Layer / File(s) Summary
Attachment protocol and runtime
crates/taskito-core/src/worker/*, crates/taskito-core/tests/rust/*
Adds address parsing, cancellation signals, handshake and job-result conversion, executor lifecycle controls, dispatch, heartbeats, draining, and integration coverage.

Node.js executor

Layer / File(s) Summary
Detached execution and task dispatch
sdks/node/src/*, crates/taskito-node/src/*
Adds detached queue adapters, executor startup and shutdown, cancellation-aware task callbacks, resource handling, and public exports.
Node CLI and integration tests
sdks/node/src/cli/*, sdks/node/test/worker/*
Adds the executor command, shared app loading, environment validation, fake-scheduler tests, and real-server tests.

Python executor

Layer / File(s) Summary
Detached execution and Python API
sdks/python/taskito/*
Adds detached queue behavior, the Python Executor binding, lifecycle methods, CLI configuration, and signal-driven shutdown.
Python executor tests
sdks/python/tests/worker/*
Adds fake-scheduler, subprocess, cancellation, retry, storage-independence, and real-server integration tests.

Java executor

Layer / File(s) Summary
Executor API and JNI control
sdks/java/src/main/java/org/byteveda/taskito/{worker,internal}/*, crates/taskito-java/src/*
Adds the Java executor builder, native attachment surface, dispatcher cancellation support, detached metadata behavior, and lifecycle controls.
CLI discovery and validation
sdks/java/processor/src/main/java/*, sdks/java/src/main/java/org/byteveda/taskito/cli/Cli.java
Adds generated ServiceLoader providers, handler registry discovery, executor CLI options, slot validation, and bounded shutdown.
Java integration tests
sdks/java/src/test/java/*
Adds socket-level coverage for handshake metadata, execution, failure results, refusal handling, and session shutdown.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

  • Issue 546: Directly covers the executor-attachment architecture implemented across Rust, Python, Node.js, and Java.

Possibly related PRs

Suggested reviewers: kartikeya-27

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the executor subcommand added for Python, Node, and Java.
Linked Issues check ✅ Passed The changes implement the Python, Node, and Java executor requirements, including attachment, discovery, lifecycle, cancellation, retries, and integration coverage [#551] [#552] [#553].
Out of Scope Changes check ✅ Passed The changes remain within executor attachment, detached execution, handler discovery, shared transport support, and related tests for #551#553.
Docstring Coverage ✅ Passed Docstring coverage is 95.52% which is sufficient. The required threshold is 80.00%.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pratyush618 pratyush618 added deployment Container and cluster deployment topology enhancement New feature or request java Java SDK node Node SDK labels Aug 1, 2026
@stromanni

Copy link
Copy Markdown
Contributor Author

Stacked on #596 — the first three commits here are that PR's, not this one's. Once #596 merges this diff drops to its own 25 commits.

@stromanni
stromanni force-pushed the feat/546-executor-attach-sdks branch 2 times, most recently from 9c5d725 to 7cdfec9 Compare August 1, 2026 04:16
The attach protocol only had scheduler-side conversions. An executor needs
the other direction: a Job rebuilt from a dispatch frame, and a result frame
built from a JobResult.
ExecutorClient is Worker::spawn with storage swapped for a socket: it dials
a scheduler, then feeds the same WorkerDispatcher every SDK already
implements. Needs no Storage, so an executor image carries app code and no
database credentials.

Draining announces zero capacity by heartbeat before disconnecting, which
the scheduler already honours, so in-flight work reports instead of waiting
for a reap.
Every SDK executor needs to turn TASKITO_ATTACH into a connection, and the
grammar has to match what the listener binds. One parser here rather than
three in three languages, where unix: support would drift.
A worker reads the storage cancel flag; an attached executor has no storage
and learns from the scheduler's cancel frame instead. Both answer one
question, so both ask it in one place.
Slots are prefork children, so the timeout watchdog, least-loaded dispatch
and restart-on-crash all come from shipped code and child.py is untouched.

start/wait/stop rather than one blocking run: a Python signal handler only
runs when the main thread holds the GIL, so a blocking call would make the
process deaf to SIGTERM.
Reads TASKITO_ATTACH and TASKITO_SLOTS, the contract shared with the other
SDKs. The token is env-only: in argv it would show up in ps and shell
history.
A socket speaking the frame protocol stands in for the scheduler so these
run without a Rust build; the same assertions run against the real
taskito-server when TASKITO_SERVER_BIN points at one.
ExecutorHandle::wait consumes the handle, which a shell that must also hold
it to shut down cannot do. A cloneable session view lets an async runtime
watch for the scheduler ending the session.
The executor runs the same task bodies as the worker, so the middleware,
codec and resource-scope handling is shared rather than copied.
run and executor both resolve a Queue from a module path.
Attaching is async: dialling and the handshake block, so on the JS thread
they would freeze the event loop until the scheduler answers.

The dispatcher now takes its cancels from the shared source, so a detached
executor can learn of one without reading storage.
The inverse of runWorker: the scheduler holds the database connection and
dispatches over a socket. Same middleware, codecs and resources — only the
transport differs.
Reads TASKITO_ATTACH and TASKITO_SLOTS, the contract shared with the other
SDKs. The token is env-only: in argv it would show up in ps.
A socket speaking the frame protocol stands in for the scheduler so these
run without a Rust build; the same assertions run against the real
taskito-server when TASKITO_SERVER_BIN points at one.
stop() cannot unpark the frame reader, which is blocked on a read only the
scheduler could satisfy. A shell that stopped and then waited would hang
instead of draining.
The processor now generates a ServiceLoader provider per annotated class and
lists it in META-INF/services, so an executor finds handlers with no user
main.

ServiceLoader cannot load HandlerRegistry itself: on the classpath a listed
class must be a subtype with a public no-arg constructor, and the static
provider() form only applies to modules. Hence the new interface.

Classes with no accessible no-arg constructor are skipped with a note —
only their own code knows how to build them.
stop() is documented as safe on a signal-handling path, but begin_drain wrote the zero-capacity heartbeat first — a scheduler that stopped reading blocked that write for the whole write timeout.
teardown joined unconditionally after the drain budget, so a task that ignores its cancel kept the pool's run alive and the process never exited. The test could not catch it: its blocking behaviour released itself.
The companion is written at package level and names the handler by simple name, so an Outer.Inner provider would not compile. Also corrects the service type in the Javadoc.
System.exit runs hooks while main is still inside Runtime.exit, so a registered hook waited out the whole drain budget for a join that could not complete, then called stop() on an already-closed control.
A throwaway CommandLine routed a bad TASKITO_SLOTS through the execution-exception handler, so the user saw a stack trace rather than a usage message. Zero and negative counts also passed, and the builder clamped them behind the banner.
awaitSession held the read lock for the whole park. A queued close() then blocked a concurrent stop() — the only call that could have ended the session. Waiters are counted instead, and close drains them before freeing.
Nothing awaits a signal listener's return value, so a rejected stop() surfaced as an unhandled rejection and aborted the process mid-drain.
runExecutor tracked nothing, so queue.shutdown() left an attached executor running and its scheduler session open.
Nothing read the pipes, so a scheduler that logs per job fills the buffer and blocks on its next write.
@kartikeya-27

Copy link
Copy Markdown
Contributor

@CodeRabbit full review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (3)
crates/taskito-core/tests/rust/executor_tests.rs (1)

59-60: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert that the pool observed shutdown().

TestPool::shutdown records into self.shutdown, but no test reads that field. ExecutorHandle::stop calls self.dispatcher.shutdown(), and spawn_reader calls it again when the session ends. Neither call is covered.

Add an accessor and assert it in the drain test, so a regression that stops signalling the pool is caught.

💚 Proposed test addition
     fn cancelled(&self) -> Vec<String> {
         self.cancels.lock().expect("cancels").clone()
     }
+
+    /// Whether the executor asked the pool to stop accepting work.
+    fn was_shut_down(&self) -> bool {
+        self.shutdown.load(Ordering::SeqCst)
+    }

Then in a_drain_announces_zero_capacity_before_anything_else, or in stop_finishes_in_flight_work_before_disconnecting after the result arrives:

     attached.handle.stop();
+    wait_until(
+        || attached.pool.was_shut_down(),
+        "stop() must tell the pool to stop accepting work",
+    );

Also applies to: 161-163

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/taskito-core/tests/rust/executor_tests.rs` around lines 59 - 60, Add a
`TestPool` accessor for its recorded `shutdown` flag, then update the
drain-related test (`a_drain_announces_zero_capacity_before_anything_else` or
`stop_finishes_in_flight_work_before_disconnecting`) to assert the accessor is
true after shutdown completes, covering the
`ExecutorHandle::stop`/`spawn_reader` signaling paths.
sdks/java/src/main/java/org/byteveda/taskito/worker/Executor.java (1)

113-138: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Make close() idempotent across threads.

closed is a plain field and close() is not synchronized. Executor is public, so a caller can close it from a shutdown hook while the main thread also closes it. Both threads can then pass the guard, call resources.teardownWorker() twice, and emit WORKER_STOPPED twice. synchronized on close() plus a volatile read keeps the documented idempotence.

♻️ Proposed refactor
-    private boolean closed;
+    private volatile boolean closed;
     `@Override`
-    public void close() {
+    public synchronized void close() {
         if (closed) {
             return;
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sdks/java/src/main/java/org/byteveda/taskito/worker/Executor.java` around
lines 113 - 138, Make Executor.close() thread-safe and idempotent by
synchronizing the close() method and declaring the closed field volatile.
Preserve the existing early-return guard so concurrent callers allow only one
shutdown sequence, including resources.teardownWorker() and WORKER_STOPPED
emission.
sdks/java/src/test/java/org/byteveda/taskito/worker/ExecutorAttachTest.java (1)

65-65: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the unused results deque.

Nothing adds to results. readFrame() returns each frame directly, so the !results.isEmpty() branch at lines 190-192 is unreachable. Deleting the field and the branch makes the polling loop easier to read.

♻️ Proposed cleanup
-        private final Deque<JsonNode> results = new ArrayDeque<>();
         JsonNode nextResult() throws IOException {
             long deadline = System.nanoTime() + TimeUnit.MILLISECONDS.toNanos(SETTLE_MS);
             while (System.nanoTime() < deadline) {
-                if (!results.isEmpty()) {
-                    return results.removeFirst();
-                }
                 JsonNode frame = readFrame();

Drop the now-unused ArrayDeque and Deque imports.

Also applies to: 186-202

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sdks/java/src/test/java/org/byteveda/taskito/worker/ExecutorAttachTest.java`
at line 65, Remove the unused results field from ExecutorAttachTest, delete the
unreachable results check in the polling loop within readFrame-related logic,
and remove the now-unused ArrayDeque and Deque imports while preserving direct
frame handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/taskito-core/src/worker/protocol.rs`:
- Around line 244-293: Update the SchedulerMessage::Job dispatch representation
and SchedulerMessage::into_job to carry and reconstruct created_at,
scheduled_at, priority, metadata, unique_key, and notes instead of defaulting
them. Populate these fields when converting a Job into a dispatch message, and
ensure the Node and Python converters expose the reconstructed values
consistently for detached and attached workers.

In `@crates/taskito-python/src/executor.rs`:
- Around line 142-154: Update Executor::stop and its contract to acknowledge
that concurrent calls may block behind wait’s with_handle mutex for up to
timeout_ms, or otherwise ensure stop uses a separately shared primitive that
does not depend on the polling handle lock. Keep the existing wait behavior and
CLI signal-handling flow unchanged.

In
`@sdks/java/processor/src/main/java/org/byteveda/taskito/processor/TaskHandlerProcessor.java`:
- Around line 35-38: Update the class Javadoc near the generated companion
description to state that an accessible no-arg constructor causes generation of
a nested Provider class implementing HandlerRegistryProvider, which is
registered through META-INF/services; remove the inaccurate provider() method
wording and preserve the explanation of classpath discovery.

In `@sdks/java/src/main/java/org/byteveda/taskito/cli/Cli.java`:
- Around line 294-296: Update the token assignment in Cli.Executor to pass
TASKITO_ATTACH_TOKEN through a blankToNull helper before calling token, treating
null and blank values as absent while preserving nonblank tokens. Add the helper
as a private static nullable method alongside the existing Executor helpers,
matching the address normalization behavior.

In `@sdks/python/tests/worker/test_executor_attach_server.py`:
- Around line 134-138: Replace the fixed one-second attach waits with a shared
polling readiness helper that confirms the executor is attached before
enqueueing. Update sdks/python/tests/worker/test_executor_attach_server.py lines
134-138, 146-150, and 175-178 to call the helper before enqueueing ECHO, BOOM,
and SLOW respectively; preserve each test’s existing enqueue and status
assertions.

---

Nitpick comments:
In `@crates/taskito-core/tests/rust/executor_tests.rs`:
- Around line 59-60: Add a `TestPool` accessor for its recorded `shutdown` flag,
then update the drain-related test
(`a_drain_announces_zero_capacity_before_anything_else` or
`stop_finishes_in_flight_work_before_disconnecting`) to assert the accessor is
true after shutdown completes, covering the
`ExecutorHandle::stop`/`spawn_reader` signaling paths.

In `@sdks/java/src/main/java/org/byteveda/taskito/worker/Executor.java`:
- Around line 113-138: Make Executor.close() thread-safe and idempotent by
synchronizing the close() method and declaring the closed field volatile.
Preserve the existing early-return guard so concurrent callers allow only one
shutdown sequence, including resources.teardownWorker() and WORKER_STOPPED
emission.

In `@sdks/java/src/test/java/org/byteveda/taskito/worker/ExecutorAttachTest.java`:
- Line 65: Remove the unused results field from ExecutorAttachTest, delete the
unreachable results check in the polling loop within readFrame-related logic,
and remove the now-unused ArrayDeque and Deque imports while preserving direct
frame handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e32abdfc-cc4f-4a80-bcfe-8c0a07073426

📥 Commits

Reviewing files that changed from the base of the PR and between 6f142d2 and eb452aa.

📒 Files selected for processing (49)
  • crates/taskito-core/src/lib.rs
  • crates/taskito-core/src/worker/cancel.rs
  • crates/taskito-core/src/worker/dial.rs
  • crates/taskito-core/src/worker/executor.rs
  • crates/taskito-core/src/worker/mod.rs
  • crates/taskito-core/src/worker/protocol.rs
  • crates/taskito-core/tests/rust.rs
  • crates/taskito-core/tests/rust/executor_tests.rs
  • crates/taskito-core/tests/rust/remote_tests.rs
  • crates/taskito-core/tests/rust/worker_tests.rs
  • crates/taskito-java/src/dispatcher.rs
  • crates/taskito-java/src/executor.rs
  • crates/taskito-java/src/lib.rs
  • crates/taskito-node/src/dispatcher.rs
  • crates/taskito-node/src/executor.rs
  • crates/taskito-node/src/lib.rs
  • crates/taskito-python/src/executor.rs
  • crates/taskito-python/src/lib.rs
  • sdks/java/processor/src/main/java/org/byteveda/taskito/processor/TaskHandlerProcessor.java
  • sdks/java/src/main/java/org/byteveda/taskito/cli/Cli.java
  • sdks/java/src/main/java/org/byteveda/taskito/internal/JniExecutorControl.java
  • sdks/java/src/main/java/org/byteveda/taskito/internal/MiddlewareDisables.java
  • sdks/java/src/main/java/org/byteveda/taskito/internal/NativeExecutor.java
  • sdks/java/src/main/java/org/byteveda/taskito/worker/Executor.java
  • sdks/java/src/main/java/org/byteveda/taskito/worker/HandlerRegistryProvider.java
  • sdks/java/src/main/java/org/byteveda/taskito/worker/WorkerDispatchBridge.java
  • sdks/java/src/test/java/org/byteveda/taskito/worker/ExecutorAttachTest.java
  • sdks/node/src/cli/commands/executor.ts
  • sdks/node/src/cli/commands/index.ts
  • sdks/node/src/cli/commands/run.ts
  • sdks/node/src/cli/index.ts
  • sdks/node/src/cli/load-app.ts
  • sdks/node/src/detached.ts
  • sdks/node/src/executor.ts
  • sdks/node/src/index.ts
  • sdks/node/src/native.ts
  • sdks/node/src/queue.ts
  • sdks/node/src/task-callback.ts
  • sdks/node/src/worker.ts
  • sdks/node/test/worker/executorAttach.test.ts
  • sdks/node/test/worker/executorAttachServer.test.ts
  • sdks/python/taskito/_taskito.pyi
  • sdks/python/taskito/app.py
  • sdks/python/taskito/cli.py
  • sdks/python/taskito/detached.py
  • sdks/python/tests/worker/executor_apps/__init__.py
  • sdks/python/tests/worker/executor_apps/attach_app.py
  • sdks/python/tests/worker/test_executor_attach.py
  • sdks/python/tests/worker/test_executor_attach_server.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • ByteVeda/taskito (manual)

Comment thread crates/taskito-core/src/worker/protocol.rs
Comment thread crates/taskito-python/src/executor.rs
Comment thread sdks/java/src/main/java/org/byteveda/taskito/cli/Cli.java Outdated
Comment thread sdks/python/tests/worker/test_executor_attach_server.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deployment Container and cluster deployment topology enhancement New feature or request java Java SDK node Node SDK python rust tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Java: executor subcommand plus classpath handler discovery Node: taskito executor subcommand Python: taskito executor subcommand

3 participants