Fix BatchIterator skipping rows when subscribers' processed status is modified [MAILPOET-987]
This commit is contained in:
@@ -9,7 +9,8 @@ if(!defined('ABSPATH')) exit;
|
|||||||
class BatchIterator implements \Iterator, \Countable {
|
class BatchIterator implements \Iterator, \Countable {
|
||||||
private $task_id;
|
private $task_id;
|
||||||
private $batch_size;
|
private $batch_size;
|
||||||
private $offset = 0;
|
private $last_processed_id = 0;
|
||||||
|
private $batch_last_id;
|
||||||
|
|
||||||
function __construct($task_id, $batch_size) {
|
function __construct($task_id, $batch_size) {
|
||||||
if($task_id <= 0) {
|
if($task_id <= 0) {
|
||||||
@@ -22,29 +23,29 @@ class BatchIterator implements \Iterator, \Countable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function rewind() {
|
function rewind() {
|
||||||
$this->offset = 0;
|
$this->last_processed_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function current() {
|
function current() {
|
||||||
$subscribers = $this->getSubscribers()
|
$subscribers = $this->getSubscribers()
|
||||||
->orderByAsc('subscriber_id')
|
->orderByAsc('subscriber_id')
|
||||||
->limit($this->batch_size)
|
->limit($this->batch_size)
|
||||||
->offset($this->offset)
|
|
||||||
->findArray();
|
->findArray();
|
||||||
$subscribers = Helpers::arrayColumn($subscribers, 'subscriber_id');
|
$subscribers = Helpers::arrayColumn($subscribers, 'subscriber_id');
|
||||||
|
$this->batch_last_id = end($subscribers);
|
||||||
return $subscribers;
|
return $subscribers;
|
||||||
}
|
}
|
||||||
|
|
||||||
function key() {
|
function key() {
|
||||||
return $this->offset;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function next() {
|
function next() {
|
||||||
$this->offset += $this->batch_size;
|
$this->last_processed_id = $this->batch_last_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
function valid() {
|
function valid() {
|
||||||
return $this->offset < $this->count();
|
return $this->count() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function count() {
|
function count() {
|
||||||
@@ -54,6 +55,7 @@ class BatchIterator implements \Iterator, \Countable {
|
|||||||
private function getSubscribers() {
|
private function getSubscribers() {
|
||||||
return ScheduledTaskSubscriber::select('subscriber_id')
|
return ScheduledTaskSubscriber::select('subscriber_id')
|
||||||
->where('task_id', $this->task_id)
|
->where('task_id', $this->task_id)
|
||||||
|
->whereGt('subscriber_id', $this->last_processed_id)
|
||||||
->where('processed', ScheduledTaskSubscriber::STATUS_UNPROCESSED);
|
->where('processed', ScheduledTaskSubscriber::STATUS_UNPROCESSED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,9 +6,9 @@ use MailPoet\Tasks\Subscribers\BatchIterator;
|
|||||||
|
|
||||||
class BatchIteratorTest extends \MailPoetTest {
|
class BatchIteratorTest extends \MailPoetTest {
|
||||||
function _before() {
|
function _before() {
|
||||||
$this->task_id = 123;
|
$this->task_id = 123; // random ID
|
||||||
$this->batch_size = 2;
|
$this->batch_size = 2;
|
||||||
$this->subscriber_count = 5;
|
$this->subscriber_count = 10;
|
||||||
for($i = 0; $i < $this->subscriber_count; $i++) {
|
for($i = 0; $i < $this->subscriber_count; $i++) {
|
||||||
ScheduledTaskSubscriber::createOrUpdate(array(
|
ScheduledTaskSubscriber::createOrUpdate(array(
|
||||||
'task_id' => $this->task_id,
|
'task_id' => $this->task_id,
|
||||||
@@ -28,7 +28,7 @@ class BatchIteratorTest extends \MailPoetTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function testItConstructs() {
|
function testItConstructs() {
|
||||||
$iterator = new BatchIterator(123, 456);
|
$iterator = new BatchIterator(123, 456); // random IDs
|
||||||
expect_that($iterator instanceof BatchIterator);
|
expect_that($iterator instanceof BatchIterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,6 +37,14 @@ class BatchIteratorTest extends \MailPoetTest {
|
|||||||
$i = 0;
|
$i = 0;
|
||||||
foreach($this->iterator as $batch) {
|
foreach($this->iterator as $batch) {
|
||||||
$i++;
|
$i++;
|
||||||
|
|
||||||
|
// process subscribers
|
||||||
|
ScheduledTaskSubscriber::where('task_id', $this->task_id)
|
||||||
|
->whereIn('subscriber_id', $batch)
|
||||||
|
->findResultSet()
|
||||||
|
->set('processed', ScheduledTaskSubscriber::STATUS_PROCESSED)
|
||||||
|
->save();
|
||||||
|
|
||||||
if($i < $iterations) {
|
if($i < $iterations) {
|
||||||
expect(count($batch))->equals($this->batch_size);
|
expect(count($batch))->equals($this->batch_size);
|
||||||
} else {
|
} else {
|
||||||
|
Reference in New Issue
Block a user