title: Python/perl print server; writing print job to file
body: <p>I'm working on trying to get a print server running using this: <a href="http://newcenturycomputers.net/projects/rawprintserver.html" rel="nofollow">http://newcenturycomputers.net/projects/rawprintserver.html</a></p>
  
  <p>I've modified spooler.py to write to a file and everything is working OK save for one issue: the job seems to take a <em>long</em> time considering what is being printed... </p>
  
  <p>The job gets received and it chugs along for a solid minute before actually finishing. This seems like an excessively long time for a 1kb txt file with the word 'test' in it... </p>
  
  <p>It exhibits the same behavior whether using Windows or Mac, so it's not an OS thing... </p>
  
  <p>This is the modified def in spooler.py</p>
  
  <pre><code>class printer(base_printer):
      def sendjob(self, fp, title = None):
          # title is irrelevant here
          print "Begin sendjob def..."
          out = open('/tmp/printserv/outs/' + str(time.time()).split('.')[0]+".txt", 'w')
          blk = fp.read(8192)
          while blk:
              out.write(blk)
              print "Block written..."
              blk = fp.read(8192)
              print "while loop done..."
          rc = out.close()
          if rc is not None:
              print "Error: lpr returns %02x" % rc
          else:
              print "OK DONE"
  </code></pre>
  
  <p>This is the main print handler class (from printserver.py) that handles the job:</p>
  
  <pre><code>class print_handler(asyncore.dispatcher):
  
      def __init__(self, conn, addr, server, jobnumber):
          asyncore.dispatcher.__init__(self, sock = conn)
          self.addr = addr
          self.server = server
          self.jobname = JOBNAME % jobnumber
          self.fp = open(self.jobname, "wb")
          print "Receiving Job from %s for Printer &lt;%s&gt; (Spool File %s)" \
              % (addr, self.server.printer.printer_name, self.jobname)
  
      def handle_read(self):
          data = self.recv(8192)
          print "Starting handle_read"
          if self.fp:
              print "begin self.fp.write..."
              self.fp.write(data)
              print "end self.fp.write.."
  
      def writable(self):
          print "Writable return 0"
          return 0
  
      def handle_write(self):
          print "handle_write pass"
          pass
  
      def handle_close(self):
          print "Printer &lt;%s&gt;: Printing Job %s" \
              % (self.server.printer.printer_name, self.jobname)
          if self.fp:
              self.fp.close()
              self.fp = None
          fp = open(self.jobname, "rb")
          self.server.printer.sendjob(fp)
          fp.close()
          try:
              os.remove(self.jobname)
          except:
              print "Can't Remove &lt;%s&gt;" % self.jobname
          self.close()
  </code></pre>
  
  <p>and the mainloop def (also in printserver.py):</p>
  
  <pre><code>def mainloop(config):
  
      if config["spooldir"]:
          os.chdir(config["spooldir"])
  
      for i in range(len(config["printer"])):
          args = string.split(config["printer"][i], ",", maxsplit = 1)
          prn = args[1].strip()
          port = int(args[0].strip())
          p = print_server('',
              port, spooler.printer(prn))
          servers.append(p)
  
      try:
          try:
              asyncore.loop(timeout = 1.0)
          except KeyboardInterrupt:
              pass
      finally:
          print "Print Server Exit"
  </code></pre>
  
  <p>those <code>print</code>'s get logged in a logfile which looks like this:</p>
  
  <blockquote>
  <pre><code>[2012/04/26 10:39:58] Raw Print Server Startup: PID = 15695
  [2012/04/26 10:39:58] Starting Printer &lt;lpr&gt; on port 515
  [2012/04/26 10:40:01] Receiving Job from ('1.2.3.4', 55070) for Printer &lt;lpr&gt; (Spool File RawPrintJob00001.prn)
  [2012/04/26 10:40:01] Writable return 0
  [2012/04/26 10:40:01] Starting handle_read
  [2012/04/26 10:40:01] begin self.fp.write...
  [2012/04/26 10:40:01] end self.fp.write..
  [2012/04/26 10:40:01] Writable return 0
  [2012/04/26 10:40:02] Writable return 0
  [2012/04/26 10:40:03] Writable return 0
  [2012/04/26 10:40:04] Writable return 0
                   [[SNIP]]
  [2012/04/26 10:41:39] Writable return 0
  [2012/04/26 10:41:40] Writable return 0
  [2012/04/26 10:41:41] Writable return 0
  [2012/04/26 10:41:42] Starting handle_read
  [2012/04/26 10:41:42] begin self.fp.write...
  [2012/04/26 10:41:42] end self.fp.write..
  [2012/04/26 10:41:42] Writable return 0
  [2012/04/26 10:41:42] Printer &lt;lpr&gt;: Printing Job RawPrintJob00001.prn
  [2012/04/26 10:41:42] Begin sendjob def...
  [2012/04/26 10:41:42] Block written...
  [2012/04/26 10:41:42] done writing blocks...
  [2012/04/26 10:41:42] OK DONE
  [2012/04/26 10:41:42] Starting handle_read
  </code></pre>
  </blockquote>
  
  <p>at this point, the job is finished and the file has been written. Nothing else gets logged until the next job comes in. As you can see, this took over 1.5 minutes to complete.</p>
  
  <p>My question is: how could it possibly take almost 2 minutes to handle a 1k file? This is all local on gigabit LAN so it must be something with the way the code is handling the job... One thing I have noticed is that the printed jobs seem to have a lot of trailing whitespace. Could it be that it is looking for an EOF or something and eventually just timing out?</p>
  
  <p>Any pointers appreciated</p>