【问题标题】:PHP Gearman Duplicate tasksPHP Gearman 重复任务
【发布时间】:2013-01-27 00:04:59
【问题描述】:

我明白了:

  • Debian 6
  • nginx 1.2.6
  • PHP 5.3.20-1~dotdeb.0 (fpm-fcgi)(构建时间:2012 年 12 月 24 日 11:53:16)
  • gearmand 1.1.4
  • pecl gearman ext 1.1.1

我得到了两个脚本(可能是我从 php 复制的)。客户:

<?php
$gmc= new GearmanClient();
$gmc->addServer();

$gmc->setCompleteCallback("reverse_complete");
$gmc->setStatusCallback("reverse_status");

$gmc->addTask("reverse", "!dlroW olleH", null, "2");

if (!$gmc->runTasks())
{
    echo "Error " . $gmc->error() . "\n";
    exit;
}

echo "Done\n";

function reverse_status($task)
{
    echo "Status: " . $task->unique() . ", " . $task->jobHandle() . " - " . $task->taskNumerator() .
         "/" . $task->taskDenominator() . "\n";
}

function reverse_complete($task)
{
    echo "Done: " . $task->unique() . ", " . $task->data() . "\n";
}

?>

和工人:

<?php
$gmworker= new GearmanWorker();
$gmworker->addServer('127.0.0.1');
$gmworker->addOptions(GEARMAN_WORKER_GRAB_UNIQ);
$gmworker->addFunction("reverse", "reverse_fn");

print "Waiting for tasks...\n";
while($gmworker->work())
{

  if ($gmworker->returnCode() != GEARMAN_SUCCESS)
  {
    echo "return code: " . $gmworker->returnCode() . "\n";
    break;
  }
}

function reverse_fn($job)
{

  echo "uniq: " . $job->unique() . "\n";
  echo "I got job: " . $job->handle() . "\n";

  $workload = $job->workload();
  $workload_size = $job->workloadSize();

  echo "Workload: $workload ($workload_size)\n";

  for ($x= 0; $x < $workload_size; $x++)
  {
    echo "Sending status: " . ($x + 1) . "/$workload_size is done\n";
    $job->sendStatus($x+1, $workload_size);
    $job->sendData(substr($workload, $x, 1));
    sleep(1);
  }

  $result= strrev($workload);
  echo "The result: $result\n";

  return $result;
}

?>

我通过“gearmand -d”运行 gearmand。 我通过“php worker.php”启动worker。

我从浏览器打开客户端脚本,任务转到服务器,一切正常。 但是当我从 2+ 个浏览器选项卡打开相同的脚本时,gearmand 会收到 2+ 个具有相同唯一 ID 的类似任务。

当我添加后台任务或使用 doBackground 方法或在 CLI 模式下时,不会发生这种情况。 两种以上不同的浏览器也不会发生这种情况。

我尝试了不同的客户端和服务器版本。同样的事情也会发生。

我完全被困住了。 感谢您的帮助。

【问题讨论】:

  • 尝试两种不同的浏览器(会话)。
  • 我在上面写道,两种不同的浏览器运行良好,但我需要一种方法来让来自 1 个浏览器的标签以相同的方式运行。

标签: php task-queue gearman worker


【解决方案1】:

$gmc->addTask("reverse", "!dlroW olleH", null, "2");最后一个选项是您的唯一密钥。所以当然总是一样的。

【讨论】:

  • 是的。但据我了解,如果第一个具有唯一键“2”(例如)的任务被排队,那么第二个具有相同唯一键的任务不应该被添加到队列中,因为另一个任务(第一个) 具有相同的唯一键已在队列中。
  • 有机会查看我用于 gearman 的代码:我不提供唯一的,而是让 gearman 处理它,它工作得很好。请注意,Gearman 只是一个简单的 Workerserver,而不是完全成熟的 MessagingQueue。
  • 即使来自同一浏览器的不同选项卡,gearman 也只将一项作业放入队列?可以在这里放一段代码,写下服务端和客户端版本吗?
  • 不,当然它会启动两次工作。作业服务器不是消息队列。您应该考虑使用真正的消息队列或在您的作业上实施一些锁定。
【解决方案2】:

旧的,但我想我想通了。浏览器不允许一次发送 2 个以上相同的查询。第二个等待第一个先完成。

【讨论】:

    猜你喜欢
    • 2013-02-04
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多