2

我正在尝试使用Windows Azure SDK for PHP提供的 REST 代理与 Azure 队列交互。虽然这里有很多代码示例,但我想检查一个队列是否存在,以便在必要时创建它,然后再向它添加消息。

try {
  // setup connection string for accessing queue storage
  $connectionString = 'DefaultEndpointsProtocol=' . PROTOCOL . ';AccountName=' . ACCOUNT_NAME . ';AccountKey=' . ACCOUNT_KEY;

  // create queue REST proxy
  $queueRestProxy = ServicesBuilder::getInstance()->createQueueService($connectionString);

  // create message
  $queueRestProxy->createMessage(QUEUE_NAME, 'Hello World!');

} catch(ServiceException $e){
  // Handle exception based on error codes and messages.
  // Error codes and messages are here: 
  // http://msdn.microsoft.com/en-us/library/windowsazure/dd179446.aspx
  $code = $e->getCode();
  $error_message = $e->getMessage();
  echo $code.": ".$error_message."<br />";
}

创建队列就这么简单...

$queueRestProxy->createQueue(QUEUE_NAME);

我应该在创建消息之前简单地包含队列创建代码,还是有更有效的方法来确定队列在与它交互之前是否存在?

4

2 回答 2

1

通常在其他 Windows Azure SDK 中我见过类似的方法createQueueIfNotExists,我很惊讶 PHP SDK 中缺少这种方法。基本上这个函数的工作方式是它试图创建一个队列。如果存储中存在同名队列,存储服务会抛出Conflict (409)错误。

由于该函数不存在,您可以执行相同的操作,即尝试在其自己的 try/catch 块中创建队列并检查错误代码。如果错误代码是 409,则继续,否则重新抛出异常。类似于下面的代码:

try {
  // setup connection string for accessing queue storage
  $connectionString = 'DefaultEndpointsProtocol=' . PROTOCOL . ';AccountName=' . ACCOUNT_NAME . ';AccountKey=' . ACCOUNT_KEY;
    // create queue REST proxy
        $queueRestProxy = ServicesBuilder::getInstance()->createQueueService($connectionString);
  try {
    // now try to create the queue.
$queueRestProxy->createQueue(QUEUE_NAME);
  } catch(ServiceException $e){
    $code = $e->getCode();
    //Now check if the $code is 409 - Conflict. If the error code is indeed 409, you continue otherwise throw the error
  }
  // create message
  $queueRestProxy->createMessage(QUEUE_NAME, 'Hello World!');

} catch(ServiceException $e){
  // Handle exception based on error codes and messages.
  // Error codes and messages are here: 
  // http://msdn.microsoft.com/en-us/library/windowsazure/dd179446.aspx
  $code = $e->getCode();
  $error_message = $e->getMessage();
  echo $code.": ".$error_message."<br />";
}

PS我没有尝试执行代码,所以它可能会抛出错误。这只是给你一个想法。

于 2014-02-04T03:13:44.160 回答
1

为了完整起见,我在下面发布了一个答案,以便人们一眼就能看到答案。

我应该在创建消息之前简单地包含队列创建代码,还是有更有效的方法来确定队列在与它交互之前是否存在?

有两种方法可以解决这个问题......

  1. createQueue在创建消息之前包含该语句,但按照Guarav Mantri 的回答的try-catch指示将该语句包装在一个块中,即忽略 409 错误,但针对任何其他类型的错误抛出异常。

    createQueue有关信息,当您在创建消息之前包含声明时...

    • 如果同名队列已经存在,并且与现有队列关联的元数据与传递给语句的元数据相同, createQueue则不会创建队列,队列 REST 代理将在内部接收204(无内容)状态代码,但此响应代码不提供给程序员。因此,从本质上讲,该createQueue语句不会导致在这种情况下引发错误/异常。

    • 如果同名队列已经存在并且与现有队列关联的元数据与传递给语句的元数据不同,则不会createQueue创建队列并且队列 REST 代理将收到409(冲突)状态代码和将引发允许程序员访问此响应代码和相关QueueAlreadyExists消息的异常。

    来源:创建队列 (REST API) - 见备注部分

  2. 创建一个queueExists函数并调用它来决定是否需要创建队列。这是实现此类功能的一种方法...

    public function queueExists($queueRestProxy, $queueName) {
      $result = FALSE;
      $listQueuesResult = $queueRestProxy->listQueues();
      $queues = $listQueuesResult->getQueues();
      foreach($queues as $queue) {
        if ($queue->getName() === $queueName) {
          $result = TRUE;
          break;
        }
      }
      return $result;        
    }
    

希望这对某人有帮助!

于 2014-02-07T19:31:01.993 回答