func (pm *PrinterManager) releaseJob(printerName string, nativeJobID uint32, jobID string) { if err := pm.native.ReleaseJob(printerName, nativeJobID); err != nil { log.ErrorJob(jobID, err) } }
// printJob prints a new job to a native printer, then polls the native job state // and updates the GCP/Privet job state. then returns when the job state is DONE // or ABORTED. // // All errors are reported and logged from inside this function. func (pm *PrinterManager) printJob(nativePrinterName, filename, title, user, jobID string, ticket *cdd.CloudJobTicket, updateJob func(string, *cdd.PrintJobStateDiff) error) { defer os.Remove(filename) if !pm.addInFlightJob(jobID) { // This print job was already received. We probably received it // again because the first instance is still QUEUED (ie not // IN_PROGRESS). That's OK, just throw away the second instance. return } defer pm.deleteInFlightJob(jobID) if !pm.jobFullUsername { user = strings.Split(user, "@")[0] } printer, exists := pm.printers.GetByNativeName(nativePrinterName) if !exists { pm.incrementJobsProcessed(false) state := cdd.PrintJobStateDiff{ State: &cdd.JobState{ Type: cdd.JobStateAborted, ServiceActionCause: &cdd.ServiceActionCause{ErrorCode: cdd.ServiceActionCausePrinterDeleted}, }, } if err := updateJob(jobID, &state); err != nil { log.ErrorJob(jobID, err) } return } nativeJobID, err := pm.native.Print(&printer, filename, title, user, jobID, ticket) if err != nil { pm.incrementJobsProcessed(false) log.ErrorJobf(jobID, "Failed to submit to native print system: %s", err) state := cdd.PrintJobStateDiff{ State: &cdd.JobState{ Type: cdd.JobStateAborted, DeviceActionCause: &cdd.DeviceActionCause{ErrorCode: cdd.DeviceActionCausePrintFailure}, }, } if err := updateJob(jobID, &state); err != nil { log.ErrorJob(jobID, err) } return } log.InfoJobf(jobID, "Submitted as native job %d", nativeJobID) var state cdd.PrintJobStateDiff ticker := time.NewTicker(time.Second) defer ticker.Stop() defer pm.releaseJob(printer.Name, nativeJobID, jobID) for _ = range ticker.C { nativeState, err := pm.native.GetJobState(printer.Name, nativeJobID) if err != nil { log.WarningJobf(jobID, "Failed to get state of native job %d: %s", nativeJobID, err) state = cdd.PrintJobStateDiff{ State: &cdd.JobState{ Type: cdd.JobStateAborted, DeviceActionCause: &cdd.DeviceActionCause{ErrorCode: cdd.DeviceActionCauseOther}, }, PagesPrinted: state.PagesPrinted, } if err := updateJob(jobID, &state); err != nil { log.ErrorJob(jobID, err) } pm.incrementJobsProcessed(false) return } if !reflect.DeepEqual(*nativeState, state) { state = *nativeState if err = updateJob(jobID, &state); err != nil { log.ErrorJob(jobID, err) } log.InfoJobf(jobID, "State: %s", state.State.Type) } if state.State.Type != cdd.JobStateInProgress && state.State.Type != cdd.JobStateStopped { if state.State.Type == cdd.JobStateDone { pm.incrementJobsProcessed(true) } else { pm.incrementJobsProcessed(false) } return } } }