Improvements to Status Handling
Added link to jobs page to fix any issues caused by non-synchronised time between webserver/worker machine leaving jobs permanently in the running state. Prevented the insertion of new status records unless the state is actually being changed. Made the HandBrake worker process write the status complete message instead of the run-jobs dispatched, in case it crashes.
This commit is contained in:
@@ -22,6 +22,10 @@ class RippingCluster_Job {
|
||||
private $audio_names;
|
||||
private $subtitle_tracks;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array(RippingCluster_JobStatus)
|
||||
*/
|
||||
private $statuses = null;
|
||||
|
||||
private static $cache = array();
|
||||
@@ -269,8 +273,13 @@ class RippingCluster_Job {
|
||||
|
||||
public function updateStatus($new_status, $rip_progress = null) {
|
||||
$this->loadStatuses();
|
||||
$new_status = RippingCluster_JobStatus::updateStatusForJob($this, $new_status, $rip_progress);
|
||||
$this->statuses[] = $new_status;
|
||||
|
||||
// Only update the status if the state is changing
|
||||
if ($this->currentStatus()->status() != $new_status) {
|
||||
$new_status = RippingCluster_JobStatus::updateStatusForJob($this, $new_status, $rip_progress);
|
||||
$this->statuses[] = $new_status;
|
||||
}
|
||||
|
||||
return $new_status;
|
||||
}
|
||||
|
||||
@@ -289,7 +298,30 @@ class RippingCluster_Job {
|
||||
|
||||
return $remaining_time;
|
||||
}
|
||||
|
||||
|
||||
public function fixBrokenTimestamps() {
|
||||
$this->loadStatuses();
|
||||
|
||||
// See if we have both a RUNNING and a COMPLETE status set
|
||||
$statuses = array();
|
||||
foreach ($this->statuses as $status) {
|
||||
switch ($status->status()) {
|
||||
case RippingCluster_JobStatus::RUNNING:
|
||||
case RippingCluster_JobStatus::COMPLETE:
|
||||
$statuses[$status->status()] = $status;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($statuses[RippingCluster_JobStatus::RUNNING]) && isset($statuses[RippingCluster_JobStatus::COMPLETE])) {
|
||||
// Ensure the timestamp on the complete is >= that of the running status
|
||||
if ($statuses[RippingCluster_JobStatus::COMPLETE]->mtime() < $statuses[RippingCluster_JobStatus::RUNNING]->mtime()) {
|
||||
$statuses[RippingCluster_JobStatus::COMPLETE]->mtime($statuses[RippingCluster_JobStatus::RUNNING]->mtime() + 1);
|
||||
$statuses[RippingCluster_JobStatus::COMPLETE]->save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ class RippingCluster_JobStatus {
|
||||
}
|
||||
|
||||
return $statuses;
|
||||
}
|
||||
}
|
||||
|
||||
protected function create() {
|
||||
$database = RippingCluster_Main::instance()->database();
|
||||
@@ -104,11 +104,22 @@ class RippingCluster_JobStatus {
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function hasProgressInfo() {
|
||||
return ($this->status == self::RUNNING);
|
||||
}
|
||||
|
||||
public static function fixBrokenTimestamps() {
|
||||
$statuses = array();
|
||||
|
||||
$database = RippingCluster_Main::instance()->database();
|
||||
foreach ($database->selectList('SELECT * FROM job_status WHERE status=4 AND job_id IN (SELECT job_id FROM job_status WHERE status=3)') as $row) {
|
||||
$status = RippingCluster_JobStatus::fromDatabaseRow($row);
|
||||
$status->mtime = time();
|
||||
$status->save();
|
||||
}
|
||||
}
|
||||
|
||||
public function id() {
|
||||
return $this->id;
|
||||
}
|
||||
@@ -129,7 +140,11 @@ class RippingCluster_JobStatus {
|
||||
return $this->ctime;
|
||||
}
|
||||
|
||||
public function mtime() {
|
||||
public function mtime($new_mtime = null) {
|
||||
if ($new_mtime !== null) {
|
||||
$this->mtime = $new_mtime;
|
||||
}
|
||||
|
||||
return $this->mtime;
|
||||
}
|
||||
|
||||
|
||||
@@ -82,6 +82,8 @@ class RippingCluster_Worker_Plugin_HandBrake implements RippingCluster_Worker_IP
|
||||
list($return_val, $stdout, $stderr) = RippingCluster_ForegroundTask::execute($handbrake_cmd, null, null, null, array($this, 'callbackOutput'), array($this, 'callbackOutput'), $this);
|
||||
if ($return_val) {
|
||||
$this->gearman_job->sendFail($return_val);
|
||||
} else {
|
||||
$this->job->updateStatus(RippingCluster_JobStatus::COMPLETE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
webui/images/clock.png
Normal file
BIN
webui/images/clock.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
@@ -52,6 +52,12 @@ if ($req->get('submit')) {
|
||||
$job->delete();
|
||||
}
|
||||
} break;
|
||||
|
||||
case 'fix-broken-timestamps': {
|
||||
foreach ($jobs as $job) {
|
||||
$job->fixBrokenTimestamps();
|
||||
}
|
||||
} break;
|
||||
|
||||
default: {
|
||||
throw new RippingCluster_Exception_InvalidParameters('action');
|
||||
|
||||
@@ -44,9 +44,6 @@ function gearman_created_callback($gearman_task) {
|
||||
$main = RippingCluster_Main::instance();
|
||||
$log = $main->log();
|
||||
|
||||
$job = RippingCluster_Job::fromId($gearman_task->unique());
|
||||
$job->updateStatus(RippingCluster_JobStatus::QUEUED);
|
||||
|
||||
$log->info("Job successfully queued with Gearman", $gearman_task->unique());
|
||||
}
|
||||
|
||||
@@ -57,26 +54,10 @@ function gearman_data_callback($gearman_task) {
|
||||
$log->debug("Received data callback from Gearman Task");
|
||||
}
|
||||
|
||||
function gearman_status_callback($gearman_task) {
|
||||
$main = RippingCluster_Main::instance();
|
||||
$log = $main->log();
|
||||
|
||||
$job = RippingCluster_Job::fromId($gearman_task->unique());
|
||||
$status = $job->currentStatus();
|
||||
|
||||
$rip_progress = $gearman_task->taskNumerator() / $gearman_task->taskDenominator();
|
||||
if ($rip_progress > $status->ripProgress() + 0.1) {
|
||||
$status->updateRipProgress($rip_progress);
|
||||
}
|
||||
}
|
||||
|
||||
function gearman_complete_callback($gearman_task) {
|
||||
$main = RippingCluster_Main::instance();
|
||||
$log = $main->log();
|
||||
|
||||
$job = RippingCluster_Job::fromId($gearman_task->unique());
|
||||
$job->updateStatus(RippingCluster_JobStatus::COMPLETE);
|
||||
|
||||
$log->info("Job Complete", $job->id());
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<input type="image" class="icon" name="action" id="mark-failed-top" value="mark-failed" src="{$base_uri}images/caution.png" alt="Mark all marked jobs as failed" />
|
||||
<input type="image" class="icon" name="action" id="redo-top" value="retry" src="{$base_uri}images/redo.png" alt="Repeat all marked jobs" />
|
||||
<input type="image" class="icon" name="action" id="delete-top" value="delete" src="{$base_uri}images/trash.png" alt="Delete all marked jobs" />
|
||||
<input type="image" class="icon" name="action" id="fix-broken-timestamps-top" value="fix-broken-timestamps" src="{$base_uri}images/clock.png" alt="Fix Broken Timestamps in Statuses" />
|
||||
</fieldset>
|
||||
<table>
|
||||
<thead>
|
||||
@@ -60,6 +61,7 @@
|
||||
<input type="image" class="icon" name="action" id="mark-failed-{$job->id()}" value="mark-failed[{$job->id()}]" src="{$base_uri}images/caution.png" alt="Mark job as failed" />
|
||||
<input type="image" class="icon" name="action" id="redo-{$job->id()}" value="retry[{$job->id()}]" src="{$base_uri}images/redo.png" alt="Repeat job" />
|
||||
<input type="image" class="icon" name="action" id="delete-{$job->id()}" value="delete[{$job->id()}]" src="{$base_uri}images/trash.png" alt="Delete job" />
|
||||
<input type="image" class="icon" name="action" id="fix-broken-timestamps-{$job->id()}" value="fix-broken-timestamps[{$job->id()}]" src="{$base_uri}images/clock.png" alt="Fix broken status timestamps" />
|
||||
</fieldset>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -72,6 +74,7 @@
|
||||
<input type="image" class="icon" name="action" id="mark-failed-bottom" value="mark-failed" src="{$base_uri}images/caution.png" alt="Mark all marked jobs as failed" />
|
||||
<input type="image" class="icon" name="action" id="redo-bottom" value="retry" src="{$base_uri}images/redo.png" alt="Repeat all marked jobs" />
|
||||
<input type="image" class="icon" name="action" id="delete-bottom" value="delete" src="{$base_uri}images/trash.png" alt="Delete all marked jobs" />
|
||||
<input type="image" class="icon" name="action" id="fix-broken-timestamps-bottom" value="fix-broken-timestamps" src="{$base_uri}images/clock.png" alt="Fix Broken Timestamps in Statuses" />
|
||||
</fieldset>
|
||||
</form>
|
||||
{else}
|
||||
|
||||
Reference in New Issue
Block a user