承接 vxm/laravel-async 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

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

vxm/laravel-async

Composer 安装命令:

composer require vxm/laravel-async

包简介

Provide an easy way to run code asynchronously for Laravel

README 文档

README

Laravel Async


Latest version Build status Total download License

About it

A package provide an easy way to run code asynchronous and parallel base on Spatie Async wrapper for Laravel application.

Installation

Require Laravel Async using Composer:

composer require vxm/laravel-async

The package will automatically register itself.

You can publish the config-file (optional) with:

php artisan vendor:publish --provider="VXM\Async\AsyncServiceProvider" --tag="config"

This is the contents of the published config file:

return [
    /*
     * The PHP binary will be use in async processes.
     */
    'withBinary' => PHP_BINARY,

    /*
     * Maximum concurrency async processes.
     */
    'concurrency' => 20,

    /*
     * Async process timeout.
     */
    'timeout' => 15,

    /*
     * Sleep (micro-second) time when waiting async processes.
     */
    'sleepTime' => 50000,

    /*
     * Default output length of async processes.
     */
    'defaultOutputLength' => 1024 * 10,

    /*
     * An autoload script to boot composer autoload and Laravel application.
     * Default null meaning using an autoload of this package.
     */
    'autoload' => null,
];

Usage

Run async code

After install, now you can try run async code via Async facade:

use VXM\Async\AsyncFacade as Async;

for ($i = 1; $i < 20; $i++) {
    Async::run(function () use ($i) {
        sleep(1);

        return $i;
    });
}

var_dump(implode(', ', Async::wait()));

// Output value may be like:
// string(65) "5, 2, 1, 14, 4, 6, 7, 8, 19, 16, 12, 18, 13, 3, 10, 9, 11, 17, 15"

An async job can be callable class, anonymous function or Laravel callback:

use VXM\Async\AsyncFacade as Async;

// run with anonymous function:
Async::run(function() {
    // Do a thing
});

// run with class@method
Async::run('Your\AsyncJobs\Class@handle');

// call default `handle` method if method not set.
Async::run('Your\AsyncJobs\Class');

You can run multiple job one time and waiting until all done.

use VXM\Async\AsyncFacade as Async;

Async::run('Your\AsyncJobs\Class@jobA');
Async::run('Your\AsyncJobs\Class@jobB');
Async::run('Your\AsyncJobs\Class@jobC');
Async::run('Your\AsyncJobs\Class@jobD');

// Another way:

Async::batchRun(
    'Your\AsyncJobs\Class@jobA',
    'Your\AsyncJobs\Class@jobB',
    'Your\AsyncJobs\Class@jobC',
    'Your\AsyncJobs\Class@jobD'
);

$results = Async::wait(); // result return from jobs above

Event listeners

When creating asynchronous processes, you can add the following event hooks:

use VXM\Async\AsyncFacade as Async;

Async::run(function () {

    return 123;
}, [
    'success' => function ($output) { 
        // `$output` of job in this case is `123`.
    },
    'timeout' => function () { 
        // A job took too long to finish.
    },
    'error' => function (\Throwable $exception) {
        // When an exception is thrown from job, it's caught and passed here.
    },
]);

// Another way:
Async::run('AsyncJobClass@handleMethod', [
    'success' => 'AsyncJobEventListener@handleSuccess',
    'timeout' => 'AsyncJobEventListener@handleTimeout',
    'error' => 'AsyncJobEventListener@handleError'
]);

Async::batchRun(
    ['AsyncJobClassA@handleMethod', ['success' => 'AsyncJobEventListenerA@handleSuccess']],
    ['AsyncJobClassB@handleMethod', ['success' => 'AsyncJobEventListenerB@handleSuccess']],
    ['AsyncJobClassC@handleMethod', ['success' => 'AsyncJobEventListenerC@handleSuccess']]
);

Working with complex job

When working with complex job you may want to setup more before it run (ex: job depend on Eloquent model). This package provide you an Artisan command make:async-job to generate a job template. By default, all of the async jobs for your application are stored in the app/AsyncJobs directory. If the app/AsyncJobs directory doesn't exist, it will be created. You may generate a new async job using the Artisan CLI:

php artisan make:async-job MyJob

After created it, you need to prepare your job structure, example:

namespace App\AsyncJobs;

use App\MyModel;
use VXM\Async\Invocation;
use App\MyHandleDependency;
use Illuminate\Queue\SerializesModels;

class MyJob
{

    use Invocation;
    use SerializesModels;

    protected $model;
    
    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(MyModel $model)
    {
        $this->model = $model;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle(MyHandleDependency $dependency)
    {
        //
    }
}

In this example, note that we were able to pass an Eloquent model directly into the async job's constructor. Because of the SerializesModels trait that the job is using, Eloquent models will be gracefully serialized and unserialized when the job is processing. If your async job accepts an Eloquent model in its constructor, only the identifier for the model will be serialized onto the queue. When the job is actually handled, the system will automatically re-retrieve the full model instance from the database. It's all totally transparent to your application and prevents issues that can arise from serializing full Eloquent model instances.

The handle method is called when the job is processed in async process. Note that we are able to type-hint dependencies on the handle method of the job. The Laravel service container automatically injects these dependencies.

If you would like to take total control over how the container injects dependencies into the handle method, you may use the container's bindMethod method. The bindMethod method accepts a callback which receives the job and the container. Within the callback, you are free to invoke the handle method however you wish. Typically, you should call this method from a service provider:

use App\AsyncJobs\MyJob;
use App\MyHandleDependency;

$this->app->bindMethod(MyJob::class.'@handle', function ($job, $app) {
    return $job->handle($app->make(MyHandleDependency::class));
});

Now run it asynchronously:

use VXM\Async\AsyncFacade as Async;
use App\MyModel;
use App\AsyncJobs\MyJob;

$model = App\MyModel::find(1);

Async::run(new MyJob($model));

// or batch run with multiple models:

$model2 = App\MyModel::find(2);

Async::batchRun(
    new MyJob($model),
    new MyJob($model2)
);

Compare with queue

You can feel this package look like queue and thing why not using queue?

Queue is a good choice for common async jobs. This package using in cases end-user need to get response in single request but it's a heavy things need to using several processes for calculation or IO heavy operations. And it no need to run a queue listener.

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

vxm/laravel-async 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 347.72k 次下载、GitHub Stars 达 157, 最近一次更新时间为 2019 年 06 月 12 日, 在 PHP 生态内属于活跃度较高的组件。

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

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

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

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

BUG 修复 & 性能优化

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

项目外包 & 长期维护

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

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

统计信息

  • 总下载量: 347.72k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 157
  • 点击次数: 22
  • 依赖项目数: 1
  • 推荐数: 0

GitHub 信息

  • Stars: 157
  • Watchers: 5
  • Forks: 31
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2019-06-12