private final void work_status(final GearmanPacket packet, final ServerClient client) {
    /*
     * This is sent to update the server (and any listening clients)
     * of the status of a running job. The client should send these
     * periodically for long running jobs to update the percentage
     * complete. The job server should store this information so a client
     * who issued a background command may retrieve it later with a
     * GET_STATUS request.
     *
     * Arguments:
     * - NULL byte terminated job handle.
     * - NULL byte terminated percent complete numerator.
     * - Percent complete denominator.
     */

    final byte[] jobHandle = packet.getArgumentData(0);
    assert jobHandle != null;
    final ByteArray jobHandleBA = new ByteArray(jobHandle);

    final byte[] num = packet.getArgumentData(1);
    assert num != null;

    final byte[] den = packet.getArgumentData(2);
    assert den != null;

    final ServerJob job = ServerJobAbstract.getJob(jobHandleBA);
    if (job == null) {
      client.sendPacket(ServerStaticPackets.ERROR_JOB_NOT_FOUND, null /*TODO*/);
    } else {
      packet.setMagic(Magic.RES);
      job.setStatus(num, den);
      job.sendPacket(packet);
    }
  }
  private final void work_data(final GearmanPacket packet, final ServerClient client) {
    /*
     * This is sent to update the client with data from a running job. A
     * client should use this when it needs to send updates, send partial
     * results, or flush data during long running jobs. It can also be
     * used to break up a result so the client does not need to buffer
     * the entire result before sending in a WORK_COMPLETE packet.
     *
     * Arguments:
     * - NULL byte terminated job handle.
     * - Opaque data that is returned to the client.
     */

    final byte[] jobHandle = packet.getArgumentData(0);
    assert jobHandle != null;
    final ByteArray jobHandleBA = new ByteArray(jobHandle);

    final ServerJob job = ServerJobAbstract.getJob(jobHandleBA);
    if (job == null) {
      client.sendPacket(ServerStaticPackets.ERROR_JOB_NOT_FOUND, null /*TODO*/);
    } else {
      packet.setMagic(Magic.RES);
      job.sendPacket(packet);
    }
  }
  private final void work_exception(final GearmanPacket packet, final ServerClient client) {
    /*
     * This is to notify the server (and any listening clients) that
     * the job failed with the given exception.
     *
     * Arguments:
     * - NULL byte terminated job handle.
     * - Opaque data that is returned to the client as an exception.
     */

    // Note: The protocol states this packet notifies the server that the specified job
    // has failed. However, the C server does not fail the Job.  It is effectively a
    // WORK_WARNING packet that is only sent to clients that have specified they want
    // exceptions forwarded to them.  This server will do the same as long as the C
    // server does so.

    /*
     * This is sent to update the client with data from a running job. A
     * client should use this when it needs to send updates, send partial
     * results, or flush data during long running jobs. It can also be
     * used to break up a result so the client does not need to buffer
     * the entire result before sending in a WORK_COMPLETE packet.
     *
     * Arguments:
     * - NULL byte terminated job handle.
     * - Opaque data that is returned to the client.
     */

    final byte[] jobHandle = packet.getArgumentData(0);
    ;
    assert jobHandle != null;
    final ByteArray jobHandleBA = new ByteArray(jobHandle);

    final ServerJob job = ServerJobAbstract.getJob(jobHandleBA);
    if (job == null) {
      client.sendPacket(ServerStaticPackets.ERROR_JOB_NOT_FOUND, null /*TODO*/);
    } else {
      packet.setMagic(Magic.RES);
      job.sendPacket(packet);
    }
  }