// assembleJob prepares for printing a job by fetching the job's printer, // ticket, and the job's PDF (what we're printing) // // The caller is responsible to remove the returned PDF file. // // Errors are returned as a string (last return value), for reporting // to GCP and local logging. func (pm *PrinterManager) assembleJob(job *lib.Job) (lib.Printer, cdd.CloudJobTicket, *os.File, string, cdd.PrintJobStateDiff) { printer, exists := pm.gcpPrintersByGCPID.Get(job.GCPPrinterID) if !exists { return lib.Printer{}, cdd.CloudJobTicket{}, nil, fmt.Sprintf("Failed to find GCP printer %s for job %s", job.GCPPrinterID, job.GCPJobID), cdd.PrintJobStateDiff{ State: cdd.JobState{ Type: "STOPPED", ServiceActionCause: &cdd.ServiceActionCause{ErrorCode: "PRINTER_DELETED"}, }, } } ticket, err := pm.gcp.Ticket(job.GCPJobID) if err != nil { return lib.Printer{}, cdd.CloudJobTicket{}, nil, fmt.Sprintf("Failed to get a ticket for job %s: %s", job.GCPJobID, err), cdd.PrintJobStateDiff{ State: cdd.JobState{ Type: "STOPPED", DeviceActionCause: &cdd.DeviceActionCause{ErrorCode: "INVALID_TICKET"}, }, } } pdfFile, err := cups.CreateTempFile() if err != nil { return lib.Printer{}, cdd.CloudJobTicket{}, nil, fmt.Sprintf("Failed to create a temporary file for job %s: %s", job.GCPJobID, err), cdd.PrintJobStateDiff{ State: cdd.JobState{ Type: "STOPPED", DeviceActionCause: &cdd.DeviceActionCause{ErrorCode: "OTHER"}, }, } } pm.downloadSemaphore.Acquire() t := time.Now() // Do not check err until semaphore is released and timer is stopped. err = pm.gcp.Download(pdfFile, job.FileURL) dt := time.Since(t) pm.downloadSemaphore.Release() if err != nil { // Clean up this temporary file so the caller doesn't need extra logic. os.Remove(pdfFile.Name()) return lib.Printer{}, cdd.CloudJobTicket{}, nil, fmt.Sprintf("Failed to download PDF for job %s: %s", job.GCPJobID, err), cdd.PrintJobStateDiff{ State: cdd.JobState{ Type: "STOPPED", DeviceActionCause: &cdd.DeviceActionCause{ErrorCode: "DOWNLOAD_FAILURE"}, }, } } glog.Infof("Downloaded job %s in %s", job.GCPJobID, dt.String()) pdfFile.Close() return printer, ticket, pdfFile, "", cdd.PrintJobStateDiff{} }
// assembleGCPJob prepares for printing a job by fetching the job's printer, // ticket, and data (what we're printing) // // The caller is responsible to remove the returned file. // // Errors are returned as a string (last return value), for reporting // to GCP and local logging. func (pm *PrinterManager) assembleGCPJob(job *gcp.Job) (string, *cdd.CloudJobTicket, string, string, cdd.PrintJobStateDiff) { _, exists := pm.gcpPrintersByGCPID.Get(job.GCPPrinterID) if !exists { return "", nil, "", fmt.Sprintf("Failed to find GCP printer %s for job %s", job.GCPPrinterID, job.GCPJobID), cdd.PrintJobStateDiff{ State: &cdd.JobState{ Type: cdd.JobStateAborted, ServiceActionCause: &cdd.ServiceActionCause{ErrorCode: cdd.ServiceActionCausePrinterDeleted}, }, } } ticket, err := pm.gcp.Ticket(job.GCPJobID) if err != nil { return "", nil, "", fmt.Sprintf("Failed to get a ticket for job %s: %s", job.GCPJobID, err), cdd.PrintJobStateDiff{ State: &cdd.JobState{ Type: cdd.JobStateAborted, DeviceActionCause: &cdd.DeviceActionCause{ErrorCode: cdd.DeviceActionCauseInvalidTicket}, }, } } file, err := cups.CreateTempFile() if err != nil { return "", nil, "", fmt.Sprintf("Failed to create a temporary file for job %s: %s", job.GCPJobID, err), cdd.PrintJobStateDiff{ State: &cdd.JobState{ Type: cdd.JobStateAborted, DeviceActionCause: &cdd.DeviceActionCause{ErrorCode: cdd.DeviceActionCauseOther}, }, } } pm.downloadSemaphore.Acquire() t := time.Now() // Do not check err until semaphore is released and timer is stopped. err = pm.gcp.Download(file, job.FileURL) dt := time.Since(t) pm.downloadSemaphore.Release() if err != nil { // Clean up this temporary file so the caller doesn't need extra logic. os.Remove(file.Name()) return "", nil, "", fmt.Sprintf("Failed to download data for job %s: %s", job.GCPJobID, err), cdd.PrintJobStateDiff{ State: &cdd.JobState{ Type: cdd.JobStateAborted, DeviceActionCause: &cdd.DeviceActionCause{ErrorCode: cdd.DeviceActionCauseDownloadFailure}, }, } } glog.Infof("Downloaded job %s in %s", job.GCPJobID, dt.String()) defer file.Close() return job.GCPPrinterID, ticket, file.Name(), "", cdd.PrintJobStateDiff{} }