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 Process Manager Laravel Package

robotomarvin/symfony-process-manager

A lightweight PHP manager for Symfony Process that simplifies running, tracking, and controlling multiple concurrent processes. Handle output, errors, exit codes, and lifecycle events through a clean, fluent API.

View on GitHub
Deep Wiki
Context7

Getting Started

This release (v0.0.2) is a breaking update for anyone on v0.0.1: the config root key and several metric labels changed. Treat the upgrade as a code+config+dashboard change, not a drop-in bump.

  1. Update the package and republish/compare config. The root key transports: becomes consumers:. Each consumer now owns one or more transports::
// config/... (package config)
'consumers' => [
    'default' => [
        'transports' => 'default',            // scalar: single transport
        'autoscaler' => ['strategy' => 'fixed', 'workers' => 2],
    ],
    'priority' => [
        'transports' => ['main', 'failed'],   // list: main drained first, failed as fallback
    ],
],
  1. Look first at the worker command the bundle generates. A consumer with a list spawns messenger:consume t1 t2 ..., so list order is your scheduling policy, not a detail.
  2. Then look at /metrics. AutoscalerLoop::emitPoolGauges() now runs at start(), so gauges exist immediately — you can validate a deploy without waiting for the first periodic tick.
  3. First use case: one consumer, one transport, scrape /metrics, import the bundled dashboard, confirm consumer (not transport) is the template variable.

Implementation Patterns

Priority vs. fair sharing is a config decision, not a runtime one. The worker drains transports in list order. Use lists only for primary/fallback:

'transports' => ['main', 'failed'], // main first; 'failed' only gets attention when main is empty

For genuine sharing (two transports both deserve ~50% throughput), declare two consumers, each with one transport. A single consumer with ['t1', 't2'] will starve t2 under sustained t1 load — that's the intended semantics.

Migration workflow (do it in this order):

# 1. config rename
grep -rn "transports:" config/   # find root-level usage, not per-consumer lists
# 2. metric label rename in dashboards/alerts
grep -rn "transport" dashboards/ monitoring/ alerts/
# 3. re-import bundled dashboard if you imported it ($transport -> $consumer)

Update PromQL deliberately. Lifecycle counters are now {consumer} only; per-transport fan-out was removed on purpose so rate() doesn't multiply by transport-list length:

sum by (consumer) (rate(worker_failures_total[5m]))
sum by (consumer) (rate(worker_backoffs_total[5m]))
sum by (consumer, exit_code) (increase(worker_exits_total[1h]))

Keep transport where it's still real — messages_processed_total and worker_busy source it from WorkerMessage*Event::getReceiverName(), and transport-level failure visibility is still:

sum by (transport, message_class) (rate(messenger_messages_failed_total[5m]))

Autoscaler visibility pattern. Because pool gauges are emitted at start(), a Fixed-strategy pool is observable from second zero. Use this for deploy verification: after a rollout, assert autoscaler_target_workers{consumer="x"} equals expected before trusting the HPA/alerting layer.

Log correlation. Worker logs are prefixed [worker N consumer-label] and JSON context carries extra.consumer. If you parse worker logs, update the regex/parser; if you aggregate by consumer in Loki/CloudWatch, key on extra.consumer rather than the prefix string.

Gotchas and Tips

  • Config rename fails silently in the wrong direction. Leaving a stale transports: root key means consumers you think you declared don't exist. After upgrading, dump the resolved worker command per consumer and confirm each one is what you expect before deploying.
  • Dashboards go blank, not red. Panels pinned to transport on lifecycle counters return no data rather than erroring. Search for the label, not for a broken panel — an unrelated Grafana refresh won't surface it.
  • $transport template variable is gone from the bundled dashboard. Re-import; don't hand-edit, since panels were reflowed too.
  • absent() alerts will change behaviour. Pool gauges now exist immediately, so alerts written as absent(autoscaler_target_workers{...}) will stop firing — that's a fix, but it also means they no longer catch a genuinely dead autoscaler loop. Re-scope to a staleness check on the metric timestamp if you relied on that.
  • worker_exits_total{consumer, exit_code} — filter exit_code!="0" for crash alerting. Cardinality is bounded, and the per-code breakdown is worth keeping for distinguishing OOM kills from graceful exits.
  • You lose per-transport lifecycle attribution for transports shared by multiple consumers. worker_starts_total etc. tell you which consumer restarted, not which transport inside it. If that granularity matters, one consumer per transport.
  • Priority lists can look like a bug. "t2 is never consumed" is usually correct behaviour under load; don't open an issue before confirming the transport ordering in config.
  • Log-prefix change breaks naive parsers. Any regex anchored on the old [worker N] form will misfire; anchor on consumer instead.
  • Extension point worth knowing: the WorkerMessage*Event payloads carry the real receiver name, which is why messages_processed_total kept its transport label. If you add custom metrics or listeners, source transport from there rather than from consumer config, or you'll reintroduce the fan-out problem this release removed.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect