public function run($limit)
 {
     $full_reindex = $limit === -1;
     $limit = $full_reindex ? 1 : $limit;
     $element_count = 0;
     $jobs = [];
     $offset = 0;
     $max_size = $this->configHelper->getNumberOfElementByPage() * $limit;
     while ($element_count < $max_size) {
         $data = $this->db->query($this->db->select()->from($this->table, '*')->where('pid IS NULL')->order(['job_id'])->limit($limit, $limit * $offset));
         $data = $data->fetchAll();
         $offset++;
         if (count($data) <= 0) {
             break;
         }
         foreach ($data as $job) {
             $job_size = (int) $job['data_size'];
             if ($element_count + $job_size <= $max_size || empty($jobs)) {
                 $jobs[] = $job;
                 $element_count += $job_size;
             } else {
                 break 2;
             }
         }
     }
     if (count($jobs) <= 0) {
         return;
     }
     $first_id = $jobs[0]['job_id'];
     $last_id = $jobs[count($jobs) - 1]['job_id'];
     $pid = getmypid();
     // Reserve all new jobs since last run
     $this->db->query("UPDATE {$this->db->quoteIdentifier($this->table, true)} SET pid = " . $pid . ' WHERE job_id >= ' . $first_id . " AND job_id <= {$last_id}");
     foreach ($jobs as &$job) {
         $job['data'] = json_decode($job['data'], true);
     }
     $jobs = $this->sortAndMergeJob($jobs);
     // Run all reserved jobs
     foreach ($jobs as $job) {
         try {
             $model = $this->objectManager->get($job['class']);
             $method = $job['method'];
             $data = $job['data'];
             call_user_func_array([$model, $method], $data);
         } catch (\Exception $e) {
             // Increment retries and log error information
             $this->logger->log("Queue processing {$job['pid']} [KO]: Mage::getSingleton({$job['class']})->{$job['method']}(" . json_encode($job['data']) . ')');
             $this->logger->log(date('c') . ' ERROR: ' . get_class($e) . ": '{$e->getMessage()}' in {$e->getFile()}:{$e->getLine()}\n" . "Stack trace:\n" . $e->getTraceAsString());
         }
     }
     // Delete only when finished to be able to debug the queue if needed
     $where = $this->db->quoteInto('pid = ?', $pid);
     $this->db->delete($this->table, $where);
     if ($full_reindex) {
         $this->run(-1);
     }
 }
 /**
  * {@inheritdoc}
  */
 public function query(RequestInterface $request)
 {
     $query = $this->catalogSearchHelper->getEscapedQueryText();
     $storeId = $this->storeManager->getStore()->getId();
     $temporaryStorage = $this->temporaryStorageFactory->create();
     $documents = [];
     $table = null;
     if (!$this->config->getApplicationID($storeId) || !$this->config->getAPIKey($storeId) || $this->config->isEnabledFrontEnd($storeId) === false || $this->config->makeSeoRequest($storeId) === '0' || $this->request->getControllerName() === 'category' && $this->config->replaceCategories($storeId) == false) {
         $query = $this->mapper->buildQuery($request);
         $table = $temporaryStorage->storeDocumentsFromSelect($query);
         $documents = $this->getDocuments($table);
     } else {
         $algolia_query = $query !== '__empty__' ? $query : '';
         //If instant search is on, do not make a search query unless SEO request is set to 'Yes'
         if (!$this->config->isInstantEnabled($storeId) || $this->config->makeSeoRequest($storeId)) {
             $documents = $this->algoliaHelper->getSearchResult($algolia_query, $storeId);
         }
         $getDocumentMethod = 'getDocument21';
         $storeDocumentsMethod = 'storeApiDocuments';
         if (version_compare($this->config->getMagentoVersion(), '2.1.0', '<') === true) {
             $getDocumentMethod = 'getDocument20';
             $storeDocumentsMethod = 'storeDocuments';
         }
         $apiDocuments = array_map(function ($document) use($getDocumentMethod) {
             return $this->{$getDocumentMethod}($document);
         }, $documents);
         $table = $temporaryStorage->{$storeDocumentsMethod}($apiDocuments);
     }
     $aggregations = $this->aggregationBuilder->build($request, $table);
     $response = ['documents' => $documents, 'aggregations' => $aggregations];
     return $this->responseFactory->create($response);
 }