Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Symfony Aop Pool Bundle Laravel Package

tourze/symfony-aop-pool-bundle

Symfony bundle that brings aspect-oriented pooling to your services: wrap expensive resources in configurable pools via AOP interceptors, with acquire and release handled automatically.

View on GitHub
Deep Wiki
Context7

Getting Started

tourze/symfony-aop-pool-bundle is a Symfony bundle, not a Laravel package — that distinction drives everything below. There is no ServiceProvider, no extra.laravel block, and no package discovery. Read the release as "an AOP engine you can borrow from," not "a package you composer require and forget."

  1. composer require tourze/symfony-aop-pool-bundle and immediately read composer.json — the require block tells you which Symfony components you are dragging in (framework-bundle, dependency-injection, the underlying AOP/proxy library) and the minimum PHP version. This is the single most important file before you write a line of code.
  2. Read, in this order:
    • the bundle class (*Bundle.php) — shows what compiler passes and config it registers;
    • DependencyInjection/Configuration.php — the authoritative list of config keys, since docs are typically thin on tourze/* packages;
    • DependencyInjection/*Extension.php — how services are wired and which parameters/tags matter;
    • Resources/config/*.yaml — the actual service definitions, and usually the clearest documentation of intent;
    • any Attribute/ or Annotation/ directory — this is where the marker attributes that make a method "advised" live.
  3. First use case: annotate one method on one service with the aspect attribute and confirm a proxy is generated. Do this in a throwaway Symfony micro-kernel (see below), not inside your Laravel app — you want to isolate whether the AOP layer works before adding container-bridging complexity.

First realistic decision point: if you cannot articulate the cross-cutting concern in one sentence (audit logging, timing/metrics, retry, tenant scoping), stop. Laravel already solves most of these more cheaply.

Implementation Patterns

Pattern A — Micro-kernel bridge (the only sane way to use the bundle itself in Laravel). The bundle needs Symfony's DI container, compiler passes, and config tree. Laravel will not provide them. Boot a minimal Symfony ContainerBuilder (or a tiny Kernel) inside a Laravel service provider, register the bundle, compile, and resolve the AOP-managed services from that container:

// App\Providers\AopServiceProvider
public function register(): void
{
    $container = new ContainerBuilder();
    $container->setParameter('kernel.debug', config('app.debug'));
    $container->setParameter('kernel.environment', app()->environment());
    $container->setParameter('kernel.build_dir', storage_path('framework/aop'));
    (new TourzeAopPoolBundle())->build($container);
    $container->compile();

    $this->app->instance('aop.container', $container);
    $this->app->bind(BillingCalculator::class, fn () => $container->get(BillingCalculator::class));
}

You are now maintaining two containers. Budget for that. Resolve only the handful of classes that actually need advice through this container; leave the rest on Laravel's.

Pattern B — Use the underlying AOP library directly. In practice the bundle is a thin Symfony wrapper over a proxy-generating AOP engine. If you only need interception, depend on the engine, write your own ServiceProvider, and generate proxies into storage_path(). You lose the bundle's pool/warmup wiring but gain something you can debug.

Pattern C — Translate the intent into Laravel-native constructs. For most teams this is the correct outcome:

AOP aspect you'd write Laravel equivalent
Transactional advice DB::transaction() closure, or DB::transactionLevel() guards
Timing/metrics advice Middleware + Telescope/Clockwork, or a decorator binding
Retry advice Retry::times(3)->sleep(100)->run(...)
Audit logging Model observers / events
Tenant or scope enforcement Global scope, middleware, or a container decorator

Aspect hygiene, if you go with A or B. One aspect class per concern; pointcuts narrowed by attribute, never by naming convention across the whole namespace. A wildcard pointcut in a pooled/proxied container is how you get a 3-second boot time and an unreadable stack trace.

Pool semantics. The "pool" in the name implies reuse of interceptor/aspect instances across advised calls. That makes aspects stateful by accident. Keep aspect properties immutable; anything request-scoped (tenant id, correlation id, authenticated user) must be injected per-invocation, not stored on the aspect.

Gotchas and Tips

  • No Laravel auto-discovery. composer require will silently do nothing until you register something. A fresh composer require followed by "it does nothing" is the most common first-hour complaint.
  • final classes and private/static methods cannot be advised. Proxy-based AOP requires subclassing. If your service is final, you get no advice and usually no error — just silence. Remove final, or extract an interface and type-hint the interface everywhere.
  • Type-hint the interface, never the concrete class. If you inject BillingCalculator and the container returns a proxy, instanceof checks, get_class() comparisons, and strict constructor hints against the concrete name will fail or bypass the proxy entirely. $object::class returns the proxy class name — never persist or switch on it.
  • Proxies are a deploy artifact. Generate into storage_path('framework/aop') (or equivalent), ensure it's gitignored, writable by the web user, and cleared during deploy alongside php artisan optimize:clear. Stale proxies after a deploy are the #1 debugging sink: the code is right, the proxy is old. Add a cache-busting step keyed on composer.lock.
  • Debugging is a container problem, not a code problem. When advice doesn't fire, check in this order: (1) is the class final? (2) was the instance resolved from the AOP container or from Laravel's? (3) does the proxy file exist on disk and is its mtime newer than the class? (4) debug:container (Symfony) to confirm the service is decorated. Do not start by reading the aspect code.
  • Octane / long-lived workers. This is the sharpest edge. Aspect instances held by a compiled container survive across requests. Any request-scoped state captured during construction leaks to the next request. Under Octane, either flush the AOP container in a RequestTerminated listener or guarantee aspects are stateless. Symptom: user A's tenant id appearing in user B's logs, intermittently, only in production.
  • Serialization and queues. Proxied objects (queued jobs, DTOs on the wire) serialize the proxy class name. unserialize() on a worker that hasn't generated proxies fails. Keep advised classes out of job payloads; pass scalars.
  • Boot-time cost. Container compilation plus proxy generation is measurable. Do not recompile per request — compile once at deploy, warm into the build directory, and assert in CI that the warm step passes.
  • Configuration quirks. tourze/* packages commonly ship a Configuration.php whose keys don't match examples in the README. Treat Configuration.php as the spec. Undefined keys are usually silently ignored rather than throwing — verify your config actually took effect by dumping the resolved parameters.
  • Extension points worth knowing: the aspect/advice base class or interface (your insertion point), the compiler pass that tags advised services, and the config tree (for pool sizing / warmup dirs). If the bundle is too opinionated, the compiler pass is the surgical override.
  • Version posture. 1.0.1 is a patch bump whose only published artifact is a compare link — no changelog prose. Treat the 1.0.x line as pre-stable: pin "tourze/symfony-aop-pool-bundle": "1.0.1" exactly, and read the GitHub diff (1.0.0...1.0.1) before bumping. For a project of this size, assume semantic versioning is aspirational and every bump carries a small breaking-change risk.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin