   #   + Arguments except the (optional) callback function will be serialized as
   #   a JSON array.
   #   + **The first argument will be served as the group identifier** to ensure
-  #   sequential processing for all tasks of the same group (aka. first-come-
-  #   first-serve). Current time is appended at the argument array for
-  #   monitoring purpose.
-  #
-  # **Usage:**
-  #
-  #     queue.enqueue 'param1', 'param2', -> console.log 'queued!'
-  #     queue.enqueue 'param1', 'param2'
+  #   sequential processing for all tasks of the same group (aka. first-come,
+  #   first-serve, first-done). Current time is appended at the argument array
+  #   for monitoring purpose.
+  #
+  # **Usage:**
+  #
+  #     queue.enqueue 'group_id', 'param2', (err, res) -> # YOUR CODE
   # 
   # A transaction ensures the atomicity.
   enqueue: (args..., callback) =>
     if typeof callback isnt 'function'
       args.push callback
       callback = undefined
-    args.push Date.now()
     multi = @redis.multi()
-    multi.rpush @key('SOURCE'), JSON.stringify([uuid.v4(), args...])
+    multi.rpush @key('SOURCE'), JSON.stringify([uuid.v4(), args..., Date.now()])
+    multi.sadd @key('GROUPS'), args[0]
     multi.hincrby @key('STATISTICS'), 'total', 1
-    multi.sadd @key('GROUPS'), args[0]
     multi.exec callback
 
   # ### Register Handler

registered_workers = []

# Log active workers while waiting for all workers to clean-up.
logging_registered_workers = ->
  console.log "\nFairy is waiting for #{registered_workers.length} workers to clean-up before exit:"
  for registered_worker in registered_workers
    registered_worker = registered_worker.split '|'
    console.log "  * Client Id: #{registered_worker[0]}, Task: #{registered_worker[1]}"

cleanup_required = off

# Fairy will enter cleanup mode before exit when:
#
#   + Received `SIGINT` or `SIGUSR2`.
#   + `uncaughtException` captured.
#
# If there's no registered workers, exit directly.
enter_cleanup_mode = ->
  cleanup_required = on
  logging_registered_workers()
  return process.exit() unless registered_workers.length
  exiting = on

# When `SIGINT` (e.g. `Control-C`) or `SIGUSR2` is received, gracefully exit
# the process by notifying all queues entering cleanup mode and exit after
# all cleaned up.
process.on 'SIGINT',  enter_cleanup_mode
process.on 'SIGUSR2', enter_cleanup_mode

# When `uncaughtException` captured, **Fairy** can not tell if this is caught by
# the handling function, as well as which queue cause the exception. **Fairy**
# will fail all processing tasks and block the according group.
process.on 'uncaughtException', (err) ->
  console.log 'Uncaught Exception:'
  console.log err.stack
  console.log 'Fairy will block all processing groups before exit.'
  enter_cleanup_mode()

# Say goodbye on exit.
process.on 'exit', ->
  console.log "Fairy cleaned up, exiting..." if cleanup_required

# ## Utilities

# ### Get Public IP
#

  client.auth options.password if options.password?
  new Fairy client

# ### Exception / Interruption Handling
#
# Use `uncaughtException` and `SIGINT` to provide elegant exception and user
# interruption handling.
