问题摘要
我有一个每小时运行的命令。它循环并排列6个项目并将数据发布到Twitter。问题是它会将所有6个项目同时发布到Twitter。我希望循环的每个元素每10分钟交错一次。这样,twitter追踪者就不会每小时收到来自我们的推文。
我尝试过的事情
我确实做了一个不太优雅的解决方案。只需将sleep(600);
添加到循环中即可。
foreach ($parks as $park) {
Twitter::post(...);
sleep(600);
}
这很好,但是我觉得比将这个过程运行一个小时更好。
答案 0 :(得分:4)
我会使用一个Job并将其排队等待一段时间。例如:
<?php
namespace App\Jobs;
use App\Park;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class PostToTwitter implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
/**
* The tweet
*
* @var App\Park
*/
public $park;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct(Park $park)
{
$this->park = $park;
}
/**
* Execute the job.
*
* @return void
*/
public function handle()
{
// handles posting to twitter
}
}
...然后将其排队。
foreach ($parks as $key => $park) {
$job = (new PostToTwitter($park))
->delay(now()->addMinutes($key * 10));
dispatch($job);
}
在这种情况下,每个作业都会延迟10分钟。
答案 1 :(得分:0)
如果您有队列系统,建议您使用delayed dispatching而不是cronjob。您还可以每小时安排一次计划的cronjob,以调度这些计划的队列作业中的六个。
如果您喜欢使用当前系统,则可以使用date('i')
来获取当前小时数。然后,您可以将分钟除以10,并将结果四舍五入。它将为您提供0到5之间的数组索引:
$minutes = (int) date('i');
$index = floor($minutes / 10);
$park = $parks[$index];
有了这种逻辑,您可以简单地将当前作业安排为每十分钟而不是每小时运行一次。
注意:为了安全起见,您可能要检查$index
是否在数组范围内。