сервер печати Python/perl; запись задания на печать в файл

Я работаю над запуском сервера печати, используя это: http://newCenturycomputers.net/projects/rawprintserver.html

Я изменил spooler.py для записи в файл, и все работает нормально, за исключением одной проблемы: задание, кажется, занимает долго время, учитывая то, что печатается...

Работа получена, и она пыхтит целую минуту, прежде чем на самом деле закончить. Кажется, это слишком много времени для текстового файла размером 1 КБ со словом «тест» в нем...

Он демонстрирует одинаковое поведение при использовании Windows или Mac, так что это не проблема ОС...

Это измененное определение в spooler.py.

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"

Это основной класс обработчика печати (из printserver.py), который обрабатывает задание:

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 <%s> (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 <%s>: 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 <%s>" % self.jobname
        self.close()

и определение основного цикла (также в printserver.py):

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"

эти print регистрируются в файле журнала, который выглядит следующим образом:

[2012/04/26 10:39:58] Raw Print Server Startup: PID = 15695
[2012/04/26 10:39:58] Starting Printer <lpr> on port 515
[2012/04/26 10:40:01] Receiving Job from ('1.2.3.4', 55070) for Printer <lpr> (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 <lpr>: 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

на данный момент работа закончена и файл записан. Больше ничего не регистрируется, пока не появится следующее задание. Как видите, это заняло более 1,5 минут.

Мой вопрос: как это могло занять почти 2 минуты для обработки файла размером 1 КБ? Это все локально в гигабитной локальной сети, поэтому это должно быть что-то с тем, как код обрабатывает задание... Одна вещь, которую я заметил, это то, что напечатанные задания, похоже, имеют много пробелов в конце. Может быть, он ищет EOF или что-то еще и в конечном итоге просто истекает?

Любые указатели приветствуются


person stormdrain    schedule 26.04.2012    source источник


Ответы (1)


Это оказалось проблемой с тем, как принтер был настроен на клиенте. Он был установлен на lpr вместо RAW.

По стечению обстоятельств я наткнулся на perl-скрипт, который будет делать то же самое, что и py-скрипт (вроде). Со сценарием perl для достижения той же цели требуется гораздо меньше кода (для меня эта цель состоит в том, чтобы просто поймать поток и записать в файл; rps более многословен, чем мне нужно).

Здесь:

#!/usr/bin/perl 
use IO::Socket::INET;
use POSIX qw(strftime);
$print_time = strftime "%Y%m%d-%H_%M_%S", localtime; 
$myport=515; 
$pserve=IO::Socket::INET->new(LocalPort => $myport,Type=>SOCK_STREAM,Reuse=>1,Listen=>1) or die "Socket error: $!\n"; 
while ($pjob=$pserve->accept()) {
    open(J,">>/tmp/printserv/outs/".$print_time.".txt") or print "File open error: $!\n"; 
    while (<$pjob>) { 
        print J "$_"; 
    } 
    close J; 
    close $pjob;
    print  "DONE..."; 
}
person stormdrain    schedule 26.04.2012