예제 #1
0
 public function handleMessage(ChangeVO $change, Message $message, Channel $channel)
 {
     if ($message->routingKey === RoutingKeys::CHANGE_MANUAL_DONE) {
         $this->log->info("BREAKING CYCLE: " . ChangeVOMeta::toJson($change) . ".");
         $channel->ack($message);
         return;
     } else {
         $this->log->debug("Got message '" . $change->getMessage() . "' created at " . $change->getDatetime()->format("Y-m-d H:i:s") . " via application " . $change->getApplication() . " on host " . $change->getHostname() . " Acking...");
         $channel->ack($message);
         $this->changeDoneProducer->publish($change, RoutingKeys::CHANGE_MANUAL_DONE);
     }
 }
예제 #2
0
 /**
  * create/return transactional channel, where messages need to be commited
  *
  * @throws BunnyException
  * @return Channel|\React\Promise\PromiseInterface
  */
 public function getTransactionalChannel()
 {
     if (!$this->transactionalChannel) {
         $this->transactionalChannel = $this->createChannel();
         // create transactional channel from normal one
         try {
             $this->transactionalChannel->txSelect();
         } catch (\Exception $e) {
             throw new BunnyException("Cannot create transaction channel.");
         }
     }
     return $this->transactionalChannel;
 }
 public function handleMessage(Change $change, Message $message, Channel $channel)
 {
     if (!$change->getProduct()) {
         throw new \InvalidArgumentException("Badly routed message '{$message->content}' with routing key '{$message->routingKey}'.");
     }
     $product = $change->getProduct();
     /** @var Eshop $eshop */
     $eshop = $this->eshopRepository->getOneById($product->getEshopId());
     $product->setEshop($eshop);
     $categoryIds = $product->getCategoryIds();
     if (!empty($categoryIds)) {
         $product->setCategories($this->categoryRepository->find(["_id" => ['$in' => $product->getCategoryIds()]]));
     }
     if (!$this->elasticsearch->indices()->existsAlias(["name" => $this->catalogIndexAliasName])) {
         $this->initIndex();
     }
     $response = $this->elasticsearch->index(["index" => $this->catalogIndexAliasName, "type" => ProductMeta::SHORT_NAME, "id" => (string) $product->getId(), "version" => $product->getV(), "version_type" => "external_gte", "body" => ProductMeta::toObject($product, "json:")]);
     $this->log->info("Indexed Product#{$product->getId()} (v={$product->getV()}, created=" . json_encode($response["created"]) . ").");
     $channel->ack($message);
 }
 public function tick()
 {
     $tickStart = microtime(true);
     if (curl_multi_exec($this->mh, $active) === CURLM_OK && $active > 0) {
         while (curl_multi_select($this->mh) > 0) {
             if (microtime(true) - $tickStart >= 4.0) {
                 break;
             }
             do {
                 $mrc = curl_multi_exec($this->mh, $active);
             } while ($mrc === CURLM_CALL_MULTI_PERFORM);
         }
     }
     $this->log->info("{$active} active downloads.");
     do {
         $info = curl_multi_info_read($this->mh, $waiting);
         if ($info !== false && $info["msg"] === CURLMSG_DONE) {
             $ch = $info["handle"];
             curl_multi_remove_handle($this->mh, $ch);
             $feedId = $this->feedIdByCh[(string) $ch];
             $import = $this->importsByFeedId[$feedId];
             $slug = $import->getEshop()->getSlug();
             $result = $info["result"];
             $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
             if ($result === CURLE_OK && $statusCode === 200) {
                 $this->importProducer->publish($import);
             } else {
                 unlink($import->getTmpFileName());
                 if ($statusCode !== 200) {
                     $this->log->error("Downloading feed {$feedId} ({$slug}) returned status code: {$statusCode}.");
                 } else {
                     $this->log->error("Downloading feed {$feedId} ({$slug}) failed with error {$result}: " . curl_strerror($result) . ".");
                 }
             }
             foreach ($this->messagesByFeedId[$feedId] as $message) {
                 $this->channel->ack($message);
             }
             unset($this->feedIdByCh[(string) $ch]);
             unset($this->chsByFeedId[$feedId]);
             unset($this->importsByFeedId[$feedId]);
             unset($this->messagesByFeedId[$feedId]);
         }
     } while ($waiting > 0);
 }
예제 #5
0
 /**
  * Closes and removes channel.
  *
  * @param Channel $channel
  * @param int $replyCode
  * @param string $replyText
  * @return Protocol\MethodChannelCloseOkFrame|Promise\PromiseInterface
  */
 public function closeChannel(Channel $channel, $replyCode = 0, $replyText = "")
 {
     if ($channel->getClient() !== $this) {
         throw new ClientException("Tried closing channel from another client.");
     }
     // break reference cycle
     unset($this->channels[$channel->getChannelId()]);
     return $this->channelClose($channel->getChannelId(), $replyCode, $replyText, 0, 0);
 }
예제 #6
0
 public function handleMessage(Message $message, BunnyMessage $bunnyMessage, Channel $channel)
 {
     $this->message = $message;
     $channel->ack($bunnyMessage);
 }
 public function handleMessage(Import $import, Message $message, Channel $channel)
 {
     if (!$import->getTmpFileName()) {
         $this->log->error("Import w/o tmp file name: {$message->content}.");
         $channel->ack($message);
         return;
     }
     if (!file_exists($import->getTmpFileName())) {
         $this->log->error("Tmp file name '{$import->getTmpFileName()}' does not exist.");
         $channel->ack($message);
         return;
     }
     $this->log->info("Got " . $message->content);
     // TODO: error handling
     $handle = fopen($import->getTmpFileName(), "r+");
     while (fread($handle, 3) === "") {
         fseek($handle, -3, SEEK_CUR);
         fwrite($handle, "   ");
         $this->log->info("Removed BOM in file '{$import->getTmpFileName()}'.");
     }
     fseek($handle, 0, SEEK_SET);
     $data = fread($handle, 1024);
     if (($sp = strpos($data, "<?xml")) !== false) {
         if (($ep = strpos($data, "?>")) !== false) {
             $newData = substr($data, $sp, $ep - $sp + 2) . str_repeat(" ", $sp) . substr($data, $ep + 2);
             fseek($handle, 0, SEEK_SET);
             fwrite($handle, $newData);
         }
     }
     fclose($handle);
     $eshopId = $import->getEshop()->getId();
     $reader = new \XMLReader();
     $reader->open($import->getTmpFileName());
     while ($reader->read()) {
         if (strtoupper($reader->name) !== "SHOPITEM") {
             continue;
         }
         $item = @$reader->expand();
         if ($item === false) {
             $this->log->error("XMLReader error: " . json_encode(libxml_get_last_error()));
             break;
         }
         $reader->next();
         $product = new Product();
         $product->setEshopId($eshopId);
         foreach ($item->childNodes as $child) {
             /** @var \DOMNode $child */
             if ($child->nodeType !== XML_ELEMENT_NODE) {
                 continue;
             }
             $textContent = trim($child->textContent);
             if (empty($textContent)) {
                 $textContent = null;
             }
             switch ($name = strtoupper($child->nodeName)) {
                 case "ITEM_GROUP_ID":
                     $product->setItemGroupId($textContent);
                     break;
                 case "ITEM_ID":
                     $product->setItemId($textContent);
                     break;
                 case "PRODUCTNAME":
                     $product->setName($textContent);
                     break;
                 case "PRODUCT":
                     $product->setLongName($textContent);
                     break;
                 case "DESCRIPTION":
                     $product->setDescription($textContent);
                     break;
                 case "URL":
                     // TODO: normalize URL
                     $product->setUrl($textContent);
                     break;
                 case "PRICE_VAT":
                     $product->setPrice(floatval(preg_replace("/[^0-9.]+/", "", str_replace(",", ".", $textContent))));
                     break;
                 case "DELIVERY_DATE":
                     $product->setDeliveryDate(intval(preg_replace("/[^0-9]+/", "", $textContent)));
                     break;
                 case "IMGURL":
                 case "IMGURL_ALTERNATIVE":
                     // TODO: normalize URL
                     $image = new Image();
                     $image->setUrl($textContent);
                     $product->addImage($image);
                     break;
                 case "EAN":
                     $product->setEan($textContent);
                     break;
                 case "ISBN":
                     $product->setIsbn($textContent);
                     break;
                 case "PRODUCTNO":
                     $product->setProductno($textContent);
                     break;
                 case "MANUFACTURER":
                     $product->setManufacturer($textContent);
                     break;
                 case "BRAND":
                     $product->setBrand($textContent);
                     break;
                 case "CATEGORYTEXT":
                     if (!empty($textContent)) {
                         $product->addCategoryText($textContent);
                     }
                     break;
                 case "ITEM_TYPE":
                     try {
                         $product->setItemType(ProductItemTypeEnum::fromXML($textContent));
                     } catch (\InvalidArgumentException $e) {
                         $this->log->warning("Got exception while assigning ITEM_TYPE: " . $e->getMessage());
                     }
                     break;
                 case "EXTRA_MESSAGE":
                     try {
                         $product->addExtraMessage(ProductExtraMessageEnum::fromXML($textContent));
                     } catch (\InvalidArgumentException $e) {
                         $this->log->warning("Got exception while assigning EXTRA_MESSAGE: " . $e->getMessage());
                     }
                     break;
             }
         }
         if ($product->getUrl() === null) {
             $this->log->warning("Skipping product without URL: " . ProductMeta::toJson($product));
             continue;
         }
         if ($product->getName() === null) {
             if ($product->getLongName() === null) {
                 $this->log->warning("Skipping product without PRODUCT/PRODUCTNAME: " . ProductMeta::toJson($product));
                 continue;
             } else {
                 $product->setName($product->getLongName());
             }
         }
         if ($product->getItemId() === null) {
             $product->setItemId($product->getUrl());
         }
         if ($product->getItemGroupId() === null) {
             $product->setItemGroupId($product->getItemId());
         }
         for (;;) {
             $existing = $this->productRepository->findOneFromEshop($product);
             if (!$existing) {
                 $this->fillCategoryIds($product);
                 $ret = $this->productRepository->insert($product);
                 if (isset($ret["ok"]) && $ret["ok"]) {
                     $this->changeProducer->publish(Change::create()->setProduct($product), RoutingKeys::CHANGE_PRODUCT_CREATE);
                     break;
                 }
             } else {
                 $this->mergeProducts($product, $existing);
                 $this->fillCategoryIds($product);
                 $ret = $this->productRepository->update(["_id" => $existing->getId(), "v" => $existing->getV()], ProductMeta::toArray($product));
                 if (isset($ret["ok"]) && $ret["ok"] && isset($ret["updatedExisting"]) && $ret["updatedExisting"]) {
                     $this->changeProducer->publish(Change::create()->setProduct($product), RoutingKeys::CHANGE_PRODUCT_UPDATE);
                     break;
                 }
             }
         }
     }
     // TODO: delete products not present in feed
     $reader->close();
     libxml_clear_errors();
     unlink($import->getTmpFileName());
     $channel->ack($message);
 }