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

Apply ordering for jobs when using Bull queue #327

Merged
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 5 additions & 1 deletion src/server/views/dashboard/queueJobsByState.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ async function _html(req, res) {

const page = parseInt(req.query.page, 10) || 1;
const pageSize = parseInt(req.query.pageSize, 10) || 100;
const order = req.query.order || 'desc';

const startId = (page - 1) * pageSize;
const endId = startId + pageSize - 1;
Expand All @@ -100,7 +101,8 @@ async function _html(req, res) {
// Filter out Bee jobs that have already been removed by the time the promise resolves
jobs = jobs.filter((job) => job);
} else {
jobs = await queue[`get${_.capitalize(state)}`](startId, endId);
const stateTypes = state === 'waiting' ? ['wait', 'paused'] : state;
jobs = await queue.getJobs(stateTypes, startId, endId, order === 'asc');
await Promise.all(
jobs.map(async (job) => {
const logs = await queue.getJobLogs(job.id);
Expand Down Expand Up @@ -130,10 +132,12 @@ async function _html(req, res) {
jobs,
jobsInStateCount: jobCounts[state],
disablePagination: queue.IS_BEE && (state === 'succeeded' || state === 'failed'),
disableOrdering: queue.IS_BEE,
currentPage: page,
pages,
pageSize,
lastPage: _.last(pages),
order,
});
}

Expand Down
196 changes: 119 additions & 77 deletions src/server/views/dashboard/templates/queueJobsByState.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -5,75 +5,115 @@
<div class="row pagination-container">
<div class="col-sm-6">
{{#unless disablePagination}}
<nav aria-label="Job navigation">
<ul class="pagination">
<li
{{#eq currentPage 1}}
class="disabled">
<span>&laquo;</span>
{{else}}
><a href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ subtract currentPage 1 }}&amp;pageSize={{ pageSize }}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
{{/eq}}
</li>
{{#each pages}}
<li
{{#eq this ../currentPage}}
class="active"
{{/eq}}>
<nav aria-label="Job navigation">
<ul class="pagination">
<li {{#eq currentPage 1}} class="disabled">
<span>&laquo;</span>
{{else}}
><a
href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ subtract currentPage 1 }}&amp;pageSize={{ pageSize }}&amp;order={{ order }}"
aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
{{/eq}}
</li>
{{#each pages}}
<li {{#eq this ../currentPage}} class="active" {{/eq}}>

<a href="{{ ../basePath }}/{{ encodeURI ../queueHost }}/{{ encodeURI ../queueName }}/{{ ../state }}?page={{ this }}&amp;pageSize={{ ../pageSize }}">{{ this }}</a>
</li>
{{/each}}
<li
{{#eq currentPage lastPage}}
class="disabled">
<span>&raquo;</span>
{{else}}
><a href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ add currentPage 1 }}&amp;pageSize={{ pageSize }}" aria-label="Previous">
<span aria-hidden="true">&raquo;</span>
</a>
{{/eq}}
</li>
</ul>
</nav>
<a
href="{{ ../basePath }}/{{ encodeURI ../queueHost }}/{{ encodeURI ../queueName }}/{{ ../state }}?page={{ this }}&amp;pageSize={{ ../pageSize }}&amp;order={{ ../order }}">{{ this }}</a>
</li>
{{/each}}
<li {{#eq currentPage lastPage}} class="disabled">
<span>&raquo;</span>
{{else}}
><a
href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ add currentPage 1 }}&amp;pageSize={{ pageSize }}&amp;order={{ order }}"
aria-label="Previous">
<span aria-hidden="true">&raquo;</span>
</a>
{{/eq}}
</li>
</ul>
</nav>
{{else}}
Bee-queue does not support pagination for {{ state }} queues &mdash; currently displaying up to <b>{{ pageSize }} jobs</b>. To change count, use "Size" dropdown.
Bee-queue does not support pagination for {{ state }} queues &mdash; currently displaying up to <b>{{ pageSize }}
jobs</b>. To change count, use "Size" dropdown.
{{/unless}}
</div>
<div class="col-sm-6 text-right">
<a href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}.json" type="button" class="btn btn-primary">
<a href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}.json" type="button"
class="btn btn-primary">
Dump jobs to JSON (limited to 1000)
</a>
<button type="button" data-action="remove" data-queue-name="{{ queueName }}" data-queue-host="{{ queueHost }}" data-queue-state="{{ state }}" class="js-bulk-action btn btn-danger">
<button type="button" data-action="remove" data-queue-name="{{ queueName }}" data-queue-host="{{ queueHost }}"
data-queue-state="{{ state }}" class="js-bulk-action btn btn-danger">
Remove Jobs
</button>
{{#eq state 'failed'}}
<button type="button" data-action="retry" data-queue-name="{{ queueName }}" data-queue-host="{{ queueHost }}" data-queue-state="{{ state }}" class="js-bulk-action btn btn-success">
Retry Jobs
</button>
<button type="button" data-action="retry" data-queue-name="{{ queueName }}" data-queue-host="{{ queueHost }}"
data-queue-state="{{ state }}" class="js-bulk-action btn btn-success">
Retry Jobs
</button>
{{/eq}}

<div class="btn-group">
<div class="btn-group">
{{#if disablePagination}}
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<div class="dropdown">
{{#if disablePagination}}
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
Size <span class="caret"></span>
</button>
{{else}}
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{else}}
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
Page Size <span class="caret"></span>
</button>
{{/if}}
<ul class="dropdown-menu">
<li><a href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ currentPage }}&amp;pageSize={{ pageSize }}">{{ pageSize }} jobs</a></li>
<li role="separator" class="divider"></li>
<li><a href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ adjustedPage currentPage pageSize 5 }}&amp;pageSize=5">5 jobs</a></li>
<li><a href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ adjustedPage currentPage pageSize 20 }}&amp;pageSize=20">20 jobs</a></li>
<li><a href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ adjustedPage currentPage pageSize 100 }}&amp;pageSize=100">100 jobs</a></li>
<li><a href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ adjustedPage currentPage pageSize 1000 }}&amp;pageSize=1000">1000 jobs</a></li>
</ul>
{{/if}}
<ul class="dropdown-menu">
<li><a
href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ currentPage }}<&amp;order={{ order }}<&amp;pageSize={{ pageSize }}">{{ pageSize }}
jobs</a></li>
<li role="separator" class="divider"></li>
<li><a
href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ adjustedPage currentPage pageSize 5 }}<&amp;order={{ order }}&amp;pageSize=5">5
jobs</a></li>
<li><a
href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ adjustedPage currentPage pageSize 20 }}<&amp;order={{ order }}&amp;pageSize=20">20
jobs</a></li>
<li><a
href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ adjustedPage currentPage pageSize 100 }}<&amp;order={{ order }}&amp;pageSize=100">100
jobs</a></li>
<li><a
href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ adjustedPage currentPage pageSize 1000 }}<&amp;order={{ order }}&amp;pageSize=1000">1000
jobs</a></li>
</ul>
</div>
</div>
{{#unless disableOrdering}}
<div class="btn-group">
<div class="dropdown">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
Order <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li><a
href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ currentPage }}&amp;pageSize={{ pageSize }}&amp;order={{ order }}">{{ order }}
</a></li>
<li role="separator" class="divider"></li>
<li><a
href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ currentPage }}&amp;pageSize={{ pageSize }}&amp;order=asc">acs
</a></li>
<li><a
href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}/{{ state }}?page={{ currentPage }}&amp;pageSize={{ pageSize }}&amp;order=desc">desc
</a></li>
</ul>
</div>
</div>
{{/unless}}
</div>
</div>
</div>

Expand All @@ -87,40 +127,42 @@
</li>

{{#each jobs}}
<li class="list-group-item">
<div class="js-bulk-action-container bulk-job-container">
<input type="hidden" name="jobId" value="{{ this.id }}" />
<input class="js-bulk-job" name="jobChecked" type="checkbox" />
</div>
<li class="list-group-item">
<div class="js-bulk-action-container bulk-job-container">
<input type="hidden" name="jobId" value="{{ this.id }}" />
<input class="js-bulk-job" name="jobChecked" type="checkbox" />
</div>

<a role="button" data-toggle="collapse" href="#collapse{{hashIdAttr this}}">
<h4 class="header-collapse">
<span class="label label-default">{{#if this.id}}{{ this.id }}{{else}}<em>missing id</em>{{/if}}</span>
{{#if this.data.arenaName}}
<span style="margin-left: 8px">{{ this.data.arenaName }}</span>
{{else if this.name}}
<span style="margin-left: 8px">{{ this.name }}</span>
{{else if this.data.name}}
<span style="margin-left: 8px">{{ this.data.name }}</span>
{{/if}}
</h4>
</a>
<div id="collapse{{hashIdAttr this}}" class="collapse">
{{~> dashboard/jobDetails this basePath=../basePath displayJobInline=true queueName=../queueName queueHost=../queueHost jobState=../state }}
</div>
</li>
<a role="button" data-toggle="collapse" href="#collapse{{hashIdAttr this}}">
<h4 class="header-collapse">
<span class="label label-default">{{#if this.id}}{{ this.id }}{{else}}<em>missing id</em>{{/if}}</span>
{{#if this.data.arenaName}}
<span style="margin-left: 8px">{{ this.data.arenaName }}</span>
{{else if this.name}}
<span style="margin-left: 8px">{{ this.name }}</span>
{{else if this.data.name}}
<span style="margin-left: 8px">{{ this.data.name }}</span>
{{/if}}
</h4>
</a>
<div id="collapse{{hashIdAttr this}}" class="collapse">
{{~> dashboard/jobDetails this basePath=../basePath displayJobInline=true queueName=../queueName queueHost=../queueHost jobState=../state }}
</div>
</li>
{{/each}}
</ul>
</form>
</div>
</div>

<p>
<em>Hint: </em><kbd><span style="font-family: sans-serif;">&#8679;</span> + Click</kbd><em> to select a range of jobs.</em>
<em>Hint: </em><kbd><span style="font-family: sans-serif;">&#8679;</span> + Click</kbd><em> to select a range of
jobs.</em>
</p>

{{#contentFor 'sidebar'}}
<li><a href="{{ basePath }}/">Queues Overview</a></li>
<li><a href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}">Queue <code>{{ queueHost }}/{{ queueName }}</code></a></li>
<li class="active"><a href="#">{{capitalize state}} Jobs</a></li>
{{/contentFor}}
<li><a href="{{ basePath }}/">Queues Overview</a></li>
<li><a href="{{ basePath }}/{{ encodeURI queueHost }}/{{ encodeURI queueName }}">Queue
<code>{{ queueHost }}/{{ queueName }}</code></a></li>
<li class="active"><a href="#">{{capitalize state}} Jobs</a></li>
{{/contentFor}}