/** * Executes a callback. * * @param \Drupal\feeds\FeedInterface $feeds_feed * The Feed we are executing a job for. * @param \Symfony\Component\HttpFoundation\Request $request * The request object to grab POST params from. * * @todo Configure a time limit. * @todo Really awesome error handling. */ public function execute(FeedInterface $feeds_feed, Request $request) { $cid = 'feeds_feed:' . $feeds_feed->id(); if ($token = $request->request->get('token') && ($job = $this->state->get($cid))) { if ($job['token'] == $token && ($lock = $this->lockBackend->acquire($cid))) { $method = $job['method']; $this->state->delete($cid); ignore_user_abort(TRUE); set_time_limit(0); while ($feeds_feed->{$method}() != StateInterface::BATCH_COMPLETE) { // Reset static caches in between runs to avoid memory leaks. drupal_reset_static(); } $this->lockBackend->release($cid); } } }
/** * {@inheritdoc} */ protected function doSave($id, EntityInterface $entity) { $is_new = $entity->isNew(); // Save the entity data in the key value store. $this->keyValueStore->set($entity->id(), $entity->toArray()); // If this is a rename, delete the original entity. if ($this->has($id, $entity) && $id !== $entity->id()) { $this->keyValueStore->delete($id); } return $is_new ? SAVED_NEW : SAVED_UPDATED; }
/** * {@inheritdoc} */ public function processFetchTask($project) { global $base_url; // This can be in the middle of a long-running batch, so REQUEST_TIME won't // necessarily be valid. $request_time_difference = time() - REQUEST_TIME; if (empty($this->failed)) { // If we have valid data about release history XML servers that we have // failed to fetch from on previous attempts, load that. $this->failed = $this->tempStore->get('fetch_failures'); } $max_fetch_attempts = $this->updateSettings->get('fetch.max_attempts'); $success = FALSE; $available = array(); $site_key = Crypt::hmacBase64($base_url, $this->privateKey->get()); $fetch_url_base = $this->updateFetcher->getFetchBaseUrl($project); $project_name = $project['name']; if (empty($this->failed[$fetch_url_base]) || $this->failed[$fetch_url_base] < $max_fetch_attempts) { $data = $this->updateFetcher->fetchProjectData($project, $site_key); } if (!empty($data)) { $available = $this->parseXml($data); // @todo: Purge release data we don't need. See // https://www.drupal.org/node/238950. if (!empty($available)) { // Only if we fetched and parsed something sane do we return success. $success = TRUE; } } else { $available['project_status'] = 'not-fetched'; if (empty($this->failed[$fetch_url_base])) { $this->failed[$fetch_url_base] = 1; } else { $this->failed[$fetch_url_base]++; } } $frequency = $this->updateSettings->get('check.interval_days'); $available['last_fetch'] = REQUEST_TIME + $request_time_difference; $this->availableReleasesTempStore->setWithExpire($project_name, $available, $request_time_difference + 60 * 60 * 24 * $frequency); // Stash the $this->failed data back in the DB for the next 5 minutes. $this->tempStore->setWithExpire('fetch_failures', $this->failed, $request_time_difference + 60 * 5); // Whether this worked or not, we did just (try to) check for updates. $this->stateStore->set('update.last_check', REQUEST_TIME + $request_time_difference); // Now that we processed the fetch task for this project, clear out the // record for this task so we're willing to fetch again. $this->fetchTaskStore->delete($project_name); return $success; }
/** * Deletes the entity type definition from the application state. * * @param string $entity_type_id * The entity type definition identifier. */ protected function deleteLastInstalledDefinition($entity_type_id) { $this->installedDefinitions->delete($entity_type_id . '.entity_type'); // Clean up field storage definitions as well. Even if the entity type // isn't currently fieldable, there might be legacy definitions or an // empty array stored from when it was. $this->installedDefinitions->delete($entity_type_id . '.field_storage_definitions'); }