Consulte, por ejemplo, Bull como alternativa. ¡Gracias!
Kue es una cola de trabajo prioritaria respaldada por Redis, construida para Node.js.
Protip Esta es la última documentación de Kue, asegúrese de leer también el ChangeList.
Último lanzamiento:
$ npm install kue
Rama maestra:
$ npm install http://github.com/Automattic/kue/tarball/master
Primero cree una Queue
de trabajo con kue.createQueue()
:
var kue = require ( 'kue' )
, queue = kue . createQueue ( ) ;
Llamar a queue.create()
con el tipo de trabajo ("correo electrónico"), y los datos de trabajo arbitrarios devolverán un Job
, que luego se puede save()
ed, agregándolo a Redis, con un nivel de prioridad predeterminado de "Normal". El método save()
opcionalmente acepta una devolución de llamada, respondiendo con un error
si algo sale mal. La clave title
es de especie y se mostrará en los listados de trabajo dentro de la interfaz de usuario, lo que hace que sea más fácil encontrar un trabajo específico.
var job = queue . create ( 'email' , {
title : 'welcome email for tj'
, to : '[email protected]'
, template : 'welcome-email'
} ) . save ( function ( err ) {
if ( ! err ) console . log ( job . id ) ;
} ) ;
Para especificar la prioridad de un trabajo, simplemente invoque el método priority()
con un número o nombre de prioridad, que se asigna a un número.
queue . create ( 'email' , {
title : 'welcome email for tj'
, to : '[email protected]'
, template : 'welcome-email'
} ) . priority ( 'high' ) . save ( ) ;
El mapa de prioridad predeterminado es el siguiente:
{
low : 10
, normal : 0
, medium : - 5
, high : - 10
, critical : - 15
} ;
Por defecto, los trabajos solo tienen un intento, es decir, cuando fallan, están marcados como una falla y siguen siendo así hasta que intervenga. Sin embargo, Kue le permite especificar esto, lo cual es importante para trabajos como la transferencia de un correo electrónico, que al fallar, generalmente puede volver a intentarlo sin problemas. Para hacer esto, invoca el método .attempts()
con un número.
queue . create ( 'email' , {
title : 'welcome email for tj'
, to : '[email protected]'
, template : 'welcome-email'
} ) . priority ( 'high' ) . attempts ( 5 ) . save ( ) ;
Los intentos de reintento de trabajo se realizan tan pronto como fallan, sin demora, incluso si su trabajo tenía un retraso establecido por Job#delay
. Si desea retrasar el trabajo de trabajo de trabajo sobre fallas (conocido como retroceso), puede usar el método Job#backoff
de diferentes maneras:
// Honor job's original delay (if set) at each attempt, defaults to fixed backoff
job . attempts ( 3 ) . backoff ( true )
// Override delay value, fixed backoff
job . attempts ( 3 ) . backoff ( { delay : 60 * 1000 , type : 'fixed' } )
// Enable exponential backoff using original delay (if set)
job . attempts ( 3 ) . backoff ( { type : 'exponential' } )
// Use a function to get a customized next attempt delay value
job . attempts ( 3 ) . backoff ( function ( attempts , delay ) {
//attempts will correspond to the nth attempt failure so it will start with 0
//delay will be the amount of the last delay, not the initial delay unless attempts === 0
return my_customized_calculated_delay ;
} )
En el último escenario, la función proporcionada se ejecutará (a través de Eval) en cada reujecimiento para obtener el próximo valor de retraso de intento, lo que significa que no puede hacer referencia a variables externas/de contexto dentro de él.
Los productores de trabajo pueden establecer un valor de vencimiento por el momento en que su trabajo puede vivir en estado activo, de modo que si los trabajadores no respondieron de manera oportuna, Kue lo fallará con TTL exceeded
el mensaje de error que evita que ese trabajo se quede atascado y se estropee. concurrencia.
queue . create ( 'email' , { title : 'email job with TTL' } ) . ttl ( milliseconds ) . save ( ) ;
Los registros específicos de empleo le permiten exponer información a la UI en cualquier momento del tiempo de vida del trabajo. Para hacerlo, simplemente invoque job.log()
, que acepta una cadena de mensajes, así como argumentos variables para soporte similar a SPRINTF:
job . log ( '$%d sent to %s' , amount , user . name ) ;
o cualquier otra cosa (usa util.inspect () internamente):
job . log ( { key : 'some key' , value : 10 } ) ;
job . log ( [ 1 , 2 , 3 , 5 , 8 ] ) ;
job . log ( 10.1 ) ;
El progreso del trabajo es extremadamente útil para trabajos de larga duración, como la conversión de video. Para actualizar el progreso del trabajo, simplemente invoque job.progress(completed, total [, data])
:
job . progress ( frames , totalFrames ) ;
Los datos se pueden usar para pasar información adicional sobre el trabajo. Por ejemplo, un mensaje o un objeto con algunos datos contextuales adicionales al estado actual.
Los eventos específicos de empleo se disparan en las instancias Job
a través de Redis PubSub. Los siguientes eventos son compatibles actualmente:
enqueue
el trabajo ahora está en colastart
el trabajo ahora se está ejecutandopromotion
El trabajo es promovido de estado retrasado a colaprogress
el progreso del trabajo que va de 0 a 100failed attempt
El trabajo ha fallado, pero aún tiene intentos restantesfailed
el trabajo ha fallado y no tiene intentos restantescomplete
el trabajo se ha completadoremove
el trabajo se ha eliminadoPor ejemplo, esto puede parecerse a lo siguiente:
var job = queue . create ( 'video conversion' , {
title : 'converting loki's to avi'
, user : 1
, frames : 200
} ) ;
job . on ( 'complete' , function ( result ) {
console . log ( 'Job completed with data ' , result ) ;
} ) . on ( 'failed attempt' , function ( errorMessage , doneAttempts ) {
console . log ( 'Job failed' ) ;
} ) . on ( 'failed' , function ( errorMessage ) {
console . log ( 'Job failed' ) ;
} ) . on ( 'progress' , function ( progress , data ) {
console . log ( 'r job #' + job . id + ' ' + progress + '% complete with data ' , data ) ;
} ) ;
Tenga en cuenta que no se garantiza que los eventos de nivel de trabajo se reciban al reiniciar el proceso, ya que el proceso Node.js reiniciado perderá la referencia al objeto de trabajo específico. Si desea un controlador de eventos más confiable, busque eventos de cola.
Tenga en cuenta que Kue almacena objetos de trabajo en la memoria hasta que estén completos/no pueden poder emitir eventos en ellos. Si tiene una gran concurrencia en trabajos incompletos, apague esta función y use eventos de nivel de cola para una mejor escala de memoria.
kue . createQueue ( { jobEvents : false } )
Alternativamente, puede usar los events
de la función de nivel de trabajo para controlar si los eventos se disparan para un trabajo a nivel de trabajo.
var job = queue . create ( 'test' ) . events ( false ) . save ( ) ;
Los eventos a nivel de cola proporcionan acceso a los eventos de nivel de trabajo mencionados anteriormente, sin embargo, el alcance de la instancia Queue
para aplicar la lógica a un nivel "global". Un ejemplo de esto es eliminar los trabajos completos:
queue . on ( 'job enqueue' , function ( id , type ) {
console . log ( 'Job %s got queued of type %s' , id , type ) ;
} ) . on ( 'job complete' , function ( id , result ) {
kue . Job . get ( id , function ( err , job ) {
if ( err ) return ;
job . remove ( function ( err ) {
if ( err ) throw err ;
console . log ( 'removed completed job #%d' , job . id ) ;
} ) ;
} ) ;
} ) ;
Los eventos disponibles son los mismos que se mencionan en "Eventos de trabajo", sin embargo, prefijados con "trabajo".
Se pueden programar trabajos retrasados para colocar una distancia arbitraria en el tiempo invocando el método .delay(ms)
, pasando el número de milisegundos en relación con ahora . Alternativamente, puede pasar un objeto Date
JavaScript con un tiempo específico en el futuro. Esto marca automáticamente el Job
como "retrasado".
var email = queue . create ( 'email' , {
title : 'Account renewal required'
, to : '[email protected]'
, template : 'renewal-email'
} ) . delay ( milliseconds )
. priority ( 'high' )
. save ( ) ;
Kue verificará los trabajos retrasados con un temporizador, promocionándolos si se ha excedido el retraso programado, por defecto a un control de los 1000 empleos principales cada segundo.
El procesamiento de trabajos es simple con Kue. Primero cree una instancia Queue
muy como lo hacemos para crear empleos, proporcionarnos acceso a Redis, etc., luego invocar queue.process()
con el tipo asociado. Tenga en cuenta que, a diferencia de lo que sugiere el nombre createQueue
, actualmente devuelve una instancia Queue
singleton. Por lo tanto, puede configurar y usar solo un objeto Queue
solo dentro de su proceso Node.js.
En el siguiente ejemplo, pasamos la devolución de llamada done
al email
, cuando ocurre un error, invocamos done(err)
para decirle a Kue que sucedió algo, de lo contrario invocamos done()
solo cuando el trabajo está completo. Si esta función responde con un error, se mostrará en la interfaz de usuario y el trabajo se marcará como una falla. El objeto de error pasado al hecho, debe ser de Error
de tipo estándar.
var kue = require ( 'kue' )
, queue = kue . createQueue ( ) ;
queue . process ( 'email' , function ( job , done ) {
email ( job . data . to , done ) ;
} ) ;
function email ( address , done ) {
if ( ! isValidEmail ( address ) ) {
//done('invalid to address') is possible but discouraged
return done ( new Error ( 'invalid to address' ) ) ;
}
// email send stuff...
done ( ) ;
}
Los trabajadores también pueden aprobar el resultado del trabajo como el segundo parámetro done(null,result)
para almacenarlo en la clave de Job.result
. result
también se pasa a través de los manejadores de eventos complete
para que los productores de empleo puedan recibirlo si les gusta.
Por defecto, una llamada a queue.process()
solo aceptará un trabajo a la vez para procesar. Para tareas pequeñas como enviar correos electrónicos, esto no es ideal, por lo que podemos especificar los trabajos activos máximos para este tipo pasando un número:
queue . process ( 'email' , 20 , function ( job , done ) {
// ...
} ) ;
Los trabajadores pueden detener temporalmente y reanudar su actividad. Es decir, después de llamar pause
, no recibirán trabajos en su devolución de llamada de su proceso hasta que se llame resume
. La función pause
apaga con gracia a este trabajador y utiliza la misma funcionalidad interna que el método shutdown
en el cierre elegante.
queue . process ( 'email' , function ( job , ctx , done ) {
ctx . pause ( 5000 , function ( err ) {
console . log ( "Worker is paused... " ) ;
setTimeout ( function ( ) { ctx . resume ( ) ; } , 10000 ) ;
} ) ;
} ) ;
Tenga en cuenta que el parámetro ctx
de Kue >=0.9.0
es el segundo argumento de la función de devolución de llamada del proceso y done
es idiomáticamente el último
Nota La firma del método pause
se cambia de kue >=0.9.0
para mover la función de devolución de llamada a la última.
Para un ejemplo "real", supongamos que necesitamos compilar un PDF de numerosas diapositivas con canvas de nodo. Nuestro trabajo puede consistir en los siguientes datos, tenga en cuenta que, en general, no debe almacenar datos grandes en el trabajo de sí mismo, es mejor almacenar referencias como IDS, atrayéndolos mientras se procesa.
queue . create ( 'slideshow pdf' , {
title : user . name + "'s slideshow"
, slides : [ ... ] // keys to data stored in redis, mongodb, or some other store
} ) ;
Podemos acceder a estos mismos datos arbitrarios dentro de un proceso separado mientras procesamos, a través de la propiedad job.data
. En el ejemplo, representamos cada diapositiva uno por uno, actualizando el registro y el progreso del trabajo.
queue . process ( 'slideshow pdf' , 5 , function ( job , done ) {
var slides = job . data . slides
, len = slides . length ;
function next ( i ) {
var slide = slides [ i ] ; // pretend we did a query on this slide id ;)
job . log ( 'rendering %dx%d slide' , slide . width , slide . height ) ;
renderSlide ( slide , function ( err ) {
if ( err ) return done ( err ) ;
job . progress ( i , len , { nextSlide : i == len ? 'itsdone' : i + 1 } ) ;
if ( i == len ) done ( )
else next ( i + 1 ) ;
} ) ;
}
next ( 0 ) ;
} ) ;
Queue#shutdown([timeout,] fn)
señala a todos los trabajadores que dejen de procesar después de que se realice su trabajo activo actual. Los trabajadores esperarán timeout
los milisegundos para que se hagan sus trabajos activos para que se llamen o marcarán el trabajo activo failed
con el motivo de error de cierre. Cuando todos los trabajadores le dicen a Kue que están detenidos, se llama fn
.
var queue = require ( 'kue' ) . createQueue ( ) ;
process . once ( 'SIGTERM' , function ( sig ) {
queue . shutdown ( 5000 , function ( err ) {
console . log ( 'Kue shutdown: ' , err || '' ) ;
process . exit ( 0 ) ;
} ) ;
} ) ;
Tenga en cuenta que la firma del método shutdown
se cambia de kue >=0.9.0
para mover la función de devolución de llamada a la última.
Todos los errores, ya sea en la biblioteca de clientes de Redis o la cola, se emiten al objeto Queue
. Debe vincularse a eventos error
para evitar excepciones no capturadas o depurar errores de Kue.
var queue = require ( 'kue' ) . createQueue ( ) ;
queue . on ( 'error' , function ( err ) {
console . log ( 'Oops... ' , err ) ;
} ) ;
Kue marca un trabajo completo/fallido cuando su trabajador done
llama, por lo que debe usar el manejo de errores adecuado para evitar excepciones no capturas en el código y el proceso de nodo.js de su trabajador. Esto se puede lograr de dos maneras:
queue . process ( 'my-error-prone-task' , function ( job , done ) {
var domain = require ( 'domain' ) . create ( ) ;
domain . on ( 'error' , function ( err ) {
done ( err ) ;
} ) ;
domain . run ( function ( ) { // your process function
throw new Error ( 'bad things happen' ) ;
done ( ) ;
} ) ;
} ) ;
AVISO: los dominios están en desuso de NodeJs con estabilidad 0 y no se recomienda usar.
Esta es la solución más suave y mejor, sin embargo, no está incorporada con Kue. Consulte esta discusión. Puede comentar sobre esta función en el problema de Kue abierto relacionado.
También puedes usar promesas para hacer algo como
queue . process ( 'my-error-prone-task' , function ( job , done ) {
Promise . method ( function ( ) { // your process function
throw new Error ( 'bad things happen' ) ;
} ) ( ) . nodeify ( done )
} ) ;
Pero esto no atrapará excepciones en su pila de llamadas Async como lo hacen los dominios.
uncaughtException
y apagando con gracia el Kue, sin embargo, este no es un error recomendado que maneje el idioma en JavaScript, ya que está perdiendo el contexto de error. process . once ( 'uncaughtException' , function ( err ) {
console . error ( 'Something bad happened: ' , err ) ;
queue . shutdown ( 1000 , function ( err2 ) {
console . error ( 'Kue shutdown result: ' , err2 || 'OK' ) ;
process . exit ( 0 ) ;
} ) ;
} ) ;
Actualmente, Kue utiliza la gestión del estado del trabajo del lado del cliente y cuando Redis se bloquea en el medio de esas operaciones, se producirán algunos trabajos atascados o inconsistencias de índice. La consecuencia es que cierta cantidad de trabajos se atascarán y serán sacados por el trabajador solo cuando se crean nuevos empleos, si no se crean más nuevos trabajos, se atasquen para siempre. Así que le sugerimos encarecidamente que ejecute Watchdog para solucionar este problema llamando:
queue . watchStuckJobs ( interval )
interval
está en milisegundos y predeterminados a 1000 ms
Kue se refactorará para la gestión de estado de trabajo completamente atómico desde la versión 1.0 y esto sucederá mediante los scripts de Lua y/o la combinación de Brpoplpush. Puedes leer más aquí y aquí.
El objeto de cola tiene dos tipos de métodos para informarle sobre la cantidad de trabajos en cada estado
queue . inactiveCount ( function ( err , total ) { // others are activeCount, completeCount, failedCount, delayedCount
if ( total > 100000 ) {
console . log ( 'We need some back pressure here' ) ;
}
} ) ;
También puede consultar sobre un tipo de trabajo específico:
queue . failedCount ( 'my-critical-job' , function ( err , total ) {
if ( total > 10000 ) {
console . log ( 'This is tOoOo bad' ) ;
}
} ) ;
e iterando sobre identificaciones de trabajo
queue . inactive ( function ( err , ids ) { // others are active, complete, failed, delayed
// you may want to fetch each id to get the Job object out of it...
} ) ;
Sin embargo, el segundo no escala a grandes implementaciones, allí puede usar métodos estáticos Job
más específicos:
kue . Job . rangeByState ( 'failed' , 0 , n , 'asc' , function ( err , jobs ) {
// you have an array of maximum n Job objects here
} ) ;
o
kue . Job . rangeByType ( 'my-job-type' , 'failed' , 0 , n , 'asc' , function ( err , jobs ) {
// you have an array of maximum n Job objects here
} ) ;
Tenga en cuenta que los dos últimos métodos están sujetos a cambios en versiones posteriores de Kue.
Si no hizo nada de lo anterior en la sección de manejo de errores o su proceso perdió los trabajos activos de alguna manera, puede recuperarse de ellos cuando se reinicie su proceso. Una lógica ciega sería volver a colocar todos los trabajos atascados:
queue . active ( function ( err , ids ) {
ids . forEach ( function ( id ) {
kue . Job . get ( id , function ( err , job ) {
// Your application should check if job is a stuck one
job . inactive ( ) ;
} ) ;
} ) ;
} ) ;
Nota En una implementación agrupada, su solicitud debe tener en cuenta no involucrar un trabajo que es válido, actualmente inútil por otros trabajadores.
Los datos de los trabajos y los índices de búsqueda comen el espacio de memoria Redis, por lo que necesitará algún proceso de mantenimiento de empleo en las implementaciones del mundo real. Su primera oportunidad es utilizar la eliminación automática de trabajo al finalizar.
queue . create ( ... ) . removeOnComplete ( true ) . save ( )
Pero si eventualmente necesita/temporalmente necesita datos de trabajo completos, puede configurar un script de eliminación de trabajo a pedido como a continuación para eliminar los trabajos Top n
completados:
kue . Job . rangeByState ( 'complete' , 0 , n , 'asc' , function ( err , jobs ) {
jobs . forEach ( function ( job ) {
job . remove ( function ( ) {
console . log ( 'removed ' , job . id ) ;
} ) ;
} ) ;
} ) ;
Tenga en cuenta que debe proporcionar suficiente tiempo para que las llamadas .remove
De forma predeterminada, Kue se conectará a Redis utilizando la configuración predeterminada del cliente (el puerto predeterminada es 6379
, el host del hosts es 127.0.0.1
, el prefijo predeterminado a q
). Queue#createQueue(options)
acepta opciones de conexión Redis en options.redis
Key.
var kue = require ( 'kue' ) ;
var q = kue . createQueue ( {
prefix : 'q' ,
redis : {
port : 1234 ,
host : '10.0.50.20' ,
auth : 'password' ,
db : 3 , // if provided select a non-default redis db
options : {
// see https://github.com/mranney/node_redis#rediscreateclient
}
}
} ) ;
prefix
controla los nombres clave utilizados en Redis. Por defecto, esto es simplemente q
. El prefijo generalmente no debe cambiarse a menos que necesite usar una instancia de Redis para múltiples aplicaciones. También puede ser útil para proporcionar un tono de prueba aislado en su aplicación principal.
También puede especificar la información de conexión como una cadena de URL.
var q = kue . createQueue ( {
redis : 'redis://example.com:1234?redis_option=value&redis_option=value'
} ) ;
Dado que Node_redis admite enchufes de dominio Unix, también puede decirle a Kue que lo haga. Consulte Unix-Domain-Socket para la configuración de su servidor Redis.
var kue = require ( 'kue' ) ;
var q = kue . createQueue ( {
prefix : 'q' ,
redis : {
socket : '/data/sockets/redis.sock' ,
auth : 'password' ,
options : {
// see https://github.com/mranney/node_redis#rediscreateclient
}
}
} ) ;
Cualquier biblioteca de cliente Node.js Redis que se ajuste (o cuando se adapte) a la API Node_Redis se puede inyectar en Kue. Solo debe proporcionar una función createClientFactory
como una fábrica de conexión Redis en lugar de proporcionar opciones de conexión Node_Redis.
A continuación se muestra un código de muestra para habilitar Redis-Sentinel para conectarse a Redis Sentinel para la conmutación por error de maestría/esclavo automático.
var kue = require ( 'kue' ) ;
var Sentinel = require ( 'redis-sentinel' ) ;
var endpoints = [
{ host : '192.168.1.10' , port : 6379 } ,
{ host : '192.168.1.11' , port : 6379 }
] ;
var opts = options || { } ; // Standard node_redis client options
var masterName = 'mymaster' ;
var sentinel = Sentinel . Sentinel ( endpoints ) ;
var q = kue . createQueue ( {
redis : {
createClientFactory : function ( ) {
return sentinel . createClient ( masterName , opts ) ;
}
}
} ) ;
Tenga en cuenta que todos los códigos de cliente <0.8.x
deben refactorizarse para pasar opciones de Redis para Queue#createQueue
en lugar del estilo parcheado de mono anulando redis#createClient
o se romperán desde Kue 0.8.x
var Redis = require ( 'ioredis' ) ;
var kue = require ( 'kue' ) ;
// using https://github.com/72squared/vagrant-redis-cluster
var queue = kue . createQueue ( {
redis : {
createClientFactory : function ( ) {
return new Redis . Cluster ( [ {
port : 7000
} , {
port : 7001
} ] ) ;
}
}
} ) ;
La interfaz de usuario es una pequeña aplicación expresa. Se proporciona un script en bin/
para ejecutar la interfaz como una aplicación independiente con la configuración predeterminada. Puede transmitir opciones para el puerto, Redis-URL y el prefijo. Por ejemplo:
node_modules/kue/bin/kue-dashboard -p 3050 -r redis://127.0.0.1:3000 -q prefix
También puede dispararlo dentro de otra aplicación:
var kue = require ( 'kue' ) ;
kue . createQueue ( ... ) ;
kue . app . listen ( 3000 ) ;
El título predeterminado es "kue", para alterar este invocar:
kue . app . set ( 'title' , 'My Application' ) ;
Tenga en cuenta que si está utilizando opciones de Kue no deformes, se debe llamar kue.createQueue(...)
antes de acceder kue.app
.
También puede usar la interfaz web Kue-Ui aportada por Arnaud Bénard
Junto con la UI Kue también expone una API JSON, que es utilizada por la interfaz de usuario.
Trabajos de consulta, por ejemplo, "get /trabajo /search? Q = AVI Video":
[ "5" , "7" , "10" ]
Por defecto, Kue indexa todo el objeto de datos de trabajo para buscar, pero esto se puede personalizar mediante llamando Job#searchKeys
para decirle a Kue qué claves en los datos del trabajo para crear índice para:
var kue = require ( 'kue' ) ;
queue = kue . createQueue ( ) ;
queue . create ( 'email' , {
title : 'welcome email for tj'
, to : '[email protected]'
, template : 'welcome-email'
} ) . searchKeys ( [ 'to' , 'title' ] ) . save ( ) ;
La función de búsqueda se desactiva de forma predeterminada de kue >=0.9.0
. Lea más sobre esto aquí. Debe habilitar los índices de búsqueda y agregar rojos en sus dependencias si es necesario:
var kue = require ( 'kue' ) ;
q = kue . createQueue ( {
disableSearch : false
} ) ;
npm install reds --save
Actualmente responde con los recuentos estatales y el tiempo de actividad de los trabajadores en milisegundos:
{ "inactiveCount" : 4 , "completeCount" : 69 , "activeCount" : 2 , "failedCount" : 0 , "workTime" : 20892 }
Obtenga un trabajo por :id
:
{ "id" : "3" , "type" : "email" , "data" : { "title" : "welcome email for tj" , "to" : "[email protected]" , "template" : "welcome-email" } , "priority" : - 10 , "progress" : "100" , "state" : "complete" , "attempts" : null , "created_at" : "1309973155248" , "updated_at" : "1309973155248" , "duration" : "15002" }
Obtener trabajo :id
de registro:
[ 'foo' , 'bar' , 'baz' ]
Obtenga trabajos con el rango especificado :from
:to
, por ejemplo "/jobs/0..2", donde :order
puede ser "ass" o "descielo":
[ { "id" : "12" , "type" : "email" , "data" : { "title" : "welcome email for tj" , "to" : "[email protected]" , "template" : "welcome-email" } , "priority" : - 10 , "progress" : 0 , "state" : "active" , "attempts" : null , "created_at" : "1309973299293" , "updated_at" : "1309973299293" } , { "id" : "130" , "type" : "email" , "data" : { "title" : "welcome email for tj" , "to" : "[email protected]" , "template" : "welcome-email" } , "priority" : - 10 , "progress" : 0 , "state" : "active" , "attempts" : null , "created_at" : "1309975157291" , "updated_at" : "1309975157291" } ]
Igual que el anterior, restringiendo por :state
que es uno de:
- active
- inactive
- failed
- complete
Igual que el anterior, sin embargo, restringido a :type
y :state
.
Eliminar trabajo :id
:
$ curl -X DELETE http://local:3000/job/2
{"message":"job 2 removed"}
Crear un trabajo:
$ curl -H "Content-Type: application/json" -X POST -d
'{
"type": "email",
"data": {
"title": "welcome email for tj",
"to": "[email protected]",
"template": "welcome-email"
},
"options" : {
"attempts": 5,
"priority": "high"
}
}' http://localhost:3000/job
{"message": "job created", "id": 3}
Puede crear múltiples trabajos a la vez pasando una matriz. En este caso, la respuesta también será una matriz, preservando el pedido:
$ curl -H "Content-Type: application/json" -X POST -d
'[{
"type": "email",
"data": {
"title": "welcome email for tj",
"to": "[email protected]",
"template": "welcome-email"
},
"options" : {
"attempts": 5,
"priority": "high"
}
},
{
"type": "email",
"data": {
"title": "followup email for tj",
"to": "[email protected]",
"template": "followup-email"
},
"options" : {
"delay": 86400,
"attempts": 5,
"priority": "high"
}
}]' http://localhost:3000/job
[
{"message": "job created", "id": 4},
{"message": "job created", "id": 5}
]
Nota: Al insertar múltiples trabajos a granel, si una inserción falla, Kue seguirá procesando los trabajos restantes en orden. La matriz de respuesta contendrá los ID de los trabajos agregados correctamente, y cualquier elemento fallido será un objeto que describa el error: {"error": "error reason"}
.
El siguiente ejemplo muestra cómo puede usar el clúster para difundir la carga de procesamiento del trabajo en las CPU. Consulte la documentación del módulo de clúster para obtener ejemplos más detallados sobre el uso de ella.
Cuando el clúster .isMaster
el archivo se está ejecutando en el contexto del proceso maestro, en cuyo caso puede realizar tareas que solo desea una vez, como iniciar la aplicación web incluida con Kue. La lógica en el bloque else
se ejecuta por trabajador .
var kue = require ( 'kue' )
, cluster = require ( 'cluster' )
, queue = kue . createQueue ( ) ;
var clusterWorkerSize = require ( 'os' ) . cpus ( ) . length ;
if ( cluster . isMaster ) {
kue . app . listen ( 3000 ) ;
for ( var i = 0 ; i < clusterWorkerSize ; i ++ ) {
cluster . fork ( ) ;
}
} else {
queue . process ( 'email' , 10 , function ( job , done ) {
var pending = 5
, total = pending ;
var interval = setInterval ( function ( ) {
job . log ( 'sending!' ) ;
job . progress ( total - pending , total ) ;
-- pending || done ( ) ;
pending || clearInterval ( interval ) ;
} , 1000 ) ;
} ) ;
}
Esto creará un procesador de trabajo email
(trabajador) por cada uno de los núcleos de CPU de su máquina, con cada uno puede manejar 10 trabajos de correo electrónico concurrentes, lo que lleva a un total de 10 * N
empleos de correo electrónico concurrentes procesados en su máquina N
central.
Ahora, cuando visite la interfaz de usuario de Kue en el navegador, ¡verá que los trabajos se procesan aproximadamente N
veces más rápido! (Si tienes N
núcleos).
Mediante el uso del montaje de aplicaciones, puede personalizar la aplicación web, habilitar TLS o agregar middleware adicional como basic-auth-connect
.
$ npm install --save basic-auth-connect
var basicAuth = require ( 'basic-auth-connect' ) ;
var app = express . createServer ( { ... tls options ... } ) ;
app . use ( basicAuth ( 'foo' , 'bar' ) ) ;
app . use ( kue . app ) ;
app . listen ( 3000 ) ;
Habilite el modo de prueba para empujar todos los trabajos en una matriz jobs
. Haga afirmaciones contra los trabajos en esa matriz para garantizar que el código bajo la prueba esté en cuanto a los trabajos.
queue = require ( 'kue' ) . createQueue ( ) ;
before ( function ( ) {
queue . testMode . enter ( ) ;
} ) ;
afterEach ( function ( ) {
queue . testMode . clear ( ) ;
} ) ;
after ( function ( ) {
queue . testMode . exit ( )
} ) ;
it ( 'does something cool' , function ( ) {
queue . createJob ( 'myJob' , { foo : 'bar' } ) . save ( ) ;
queue . createJob ( 'anotherJob' , { baz : 'bip' } ) . save ( ) ;
expect ( queue . testMode . jobs . length ) . to . equal ( 2 ) ;
expect ( queue . testMode . jobs [ 0 ] . type ) . to . equal ( 'myJob' ) ;
expect ( queue . testMode . jobs [ 0 ] . data ) . to . eql ( { foo : 'bar' } ) ;
} ) ;
IMPORTANTE: Por defecto, los trabajos no se procesan cuando se crean durante el modo de prueba. Puede habilitar el procesamiento del trabajo pasando True a testMode.enter
before ( function ( ) {
queue . testMode . enter ( true ) ;
} ) ;
¡Nos encantan las contribuciones!
Al contribuir, siga las reglas simples:
(La licencia del MIT)
Copyright (c) 2011 LearnBoost <[email protected]>
Por la presente, se otorga el permiso, de forma gratuita, a cualquier persona que obtenga una copia de este software y archivos de documentación asociados (el 'software'), para tratar el software sin restricción, incluidos los derechos de usar, copiar, modificar, modificar, modificar, fusionar , publique, distribuya, sublicence y venda copias del software, y para permitir a las personas a las que se proporciona el software para hacerlo, sujeto a las siguientes condiciones:
El aviso de derechos de autor anterior y este aviso de permiso se incluirán en todas las copias o porciones sustanciales del software.
El software se proporciona 'tal cual', sin garantía de ningún tipo, expresa o implícita, incluidas, entre otros, las garantías de comerciabilidad, idoneidad para un propósito particular y no infracción. En ningún caso los autores o titulares de derechos de autor serán responsables de cualquier reclamo, daños u otro responsabilidad, ya sea en una acción de contrato, agravio o de otro tipo, derivado, de o en relación con el software o el uso u otros tratos en el SOFTWARE.