feat(queue): KubernetesJob broker — run queue jobs as Kubernetes Jobs#35
feat(queue): KubernetesJob broker — run queue jobs as Kubernetes Jobs#35abnegate wants to merge 6 commits into
Conversation
Greptile SummaryIntroduces a
Confidence Score: 4/5Safe to merge once appwrite-labs/php-k8s is registered on Packagist; the broker logic and test harness are sound but a few rough edges around documentation and the configureJob API surface warrant a second look before broader adoption. The three main concerns from earlier rounds — the isFailed() misclassification, the missing checksum verification, and the hard-require K8s dependency — have all been addressed in this revision. The remaining open items (README static method reference, configureJob overwrite semantics) are low blast-radius but do affect developer experience for anyone following the docs or building on top of this adapter. packages/queue/README.md and packages/queue/src/Queue/Broker/KubernetesJob.php deserve a close read before the adapter is declared stable for external consumers. Important Files Changed
Reviews (7): Last reviewed commit: "refactor(queue): move KubernetesJobEnvel..." | Re-trigger Greptile |
Adds a Publisher that triggers each enqueued message as a native Kubernetes Job (via appwrite-labs/php-k8s) instead of pushing it onto a broker: the cluster scheduler runs a pod to completion per message, so no long-running worker is required. The message envelope travels in the UTOPIA_QUEUE_MESSAGE env var and KubernetesJob::message() rebuilds it inside the pod. Honours the new Publisher::enqueue $priority arg (PriorityClass) and Queue::jobTtl, plus image pull policy and a configureJob() hook. getQueueSize() counts the queue's Jobs by label selector; per-job retries are left to the Job's native backoffLimit, so retry() is a no-op. Unit tests cover manifest construction (bare host); a kind + Tilt e2e suite (tests/e2e.sh) proves real execution: jobs run to completion and failures are marked failed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
e15e944 to
d3f0f0e
Compare
…wnloads - isFailed() now keys off the Job's terminal "Failed" status condition instead of getFailedPodsCount(), which is non-zero mid-retry when backoffLimit > 0 (would inflate getQueueSize(failedJobs: true)). - tests/e2e.sh pins kubectl to a fixed version (no stable.txt) and verifies SHA-256 of the kind/kubectl/tilt downloads before granting execute. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Thanks @greptile — addressed in c1f2783:
|
|
All three fixes look solid. Here's a quick assessment: 1. The new implementation correctly iterates if ($failedJobs === $this->isFailed($job) && ($failedJobs || !$job->hasCompleted())) {One minor note: 2. Clean and the comment explains the intent well. No concerns here. 3. The pinned versions +
Overall the changes are correct and address all the original concerns. LGTM. Tip: You can customize Greptile's behavior for this repo with |
…obEnvelope - appwrite-labs/php-k8s is added as a committed VCS repository (it is public, so no token is needed) instead of relying on Packagist — fixes the failing "could not be found" composer resolution in CI. - The pod-side message decode moves off the Publisher into a small KubernetesJobEnvelope (ENV const + read()), so the producer (broker) and the in-pod consumer share only the wire contract. Updated the worker entrypoint and unit tests accordingly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The KubernetesJob broker is optional, like the Swoole/Workerman adapters, so appwrite-labs/php-k8s moves from require to require-dev (for this package's own tests) plus suggest (for consumers). Composer repositories aren't transitive, so keeping it in require broke resolution for dependents like platform that don't declare the VCS repo; as require-dev it is never pulled into dependents. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the two preg_replace calls with a small shared slug() helper that walks the string, keeps allowed characters, and collapses runs of the rest into a single '-'. Same DNS-1123 output, no regex. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Relocate the pod-side decoder under the broker's namespace (Utopia\Queue\Broker\KubernetesJob\Envelope). No behaviour change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
What
Adds a
KubernetesJobPublisher topackages/queuethat triggers each enqueued message as a native Kubernetes Job instead of pushing it onto a broker. The cluster scheduler runs a pod to completion per message, so there's no long-running worker process.UTOPIA_QUEUE_MESSAGEenv var;KubernetesJob::message()rebuilds theMessageinside the pod.Publisher::enqueue($priority)arg (maps to a podPriorityClasswhen configured) andQueue::jobTtl(→ttlSecondsAfterFinished).configureJob()hook for advanced manifest tweaks.getQueueSize()andretry()operate over the queue's Jobs via label selector.queue.utopia-php.com/*labels + annotations.Uses
appwrite-labs/php-k8sfor the Kubernetes API; no library changes were needed (itsK8sJob/K8sPod/Containersurface covers everything).Tests
unitsuite, bare host):KubernetesJobManifestTestasserts the generated manifest — names, labels/annotations, env-carried message, ttl/jobTtl, priority, pull policy, the config hook, and themessage()round-trip.e2esuite):KubernetesJobTestruns against a real kind cluster provisioned bytests/e2e.sh+ the packageTiltfile(builds & loads the worker image, applies the namespace). It proves: jobs run to completion, a failing job is marked failed, andretry()deletes the failed Job and re-enqueues a fresh one.Verified locally against kind (
kindest/node:v1.35.0): unitOK (50 tests),bin/monorepo check queueclean (pint + phpstan level 5), e2eOK (3 tests, 12 assertions).appwrite-labs/php-k8sis tagged0.1.0but not yet on Packagist. Submit it once at https://packagist.org/packages/submit (repohttps://github.com/appwrite-labs/php-k8s); after that,bin/monorepo test queue/ CIcomposer updatewill resolveappwrite-labs/php-k8s:^0.1and regenerate the lock. Until then composer resolution for this package will fail.🤖 Generated with Claude Code