Skip to content

Job Management

Quest provides a simple API to manage your scheduled jobs programmatically.

Starting Jobs

Jobs start automatically by default when Sails lifts. You can also start them manually:

javascript
// Start all jobs
await sails.quest.start()

// Start a specific job
await sails.quest.start('weekly-report')

// Start multiple jobs
await sails.quest.start(['cleanup', 'backup', 'reports'])

Stopping Jobs

Stop jobs from running on their schedule:

javascript
// Stop all jobs
await sails.quest.stop()

// Stop a specific job
await sails.quest.stop('heavy-processing')

// Stop multiple jobs
await sails.quest.stop(['job1', 'job2'])

Running Jobs Manually

Execute a job immediately, regardless of its schedule:

javascript
// Run with default inputs
await sails.quest.run('send-newsletter')

// Run with custom inputs
await sails.quest.run('cleanup-sessions', {
  daysOld: 7,
  verbose: true
})

// Run multiple jobs
await sails.quest.run(['job1', 'job2'])

Running Any Sails Script

Quest can run ANY Sails script, not just ones with quest configuration:

javascript
// This script has NO quest metadata - just a regular Sails script
// scripts/migrate-data.js
module.exports = {
  friendlyName: 'Migrate data',

  inputs: {
    dryRun: {
      type: 'boolean',
      defaultsTo: true
    }
  },

  fn: async function ({ dryRun }) {
    // Migration logic...
    return { migrated: 100, dryRun }
  }
}

// You can still run it with Quest!
await sails.quest.run('migrate-data', { dryRun: false })

This is perfect for:

  • One-time administrative tasks
  • Scripts triggered by user actions
  • Testing scripts before scheduling them
  • Running maintenance scripts from the console

Pausing and Resuming

Temporarily pause a job without removing its schedule:

javascript
// Pause a job (won't execute but keeps schedule)
sails.quest.pause('resource-intensive-job')

// Resume a paused job
sails.quest.resume('resource-intensive-job')

// Check if a job is paused
const job = sails.quest.get('resource-intensive-job')
if (job.paused) {
  console.log('Job is currently paused')
}

Listing Jobs

Get information about registered jobs:

javascript
// List all jobs
const jobs = sails.quest.list()
console.log(jobs)
// [{
//   name: 'cleanup',
//   interval: '1 hour',
//   paused: false,
//   withoutOverlapping: true
// }, ...]

// Get a specific job
const job = sails.quest.get('weekly-report')
console.log(job.friendlyName) // "Weekly Report Generator"

Checking Job Status

javascript
// Check if a job is currently running
if (sails.quest.isRunning('data-import')) {
  console.log('Import is in progress...')
}

// Get all running jobs
const runningJobs = sails.quest
  .list()
  .filter((job) => sails.quest.isRunning(job.name))

Dynamic Job Management

Add or remove jobs at runtime:

javascript
// Add a new job dynamically
await sails.quest.add({
  name: 'temporary-task',
  interval: '10 minutes',
  inputs: { mode: 'production' }
})

// Add multiple jobs
await sails.quest.add([
  { name: 'job1', interval: '5 minutes' },
  { name: 'job2', cron: '0 * * * *' }
])

// Remove a job
sails.quest.remove('temporary-task')

// Remove multiple jobs
sails.quest.remove(['job1', 'job2'])

Auto-Start Configuration

Control whether jobs start automatically:

javascript
// config/quest.js
module.exports.quest = {
  autoStart: false // Don't start jobs on lift
}

// Then start manually in bootstrap.js
// config/bootstrap.js
module.exports.bootstrap = async function () {
  // Do some setup...

  // Now start the jobs
  await sails.quest.start()
}

Job Configuration in Config

Define jobs directly in your config:

javascript
// config/quest.js
module.exports.quest = {
  jobs: [
    {
      name: 'health-check',
      interval: '5 minutes',
      inputs: {
        url: 'https://api.example.com/health'
      }
    },
    {
      name: 'daily-backup',
      cron: '0 3 * * *',
      withoutOverlapping: true
    }
  ]
}

Practical Examples

Maintenance Mode

javascript
// Enter maintenance mode - pause all jobs
const jobs = sails.quest.list()
jobs.forEach((job) => sails.quest.pause(job.name))

// Exit maintenance mode - resume all jobs
jobs.forEach((job) => sails.quest.resume(job.name))

Conditional Job Execution

javascript
// In your script
module.exports = {
  friendlyName: 'Conditional job',

  quest: {
    interval: '1 hour'
  },

  fn: async function () {
    // Check conditions
    const settings = await Settings.findOne({ key: 'jobs_enabled' })
    if (!settings.value) {
      console.log('Jobs are disabled, skipping...')
      return { skipped: true }
    }

    // Proceed with job logic
    // ...
  }
}

Rate Limiting

javascript
// Only allow one instance to run
quest: {
  interval: '1 minute',
  withoutOverlapping: true  // Prevents concurrent runs
}

All open source projects are released under the MIT License.