vectorial1024/laravel-process-async 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

vectorial1024/laravel-process-async

Composer 安装命令:

composer require vectorial1024/laravel-process-async

包简介

Utilize Laravel Process to run PHP code asynchronously, as if using Laravel Concurrency.

README 文档

README

Packagist License Packagist Version Packagist Downloads PHP Dependency Version GitHub Repo Stars

Utilize Laravel Processes to run PHP code asynchronously, as if using Laravel Concurrency.

What really is this?

Laravel Processes was first introduced in Laravel 10. This library wraps around Process::start() to let you execute code in the background to achieve async, albeit with some caveats:

  • You may only execute PHP code
  • Restrictions from opis/closure apply (see their README)
  • Hands-off execution: no built-in result-checking, check the results yourself (e.g. via database, file cache, etc)

This library internally uses an Artisan command to run the async code, which is similar to Laravel 11 Concurrency.

Why should I want this?

This library is very helpful for these cases:

  • You want a cross-platform minimal-setup async for easy vertical scaling
    • pthreads is dead (source)
    • parallel is general-purpose and does not have Laravel integration
  • You want to start quick-and-dirty async tasks right now (e.g. prefetching resources, pinging remote, etc.)
    • Best is if your task only has very few lines of code
  • Laravel 11 Concurrency is too limiting; e.g.:
    • You want to do something else while waiting for results
    • You want to conveniently limit the max (real) execution time of the concurrent tasks
  • And perhaps more!

Of course, if you are considering extreme scaling (e.g. Redis queues in Laravel, multi-worker clusters, etc.) or guaranteed task execution, then this library is obviously not for you.

Installation

via Composer:

composer require vectorial1024/laravel-process-async

This library supports Unix and Windows; see the Testing section for more details.

Extra requirements for Unix

If you are on Unix, check that you also have the following:

  • GNU Core Utilities (coreutils)
    • MacOS do brew install coreutils!
    • Other Unix distros should check if coreutils is preinstalled

Change log

Please see CHANGELOG.md.

Example code and features

Tasks can be defined as PHP closures, or (recommended) as an instance of a class that implements AsyncTaskInterface.

A very simple example task to write Hello World to a file:

// define the task...
$target = "document.txt";
$task = new AsyncTask(function () use ($target) {
    file_put_contents($target, "Hello World!");
});

// if you are using interfaces, then it is just like this:
// $task = new AsyncTask(new WriteToFileTask($target, $message));

// then start it.
$task->start();

// the task is now run in another PHP process, and will not report back to this PHP process.

Task time limits

You can set task time limits before you start them, but you cannot change them after the tasks are started. When the time limit is reached, the async task is killed.

The default time limit is 30 real seconds. You can also choose to not set any time limit, in this case the (CLI) PHP max_execution_time directive will control the time limit.

Note: AsyncTaskInterface contains an implementable method handleTimeout for you to define timeout-related cleanups (e.g. write to some log that the task has timed out). This method is still called when the PHP max_execution_time directive is triggered.

// start with the default time limit...
$task->start();

// start task with a different time limit...
$task->withTimeLimit(15)->start();

// ...or not have any limits at all (beware of orphaned processes!)
$task->withoutTimeLimit()->start();

Some tips:

  • Don't sleep too long! On Windows, timeout handlers cannot trigger while your task is sleeping.
    • Use short but frequent sleeps instead.
  • Avoid using SIGINT! On Unix, this signal is reserved for timeout detection.

Task IDs

You can assign task IDs to tasks before they are run, but you cannot change them after the tasks are started. This allows you to track the statuses of long-running tasks across web requests.

By default, if a task does not has its user-specified task ID when starting, a ULID will be generated as its task ID.

// create a task with a specified task ID...
$task = new AsyncTask(function () {}, "customTaskID");

// will return a status object for immediate checking...
$status = $task->start();

// in case the task ID was not given, what is the generated task ID?
$taskID = $status->taskID;

// is that task still running?
$status->isRunning();

// when task IDs are known, task status objects can be recreated on-the-fly
$anotherStatus = new AsyncTaskStatus("customTaskID");

Some tips:

  • Task IDs can be optional (i.e. null) but CANNOT be blank (i.e. "")!
  • If multiple tasks are started with the same task ID, then the task status object will only track the first task that was started
  • Known issue: on Windows, checking task statuses can be slow (about 0.5 - 1 seconds) due to underlying bottlenecks

Securing the task runners

The way this library works means that attackers (or other unwanted parties) may simply craft malicious commands that mimic legitimate usage of this library.

To secure the task runners from being started illegitimately, you may configure the .env file to contain the following key:

PROCESS_ASYNC_SECRET_KEY=[your secret key here]

You may need to clear your Laravel optimisation cache after changing this value.

The contents of the async tasks will be signed by this secret key, so that this library can know whether the tasks are started by this library itself or someone else.

Fake Objects

Fake objects are available for users to simulate async task behaviors without actually starting async tasks. This should be helpful when writing tests that attempts to react to task statuses.

The following fake objects are available:

  • FakeAsyncTask: a fake of AsyncTask
  • FakeAsyncTaskStatus: a fake of AsyncTaskStatus

Notably, they can be used like this:

// you may obtain the task status in the usual way...
$fakeTask = new FakeAsyncTask(/* ... */, taskID: "TestingTask");
$fakeStatus = $fakeTask->start();

// ...or just construct it directly
$fakeStatusDirect = new FakeAsyncTaskStatus("TestingTask");
// both are the same
assert($fakeStatus == $fakeStatusDirect); // passes

// in your test code, fake task status can be used just like the normal task status:
$fakeStatus->isRunning(); // default returns true

// note: FakeAsyncTaskStatus defaults to "is running" when constructed
// to simulate "task ended", simply do:
$fakeStatus->fakeStopRunning();
// then, the following will return false
$fakeStatus->isRunning(); // returns false

Testing

PHPUnit via Composer script:

composer run-script test

Latest cross-platform testing results:

Runtime MacOS Ubuntu Windows
Laravel 10 (PHP 8.1) skipped* skipped* skipped*
Laravel 11 (PHP 8.2) Build-M-L11 Build-U-L11 Build-W-L11
Laravel 12 (PHP 8.3) Build-M-L12 Build-U-L12 Build-W-L12
Laravel 13 (PHP ???) 🛠️ 🛠️ 🛠️

*Note: tests for these Laravel versions are skipped because they have old artisan file contents:

  • It is difficult to mock multi-version artisan files for different Laravel versions (see #6).
  • It is rare for the artisan file at Laravel to be updated
  • The actual behavior is expected to be the same.

vectorial1024/laravel-process-async 适用场景与选型建议

vectorial1024/laravel-process-async 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 9 次下载、GitHub Stars 达 10, 最近一次更新时间为 2024 年 11 月 28 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「process」 「task」 「background」 「async」 「laravel」 「job」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 vectorial1024/laravel-process-async 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 vectorial1024/laravel-process-async 我们能提供哪些服务?
定制开发 / 二次开发

基于 vectorial1024/laravel-process-async 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 9
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 10
  • 点击次数: 23
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 10
  • Watchers: 1
  • Forks: 2
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2024-11-28