From: <we...@gi...> - 2001-03-07 17:02:16
|
Ben - The light print client design follows. -Wendy This is a high level architecture of the print client. I prefer to think of it as a light, rather than stupid, client. The main advantage of this client is that it requires zero configuration when used in conjunction with nameservice maps. Additionally, it uses zero resources when not in use. And, finally, it's KISS. In general, the print client takes in the command line, selects the appropriate over-the-wire protocol, builds a protocol specific job, opens the correct socket and sends the job to the socket using the selected protocol. There are two other tasks that it provides: retries and job data filtering. The filtering is provided to support client side filtering. We have found that there are times when this is needed. This has not been designed; I suspect the filters would be added to the output stream on the way off the client machine to the print server. The retry_daemon supports software retries due to temporary outages that are preventing printing. Thus the user may send the job and not wait for the completion, nor keep resending the job if the server is busy. We are working on the implementation as we speak. Much of the client and print library are completed. The interface to the data store modules is designed and implemented. The data store module for rfc1179 is currently being designed and implemented. lpr - the print client -------- read_command_line() if (printer_name == NULL) get_default_destination() job = initialize_job(NULL) add_job_attributes(job) for each document add_document_to_job(job) add_document_attributes(job) commit_job(job) return status print library ------------- The print library does the job of building generic (protocol neutral) jobs. The interfaces are used by the application to generate the jobs. Once the jobs have been built and sent on to be printed (commit_job()) by the application program, the library uses the configuration data to determine which protocol module to load to print the job. Thus, all protocol specifics are hidden from the client. I am only showing a couple of the more interesting routines in the print library. There are job, document, list, attribute, and name service routines as well. job = initialize_job() builds data structure for a job commit_job(job) load_dsi(job) /* * load_dsi() - This is where the protocol specific routine * handles are made available. All protocol specific routines * are accessed through the job->dsi structure. If the protocol * for this job is IPP, load_dsi() makes all the calls available * from the IPP data store * module. Thus, again considering * IPP, the commit_job() handle returned will reference the * commit_job() routine from the IPP data store module. * * The protocol is selected from a list of protocols that is an * attribute of a printer (or queue). Thus, the protocol list * may be: ipp, rfc1179, smb, ncp, retry ... load_dsi() selects * the first protocol in the list that the client supports and * uses it. The retry module could be a part of this list or a * separate attribute. */ /* Here we go off into the protocol specific routines */ if (job->dsi->commit_job(job) == retry_failure) start retry_daemon() return status retry_daemon ------------- The retry_daemon exists to retry sending jobs that encountered difficulty in the commit_job() routine. It continues to retry sending all jobs in the client spooling directory until all are sent; it sleeps between tries. Retries occurs due to "temporary" problems: print server is down; print server cannot take connection; ... The ability to do retries is an attribute settable by the print administrator as an attribute of the queue. It would be beneficial to allow the user or application to turn off retry using user/environment input. while (there are jobs in the client spool directory) for each job in spooler commit_job() if (check_spool_directory == empty) die else adjust_backoff_time Data Store Modules -------------------------- These modules exist to transform the jobs from generic to protocol specific and perform the various printing tasks. In the current design, generic-jobs would be mapped to rfc1179-jobs or IPP-jobs and then sent over the wire to the server using rfc1179 or IPP, respectively. Other protocols can be added if/when they appear. These modules are not part of the print library. commit_job() /* protocol specific commit_job */ Does whatever it needs to do to get the job ready to send over the wire and then sends it. As it is protocol specific it can tailor the jobs to suite the protocol. For example, order of sending the job, ie data or control file first, handshaking protocol, port to send to etc. Other routines in the data store modules are: store_job(), store_document() and commit_document(). This may not be the final list of functions. |