Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.x] Ability to see if a job is delayed #755

Merged
merged 10 commits into from
Feb 12, 2020
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions resources/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,13 @@ import Routes from './routes';
import VueRouter from 'vue-router';
import VueJsonPretty from 'vue-json-pretty';

require('bootstrap');
window.Popper = require('popper.js').default;

try {
window.$ = window.jQuery = require('jquery');

require('bootstrap');
} catch (e) {}

let token = document.head.querySelector('meta[name="csrf-token"]');

Expand All @@ -17,8 +23,6 @@ if (token) {

Vue.use(VueRouter);

window.Popper = require('popper.js').default;

Vue.prototype.$http = axios.create();

window.Horizon.basePath = '/' + window.Horizon.path;
Expand All @@ -41,6 +45,14 @@ Vue.component('alert', require('./components/Alert.vue').default);

Vue.mixin(Base);

Vue.directive('tooltip', function(el, binding) {
$(el).tooltip({
title: binding.value,
placement: binding.arg,
trigger: 'hover',
});
});

new Vue({
el: '#horizon',

Expand Down
7 changes: 7 additions & 0 deletions resources/js/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,12 @@ export default {
readableTimestamp(timestamp) {
return this.formatDate(timestamp).format('YYYY-MM-DD HH:mm:ss');
},

/**
* Convert to human readable timestamp e.g. "18 minutes".
*/
readableHumanTimestamp(timestamp) {
return this.formatDate(timestamp).fromNow(true);
},
},
};
2 changes: 0 additions & 2 deletions resources/js/components/Alert.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
<script type="text/ecmascript-6">
import $ from 'jquery';

export default {
props: ['type', 'message', 'autoClose', 'confirmationProceed', 'confirmationCancel'],

Expand Down
6 changes: 3 additions & 3 deletions resources/js/components/Stacktrace.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script type="text/ecmascript-6">
import _ from "lodash"
import _take from "lodash/take"

export default {
props: ['trace'],
Expand All @@ -16,7 +16,7 @@

computed: {
lines(){
return this.showAll ? _.take(this.trace, 1000) : _.take(this.trace, this.minimumLines);
return this.showAll ? _take(this.trace, 1000) : _take(this.trace, this.minimumLines);
}
}
}
Expand All @@ -38,4 +38,4 @@

<style scoped>

</style>
</style>
2 changes: 0 additions & 2 deletions resources/js/screens/monitoring/index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
<script type="text/ecmascript-6">
import $ from 'jquery';

export default {
/**
* The component's data.
Expand Down
7 changes: 4 additions & 3 deletions resources/js/screens/recentJobs/index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
<script type="text/ecmascript-6">
import $ from 'jquery';

export default {
/**
* The component's data.
Expand Down Expand Up @@ -173,7 +171,10 @@
<span v-if="job.status != 'failed'" :title="job.name">{{jobBaseName(job.name)}}</span>
<router-link v-if="job.status === 'failed'" :title="job.name" :to="{ name: 'failed-jobs-preview', params: { jobId: job.id }}">
{{ jobBaseName(job.name) }}
</router-link><br>
</router-link>

<small class="badge badge-secondary badge-sm" v-tooltip:top="`Delayed for ${readableHumanTimestamp(job.delayed)}`" v-if="job.delayed && (job.status == 'reserved' || job.status == 'pending')">Delayed</small>
<br>

<small class="text-muted">
<router-link :to="{name: 'recent-jobs-preview', params: {jobId: job.id}}">View detail</router-link> |
Expand Down
11 changes: 10 additions & 1 deletion resources/js/screens/recentJobs/job.vue
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,18 @@
<div class="col-md-2"><strong>Queue</strong></div>
<div class="col">{{job.queue}}</div>
</div>
<div class="row mb-2">
<div class="col-md-2"><strong>Pushed At</strong></div>
<div class="col">{{ readableTimestamp(job.payload.pushedAt) }}</div>
</div>
<div class="row mb-2" v-if="job.delayed">
<div class="col-md-2"><strong>Delayed Until</strong></div>
<div class="col">{{readableTimestamp(job.delayed)}}</div>
</div>
<div class="row">
<div class="col-md-2"><strong>Completed At</strong></div>
<div class="col">{{readableTimestamp(job.completed_at)}}</div>
<div class="col" v-if="job.completed_at">{{readableTimestamp(job.completed_at)}}</div>
<div class="col" else>-</div>
</div>
</div>
</div>
Expand Down
4 changes: 4 additions & 0 deletions resources/sass/base.scss
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,7 @@ button:hover {
color: #fff;
background: $danger;
}

.badge-sm {
font-size: 0.75rem;
}
4 changes: 4 additions & 0 deletions src/Http/Controllers/RecentJobsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ public function index(Request $request)
$jobs = $this->jobs->getRecent($request->query('starting_at', -1))->map(function ($job) {
$job->payload = json_decode($job->payload);

$job->delayed = strtotime(optional(unserialize($job->payload->data->command))->delay);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are unserializing the entire command to get this won't that re-issue the database queries needed to get the Eloquent models / collections required by the job?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@taylorotwell Just tried, indeed it will introduce queries to be run whenever a model is type hinted into the job class, this will introduce reduced performance once there are jobs with a lot of models.

Is there a way to disable this magic once we call an unserialise on the payload?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not that I can think of off of the top of my head. It may be possible to extract the delay from the raw serialized string but I'm not sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am going to think and try some stuff out. Will get back on this, thanks, good find 👍


return $job;
})->values();

Expand All @@ -64,6 +66,8 @@ protected function decode($job)
{
$job->payload = json_decode($job->payload);

$job->delayed = strtotime(optional(unserialize($job->payload->data->command))->delay);

return $job;
}
}