【问题标题】:Given array of 1000 strings wih an associated time-interval value X for each, how do I perform a task for each of the strings, every x minutes?给定 1000 个字符串的数组,每个字符串都有一个关联的时间间隔值 X,我如何每 x 分钟为每个字符串执行一项任务?
【发布时间】:2018-08-08 18:05:11
【问题描述】:

我有一千个(例如,可能更多)字符串,对于每个字符串,都有一个与之关联的字段,它表示 时间间隔

对于每个字符串,我需要执行一个任务,将字符串作为输入并产生一些输出,每隔X 分钟(X 是上面提到的时间间隔)。

如果它是所有字符串的单一时间间隔值,那么我将设置一个单一的 cron 作业,这就足够了;但我对每个字符串都有不同的时间间隔值。

所以我将设置一千个或更多的 cron 作业。那感觉不对。那么解决这个问题的最佳方法是什么?

【问题讨论】:

  • 如果我理解正确,你想用一个字符串做点什么,然后休眠 (secure.php.net/manual/en/function.sleep.php) 一些x 时间并转到下一个字符串?
  • 睡几分钟真的有用吗?那么浏览器不会直接终止连接吗?
  • 运行之间的“X”时间必须有多准确?
  • @Edwin Nooo。我有 1000 个字符串,对于每个字符串,我必须每 X 分钟执行一些任务(这会永远持续下去),这样每个字符串的 X 都是不同的。增加的复杂性:每个字符串的任务必须异步/同时执行。换句话说,所有字符串的任务应该(几乎)同时触发/启动(几秒钟的差异是可以的)
  • @Andreas 它可以是一个完成整个睡眠工作的 cron 工作

标签: php cron cron-task


【解决方案1】:

您可能想考虑使用已经这样做的库,而不是自己重新发明轮子。

https://packagist.org/packages/peppeocchi/php-cron-scheduler

但是,如果您真的想自己编写代码,您需要有“两个变量”,一个是最后执行的,必须在执行周期之间从文件或数据库中读取,一个有间隔并有 cron每秒/分钟调用一次你的脚本

在此处查看概念验证代码。未经测试,但它应该指出它在理论上应该如何工作。

class Job 
{
    protected $interval = 0;
    protected $lastrun = 0;
    protected $job = null; 
    protected $filename = null;   

    public function __construct($id, $interval,callable $job) 
    {
         $this->interval = $interval;
         $this->job = $job;
         $this->filename = __DIR__.'/'.$id.'.job';
         $this->lastrun = file_get_contents($this->filename) ? : 0;
    }

    public function attemptRun($time) 
    {
       if($time - $this->lastrun >= $this->interval) {
           $this->run($time);
       }
    }

    protected function run($time) 
    {
         file_put_contents($this->filename, $time);
         $this->job();
    }

}

$jobs = [
   new Job('addition', 10, function() { $a = 1; $b = 2; $c = $a + $b;}),
   new Job('subtraction', 20, function() { $a = 1; $b = 2; $c = $a - $b;}),
];

var $currentTime = time();
foreach($jobs as $job) {
   $job->attemptRun($currentTime);
} 

【讨论】:

  • 如果我没记错的话,这个脚本只会在$interval时间过去后运行一次。我需要定期运行作业
  • @JBel 是一个固定的时间间隔......如果你让 cron 每秒触发一次,则作业每 10 秒和 20 秒运行一次。在第一次运行时,所有作业都会运行,然后间隔计时器启动。
【解决方案2】:

Cron 作业:每分钟运行一次。

假设您有 3 个字符串,格式为 string_value-execute after certain minutes-

  • some_string-5
  • some_string_2-10
  • some_string_3-15

所以,如果我们从 0 开始,执行时间会有一个这样的序列-

  • 0
  • 5(先执行)
  • 10(执行第一个和第二个字符串)
  • 15(执行第一个和第三个字符串)
  • 20(执行第一个和第二个字符串)
  • 25(仅先执行)
  • 30(执行第一、二、三)

数据库部分:

有 2 张桌子。

  • 第一个表 - 有一个具有当前 cron 分钟的列。
  • 第二个表 - 将列作为字符串、间隔持续时间、下一个执行时间

现在,无论何时运行它都插入第一个表。 其次,执行“Select * from table_name where next_execution_time = current_got_fetched_from_first_table”。

引入新字符串- 当您这样做时,插入为first start interval = current_cron_time + interval_duration to execute

P.S- 处理完成后,您还需要使用它们各自的next_execution_time 更新第二个表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-22
    • 2018-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-25
    • 2013-05-22
    • 1970-01-01
    相关资源
    最近更新 更多