/**
   * Get the solution and stores it in MongoDB after an <code>async</code> request.
   *
   * @param jobid the job id.
   */
  private void completedAsync(String jobid) {
    LOG.log(Level.INFO, "Complete async job {0}", jobid);
    try {
      // create the request
      TruckingJobOutput updater = new TruckingJobOutput(this.mongoDB);
      JobRequest request =
          jobclient.newRequest().output(updater).timeout(60, TimeUnit.SECONDS).build();
      updater.setRequest(request);

      executor.monitor(request, jobid, null).get();

    } catch (Exception e) {
      LOG.log(Level.WARNING, "Error while completing job", e);
      e.printStackTrace();
    } finally {
      // always cleanup the job by deleting it
      if (jobid != null) {
        try {
          jobclient.deleteJob(jobid);
        } catch (Exception e) {
          // ignore any exception
        }
      }
      requestJobDone();
    }
  }
  @Override
  public void solve() {
    if (requestJob() == null) {
      LOG.log(Level.INFO, "Job is already requested, ignoring...");
      return;
    }

    String jobid = null;
    JobExecutionStatus status = null;
    try {
      // create the request
      TruckingJobOutput updater = new TruckingJobOutput(this.mongoDB);
      JobRequest request =
          jobclient
              .newRequest()
              .input("model.mod", modFile)
              .input(new TruckingJobInput(this.mongoDB))
              .livelog(System.out)
              .output(updater)
              .timeout(5, TimeUnit.MINUTES)
              .build();
      updater.setRequest(request);

      // submit and get the job id
      Future<JobResponse> submit = executor.execute(request);
      jobid = request.getJobId();
      requestJobCreated(jobid);
      requestJobProcessed(jobid);

      StatusEventEndpoint.broadcastStatus(
          new RequestStatus(true, jobid, JobExecutionStatus.CREATED));
      LOG.info("Job submitted " + jobid);

      // wait for completion
      JobResponse response = submit.get();

      status = response.getJob().getExecutionStatus();

      switch (status) {
        case PROCESSED:
          break;
        case FAILED:
          // get failure message if defined
          String message = "";
          if (response.getJob().getFailureInfo() != null) {
            message = response.getJob().getFailureInfo().getMessage();
          }
          LOG.warning("Failed " + message);
          break;
        default:
          break;
      }

    } catch (Exception e) {
      LOG.log(Level.WARNING, "Error while executing job", e);
    } finally {
      // always cleanup the job by deleting it
      if (jobid != null) {
        try {
          jobclient.deleteJob(jobid);
        } catch (Exception e) {
          // ignore any exception
        }
      }
      requestJobDone();
      broadcastLatestSolution();
    }
  }