【问题标题】:What is the most efficient way to trigger x actions per minute interval?每分钟间隔触发 x 个动作的最有效方法是什么?
【发布时间】:2012-11-19 00:02:00
【问题描述】:

想象一个呼叫中心,每分钟呼叫次数不能超过 2 个。因此,超出该范围的任何人都将获得电子邮件支持链接 ($bTrigger = FALSE)。其他所有人 ($bTrigger = TRUE) 都会获得技术支持电话号码。

脚本是 PHP。那么,最有效和最准确的构建方法是什么?

这是我目前所拥有的,但不幸的是它每分钟只触发一次。我似乎无法弄清楚为什么它不会每分钟运行两次。

<?php

$bTrigger = FALSE;
$sDir = dirname(__FILE__);
$sDir = rtrim($sDir,'/');
$sFile = $sDir . '/MINUTE-TIMER.txt';

$sLine = @ file_get_contents($sFile);
$sLine = str_replace("\r\n",'',$sLine);
$sLine = str_replace("\r",'',$sLine);
$sLine = str_replace("\n",'',$sLine);
$sLine = str_replace("\t",'',$sLine);
$asParts = explode(',',$sLine);
$nLetThru = @ $asParts[0];
$nLetThru = intval($nLetThru);
$nLastMin = @ $asParts[1];
$nLastMin = intval($nLastMin);
$nCurMin = intval(date('i'));
if (empty($sLine)) {
  $nLetThru = 0;
  $nLastMin = 0;
}

$nMaxLetThru = 2;

if ($nCurMin != $nLastMin) { // meaning, a new minute since last checked
  if ($nLetThru <= $nMaxLetThru) { // meaning, we haven't hit more than max allowed
    $bTrigger = TRUE;
    ++$nLetThru;
    file_put_contents($sFile,"$nLetThru,$nCurMin");
  } else {
    file_put_contents($sFile,"0,$nCurMin");
  }
}

if ($bTrigger) {
  echo 'TRIGGERED!!!!';
} else {
  echo 'not triggered';
}

【问题讨论】:

  • 我们是来帮助解决具体问题的,而不是为你做你的工作。
  • @MarcB 我即将回答这个问题,然后人们可以挑战这个答案。我会从挑战中学习。
  • 好的,已经足够反对投票和关闭请求了。在 META 中哪里说我无法显示我卡住的代码示例,看看人们是否无法修复它?
  • 嗯? “不是一个真正的问题?”这是荒谬的!当然,这是一个真正的问题。问题是一个简单的编码错误:当分钟改变时,$nLetThru 没有被重置。
  • @Matt:没问题;由于问题尚未结束,我只是将答案发布为答案,这显然是更好的地方。谢谢。

标签: php timer intervals


【解决方案1】:
<?php

$bTrigger = TRUE;
$config = (object) array();
$config->THROTTLE_ENABLED = TRUE;
$config->THROTTLE_MAX_PER_MINUTE = 2;
if ($config->THROTTLE_ENABLED) {

    $bThrottleTrigger = FALSE;
    $sDir = dirname(__FILE__);
    $sDir = rtrim($sDir,'/');
    $sFile = $sDir . '/MINUTE-TIMER.txt';

    $sLine = @ file_get_contents($sFile);
    $sLine = str_replace("\r\n",'',$sLine);
    $sLine = str_replace("\r",'',$sLine);
    $sLine = str_replace("\n",'',$sLine);
    $sLine = str_replace("\t",'',$sLine);
    $asParts = explode(',',$sLine);
    $nLetThru = @ $asParts[0];
    $nLetThru = intval($nLetThru);
    $nLastMin = @ $asParts[1];
    $nLastMin = intval($nLastMin);
    $nCurMin = intval(date('i'));
    if (empty($sLine)) {
        $nLetThru = 0;
        $nLastMin = 0;
    }

    if ($nCurMin != $nLastMin) { // meaning, a new minute since last checked
        if ($nLetThru < $config->THROTTLE_MAX_PER_MINUTE) { // meaning, we haven't hit more than max allowed
            $bThrottleTrigger = TRUE;
            ++$nLetThru;
            @ file_put_contents($sFile,"$nLetThru,$nLastMin");
        } else {
            @ file_put_contents($sFile,"0,$nCurMin");
        }
    } else {
        @ file_put_contents($sFile,"0,$nCurMin");
    }

    if (!$bThrottleTrigger) { // will be like most of the time
        $bTrigger = FALSE; // don't show the number
    }

} // end if ($config->THROTTLE_ENABLED)

【讨论】:

  • 这几乎是正确的,但是当分钟没有改变时,您需要检查计数。当分钟改变时,您应该继续让用户通过,并将计数器设置为 1。当分钟没有改变时,检查计数器,如果它小于 2,则增加它并让呼叫通过,否则不要让电话通过。
【解决方案2】:

问题是一个简单的编码错误:当分钟改变时,$nLetThru 没有被重置。 (另外,你的

这是固定代码(基于原始版本,在问题中):

if (empty($sLine)) {
  $nLastMin = -1; # (instead of 0) just affects the 1st time thru, 1 chance in 60
}

...

if ($nCurMin != $nLastMin) { // new minute
  $bTrigger = TRUE;
  $nLetThru = 1;
} else { // another hit, same minute
  if ($nLetThru < $nMaxLetThru) { // not too many yet
    $bTrigger = TRUE;
    ++$nLetThru;
  }
}
if ($bTrigger) {
  file_put_contents($sFile,"$nLetThru,$nCurMin");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多