Skip to content
Snippets Groups Projects
Commit aeb379a8 authored by Alex Barth's avatar Alex Barth
Browse files

#928836: Set progress floating point directly.

parent 0cfb7489
No related branches found
No related tags found
No related merge requests found
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
Feeds 7.x 2.0 XXXXXXXXXXXXXXXXXXX Feeds 7.x 2.0 XXXXXXXXXXXXXXXXXXX
--------------------------------- ---------------------------------
- #928836: Set progress floating point directly. Note: fetchers and parsers
must use $state->progress() for setting the batch progress now IF they support
batching.
- #928728: Track source states by stage, not by plugin. Note: call signature of - #928728: Track source states by stage, not by plugin. Note: call signature of
FeedsSource::state() has changed. FeedsSource::state() has changed.
- #923318: Fix Fatal error: Call to a member function import() on a non-object - #923318: Fix Fatal error: Call to a member function import() on a non-object
......
...@@ -15,8 +15,8 @@ define('FEEDS_EXPIRE_NEVER', -1); ...@@ -15,8 +15,8 @@ define('FEEDS_EXPIRE_NEVER', -1);
// An object that is not persistent. Compare EXPORT_IN_DATABASE, EXPORT_IN_CODE. // An object that is not persistent. Compare EXPORT_IN_DATABASE, EXPORT_IN_CODE.
define('FEEDS_EXPORT_NONE', 0x0); define('FEEDS_EXPORT_NONE', 0x0);
// Status of batched operations. // Status of batched operations.
define('FEEDS_BATCH_COMPLETE', 1); define('FEEDS_BATCH_COMPLETE', 1.0);
define('FEEDS_BATCH_ACTIVE', 0); define('FEEDS_BATCH_ACTIVE', 0.0);
/** /**
* @defgroup hooks Hook and callback implementations * @defgroup hooks Hook and callback implementations
......
...@@ -64,9 +64,9 @@ interface FeedsSourceInterface { ...@@ -64,9 +64,9 @@ interface FeedsSourceInterface {
*/ */
class FeedsState { class FeedsState {
/** /**
* Natural numbers denoting the total and the progress of that total made. * Floating point number denoting the progress made. 0.0 meaning no progress
* 1.0 = FEEDS_BATCH_COMPLETE meaning finished.
*/ */
public $total;
public $progress; public $progress;
/** /**
...@@ -77,6 +77,7 @@ class FeedsState { ...@@ -77,6 +77,7 @@ class FeedsState {
/** /**
* Natural numbers denoting more details about the progress being made. * Natural numbers denoting more details about the progress being made.
*/ */
public $total;
public $created; public $created;
public $updated; public $updated;
public $deleted; public $deleted;
...@@ -87,8 +88,8 @@ class FeedsState { ...@@ -87,8 +88,8 @@ class FeedsState {
* Constructor, initialize variables. * Constructor, initialize variables.
*/ */
public function __construct() { public function __construct() {
$this->progress = FEEDS_BATCH_COMPLETE;
$this->total = $this->total =
$this->progress =
$this->created = $this->created =
$this->updated = $this->updated =
$this->deleted = $this->deleted =
...@@ -97,29 +98,35 @@ class FeedsState { ...@@ -97,29 +98,35 @@ class FeedsState {
} }
/** /**
* Report normalized progress. * Safely report progress.
* *
* @return * When $total == $progress, the state of the task tracked by this state is
* A float between 0 and 1, 1 = FEEDS_BATCH_COMPLETE. * regarded to be complete.
*
* Handles the following cases gracefully:
*
* - $total is 0
* - $progress is larger than $total
* - $progress approximates $total so that $finished rounds to 1.0
*
* @param $total
* A natural number that is the total to be worked off.
* @param $progress
* A natural number that is the progress made on $total.
*/ */
public function progress() { public function progress($total, $progress) {
// If no total and no progress is reported, we are done. if ($progress > $total) {
if (empty($this->total) && empty($this->progress)) { $this->progress = FEEDS_BATCH_COMPLETE;
return FEEDS_BATCH_COMPLETE;
} }
$progress = $this->progress / $this->total; elseif ($total) {
if ($progress == FEEDS_BATCH_COMPLETE && $this->total != $this->progress) { $this->progress = $progress / $total;
return 0.999; if ($this->progress == FEEDS_BATCH_COMPLETE && $total != $progress) {
$this->progress = 0.99;
}
}
else {
$this->progress = FEEDS_BATCH_COMPLETE;
} }
return $progress;
}
/**
* Sets this state to finished.
*/
public function finished() {
$this->total =
$this->progress = FEEDS_BATCH_COMPLETE;
} }
} }
...@@ -280,7 +287,7 @@ class FeedsSource extends FeedsConfigurable { ...@@ -280,7 +287,7 @@ class FeedsSource extends FeedsConfigurable {
* Report progress as float between 0 and 1. 1 = FEEDS_BATCH_COMPLETE. * Report progress as float between 0 and 1. 1 = FEEDS_BATCH_COMPLETE.
*/ */
public function progressParsing() { public function progressParsing() {
return $this->state(FEEDS_PARSE)->progress(); return $this->state(FEEDS_PARSE)->progress;
} }
/** /**
...@@ -289,20 +296,25 @@ class FeedsSource extends FeedsConfigurable { ...@@ -289,20 +296,25 @@ class FeedsSource extends FeedsConfigurable {
public function progressImporting() { public function progressImporting() {
$fetcher = $this->state(FEEDS_FETCH); $fetcher = $this->state(FEEDS_FETCH);
$parser = $this->state(FEEDS_PARSE); $parser = $this->state(FEEDS_PARSE);
if ($fetcher->progress() == FEEDS_BATCH_COMPLETE && $parser->progress() == FEEDS_BATCH_COMPLETE) { if ($fetcher->progress == FEEDS_BATCH_COMPLETE && $parser->progress == FEEDS_BATCH_COMPLETE) {
return FEEDS_BATCH_COMPLETE; return FEEDS_BATCH_COMPLETE;
} }
// Fetching envelops parsing. // Fetching envelops parsing.
$parser_progress = $parser->progress() / $fetcher->total; // @todo: this assumes all fetchers neatly use total. May not be the case.
$fetcher_fraction = 1.0 / $fetcher->total; $fetcher_fraction = $fetcher->total ? 1.0 / $fetcher->total : 1.0;
return $fetcher->progress() - $fetcher_fraction + $parser_progress; $parser_progress = $parser->progress * $fetcher_fraction;
$result = $fetcher->progress - $fetcher_fraction + $parser_progress;
if ($result == FEEDS_BATCH_COMPLETE) {
return 0.99;
}
return $result;
} }
/** /**
* Report progress on clearing. * Report progress on clearing.
*/ */
public function progressClearing() { public function progressClearing() {
return $this->state(FEEDS_PROCESS_CLEAR)->progress(); return $this->state(FEEDS_PROCESS_CLEAR)->progress;
} }
/** /**
......
...@@ -33,8 +33,9 @@ class FeedsCSVParser extends FeedsParser { ...@@ -33,8 +33,9 @@ class FeedsCSVParser extends FeedsParser {
// Report progress. // Report progress.
$state->total = filesize($fetcher_result->getFilePath()); $state->total = filesize($fetcher_result->getFilePath());
$state->pointer = $state->pointer = $parser->lastLinePos();
$state->progress = $parser->lastLinePos() ? $parser->lastLinePos() : $state->total; $progress = $parser->lastLinePos() ? $parser->lastLinePos() : $state->total;
$state->progress($state->total, $progress);
// Create a result object and return it. // Create a result object and return it.
return new FeedsParserResult($rows, $source->feed_nid); return new FeedsParserResult($rows, $source->feed_nid);
......
...@@ -58,13 +58,11 @@ class FeedsFileFetcher extends FeedsFetcher { ...@@ -58,13 +58,11 @@ class FeedsFileFetcher extends FeedsFetcher {
$files = array(); $files = array();
if (!isset($state->files)) { if (!isset($state->files)) {
$state->files = $this->listFiles($source_config['source']); $state->files = $this->listFiles($source_config['source']);
$state->progress =
$state->total = count($state->files); $state->total = count($state->files);
} }
if (count($state->files)) { if (count($state->files)) {
$file = array_shift($state->files); $file = array_shift($state->files);
// When progress == total, file fetcher will not be called again. $state->progress($state->total, $state->total - count($state->files));
$state->progress = $state->total - count($state->files);
return new FeedsFileFetcherResult($file); return new FeedsFileFetcherResult($file);
} }
......
...@@ -87,7 +87,7 @@ class FeedsNodeProcessor extends FeedsProcessor { ...@@ -87,7 +87,7 @@ class FeedsNodeProcessor extends FeedsProcessor {
} }
node_delete_multiple($nids); node_delete_multiple($nids);
if (db_query_range("SELECT 1 FROM {node} n JOIN {feeds_node_item} fn ON n.nid = fn.nid WHERE fn.id = :id AND fn.feed_nid = :nid", 0, 1, array(':id' => $source->id, ':nid' => $source->feed_nid))->fetchField()) { if (db_query_range("SELECT 1 FROM {node} n JOIN {feeds_node_item} fn ON n.nid = fn.nid WHERE fn.id = :id AND fn.feed_nid = :nid", 0, 1, array(':id' => $source->id, ':nid' => $source->feed_nid))->fetchField()) {
$state->progress = $state->deleted; $state->progress($state->total, $state->deleted);
return; return;
} }
...@@ -99,7 +99,9 @@ class FeedsNodeProcessor extends FeedsProcessor { ...@@ -99,7 +99,9 @@ class FeedsNodeProcessor extends FeedsProcessor {
else { else {
drupal_set_message(t('There is no content to be deleted.')); drupal_set_message(t('There is no content to be deleted.'));
} }
$state->finished(); // Make sure we are finished, there may be a discrepancy between total and
// deleted if other processes have deleted nodes in the meantime.
$state->progress = FEEDS_BATCH_COMPLETE;
} }
/** /**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment