fullscreeninteractive/silverstripe-queuedjob-progressfield

显示一个友好的表单字段,用于显示队列作业的进度

安装次数: 3,818

依赖关系: 0

建议者: 0

安全: 0

星级: 6

关注者: 2

分支: 0

开放问题: 11

语言:JavaScript

类型:silverstripe-vendormodule


README

一个进度条和屏幕,用于监控SilverStripe的计划任务

Build Status Version License

demo

安装

composer require fullscreeninteractive/silverstripe-queuedjob-progressfield

使用

可以将队列进度字段包含在任何Form

use FullscreenInteractive\QueuedJobProgressField\QueuedJobProgressField;

$fields = [
    // ...
    QueuedJobProgressField::create('ScheduledJob', '', $this->ScheduledJobID)
];

此模块还提供了一个Controller子类,如果需要,可以显示作业的状态。设置一个路由指向QueuedJobProgressController

SilverStripe\Control\Director:
  rules:
    'upload//$Action/$ID': 'FullscreenInteractive\QueuedJobProgressField\QueuedJobProgressController'

然后,您可以将用户重定向到site.com/upload/progress/<jobSignature>/<jobId>以查看作业的实时进度。

demo-web

用户体验技巧

覆盖重定向位置

将用户重定向到site.com/upload/progress/<jobSignature>/<jobId>显示作业的运行状态。如果作业成功,则激活用户的继续按钮。默认情况下,继续按钮将重定向用户,但可以使用原始链接上的ContinueLink查询参数覆盖此行为。

site.com/upload/progress/<jobSignature>/<jobId>?ContinueLink=/thanks/

同样,如果作业失败、停滞或发生其他错误,您可以设置按钮的不同链接。

site.com/upload/progress/<jobSignature>/<jobId>?FailureLink=/error/

长时间运行的单个进度作业

由于队列作业的设计,进度指示器(currentStep)仅在process调用结束时在数据库中修改。有时对于长时间运行的单进程作业,我们需要更详细地显示进度。QueuedJobProgressService被设计为QueuedJobService的即插即用替代品。该服务允许您的作业更频繁地更新作业描述符。

示例作业

use Symbiote\QueuedJobs\DataObjects\QueuedJobDescriptor;
use Symbiote\QueuedJobs\Services\AbstractQueuedJob;
use FullscreenInteractive\QueuedJobProgressField\QueuedJobProgressService;
use SilverStripe\Core\Injector\Injector;

class MyAwesomeJob extends AbstractQueuedJob
{
    protected $descriptor;

    /**
     * By default the job descriptor is only ever updated when process() is
     * finished, so for long running single tasks the user see's no process.
     *
     * This method manually updates the count values on the QueuedJobDescriptor
     */
    public function updateJobDescriptor()
    {
        if (!$this->descriptor && $this->jobDescriptorId) {
            $this->descriptor = QueuedJobDescriptor::get()->byId($this->jobDescriptorId);
        }

        // rate limit the updater to only 1 query every sec, our front end only
        // updates every 1s as well.
        if ($this->descriptor && (!$this->lastUpdatedDescriptor || $this->lastUpdatedDescriptor < (strtotime('-1 SECOND')))) {
            Injector::inst()->get(QueuedJobProgressService::class)
                ->copyJobToDescriptor($this, $this->descriptor);

            $this->lastUpdatedDescriptor = time();
        }
    }

    public function process()
    {
        $tasks = [
            // ..
        ];

        foreach ($tasks as $task) {
            $this->currentStep++;

            // sends feedback to the database in the middle of process() allowing
            // long single processes to continue.
            $this->updateJobDescriptor();
        }

        $this->isComplete = true;
    }
}