Skip to content

Fix #59: inject the cache store into LocalSimulatorDriver and read task_ttl from its own config - #106

Open
corgab wants to merge 2 commits into
mainfrom
fix/59-local-driver-injection
Open

Fix #59: inject the cache store into LocalSimulatorDriver and read task_ttl from its own config#106
corgab wants to merge 2 commits into
mainfrom
fix/59-local-driver-injection

Conversation

@corgab

@corgab corgab commented Sep 8, 2026

Copy link
Copy Markdown
Owner

Summary

LocalSimulatorDriver was the only driver reaching Laravel directly: the Cache facade for the dispatched results and the global config() helper for their retention. Every other driver reads its options from the injected config array and touches the framework only through injected collaborators. This PR brings the local driver in line, as the issue proposes.

Plan

  1. Take the cache store through the constructor (Illuminate\Contracts\Cache\Repository), next to the PythonExecutor, and use it in submitCircuit() / checkTask().
  2. Read the retention from the driver's own config array as task_ttl, which moves the option from the top-level aether.local_task_ttl to aether.drivers.local.task_ttl. The env var AETHER_LOCAL_TASK_TTL is unchanged, and the manager keeps honouring the old key from an already published config file.
  3. Make the unit test run without a facade root or a container: an in-memory repository is injected, and a mocked one pins the TTL the driver passes to put().

Changes

  • src/Drivers/LocalSimulatorDriver.php: constructor (PythonExecutor $bridge, array $config, CacheRepository $cache); Cache::put() / Cache::get() become $this->cache->...; taskTtl() reads task_ttl with a DEFAULT_TASK_TTL = 3600 fallback for a blank, non-numeric or non-positive value. The constructor docblock notes that the injected store is fixed for the driver's lifetime (it is rebuilt after Quantum::forgetDrivers()), where the facade re-resolved the default store on every call.
  • src/QuantumManager.php: createLocalDriver() resolves the cache contract from the container, and copies a legacy top-level aether.local_task_ttl into the driver config when task_ttl is absent (an explicit task_ttl always wins).
  • config/aether.php: the "Local Task Retention" block moves under drivers.local as task_ttl, comment included; its default references LocalSimulatorDriver::DEFAULT_TASK_TTL so the value lives in one place.
  • README.md: the local ->dispatch() paragraph names the option and its default.
  • tests/Unit/Drivers/LocalSimulatorDriverTest.php: the Cache::swap() and bare-container setup are gone; the driver is built with an ArrayStore repository. New dataset test: a configured, string-from-env, absent, zero and garbage task_ttl each produce the expected put() TTL.
  • tests/Feature/ServiceProviderTest.php: shipped default, legacy-key fallback, explicit key precedence.
  • tests/Feature/LifecycleEventsTest.php, tests/Feature/AsynchronousExecutionTest.php: hand-built local drivers pass the app's cache repository.

Upgrade notes

  • LocalSimulatorDriver::__construct() takes a third argument, the cache repository. Code that builds the driver by hand (a Quantum::extend('local', ...) closure, a subclass) passes app(\Illuminate\Contracts\Cache\Repository::class) or any repository of its choice.
  • aether.local_task_ttl is now aether.drivers.local.task_ttl. A published config file with the old key keeps working through the manager's fallback; move the key when you next republish.

Overlap

#104 (#57) adds AetherConfig::localTaskTtl() over the old top-level key and has the driver read through it. If this PR merges first, that method and the driver change in #104 can be dropped; if #104 merges first, this PR's version of taskTtl() and the moved config key win. #103 (#66) types the driver config; task_ttl can join DriverConfig there as a positive integer.

Tests

  • vendor/bin/pint --test passes.
  • vendor/bin/pest --compact: 799 tests, 1 skipped (791 before: +8).

Closes #59

…nd read task_ttl from its own config

LocalSimulatorDriver was the only driver reaching Laravel directly: the
Cache facade for the dispatched results and the global config() helper for
their retention. It now takes a cache repository through its constructor,
next to the PythonExecutor, and reads the retention from its own config
array as `task_ttl`, so the option moves from the top-level
aether.local_task_ttl to aether.drivers.local.task_ttl (same env var).

The unit test no longer needs a facade root or a bare container: an
in-memory repository is injected, and a mocked one pins the TTL passed to
put() for a configured, string, absent, zero and garbage value.

Closes #59
…default

createLocalDriver() copies a top-level aether.local_task_ttl into the driver
config when drivers.local.task_ttl is absent, so a config file published
before the key moved keeps its retention. The shipped default now points at
LocalSimulatorDriver::DEFAULT_TASK_TTL, and the constructor docblock notes
that the injected store is fixed for the driver's lifetime.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[maintainability] LocalSimulatorDriver is the only driver mixing injected config with the global config() helper and a facade

1 participant