Ignore:
Timestamp:
Jan 11, 2012, 3:13:30 PM (12 years ago)
Author:
Jessica B. Hamrick <jhamrick@…>
Branches:
no-cups
Children:
d21198f
Parents:
be6ff03
git-author:
Jessica B. Hamrick <jhamrick@…> (01/11/12 15:13:30)
git-committer:
Jessica B. Hamrick <jhamrick@…> (01/11/12 15:13:30)
Message:

Better threading model

File:
1 edited

Legend:

Unmodified
Added
Removed
  • server/lib/gutenbach/server/job.py

    rbe6ff03 reee389a  
    1 from . import InvalidJobException, InvalidPrinterStateException
     1from . import InvalidJobStateException, MissingDataException
     2from .player import Player
    23from gutenbach.ipp import JobStates as States
    34import os
    45import gutenbach.ipp as ipp
    56import logging
    6 import subprocess
    7 import time
    87
    98# initialize logger
     
    3433        self.name = name
    3534        self.size = size
    36         self.status = States.HELD
    37 
    38         self.document = None
     35        self.state = States.HELD
     36        self.priority = 1
     37
    3938        self.document_name = None
    4039        self.document_format = None
     
    4847        return "<Job %d '%s'>" % (self.id, self.name)
    4948
     49    def __cmp__(self, other):
     50        return cmp(self.priority, other.priority)
     51
    5052    ######################################################################
    5153    ###                          Properties                            ###
     
    98100
    99101        """
    100         if self.document:
    101             size = os.path.getsize(self.document.name)
    102         else:
    103             size = self._size
    104         return size
     102        return self._size
    105103    @size.setter
    106104    def size(self, val):
     
    110108            self._size = 0
    111109
     110    @property
     111    def is_playing(self):
     112        return self.state == States.PROCESSING
     113
     114    @property
     115    def is_ready(self):
     116        return self.state == States.PENDING
     117
     118    @property
     119    def is_finished(self):
     120        return self.state != States.PENDING and self.state != States.PROCESSING
     121       
    112122    ######################################################################
    113123    ###                            Methods                             ###
     
    115125
    116126    def play(self):
     127        """Non-blocking play function.
     128
     129        """
     130       
     131        # make sure the job is waiting to be played and that it's
     132        # valid
     133        if self.state != States.PENDING:
     134            raise InvalidJobStateException(self.state)
     135       
     136        # and set the state to processing if we're good to go
    117137        logger.info("playing job %s" % str(self))
    118         self.status = States.PROCESSING
    119         self.player = subprocess.Popen(
    120             "/usr/bin/mplayer -really-quiet -slave %s" % self.document.name,
    121             shell=True,
    122             stderr=subprocess.PIPE,
    123             stdout=subprocess.PIPE)
    124         while self.player.poll() is None:
    125             time.sleep(0.1)
    126         logger.info("mplayer finished with code %d" % self.player.returncode)
    127         stderr = self.player.stderr.read()
    128         stdout = self.player.stdout.read()
    129         if stderr.strip() != "":
    130             logger.error(stderr)
    131         logger.debug(stdout)
    132         self.player = None
    133         self.printer.complete_job(self.id)
    134 
    135     def finish(self):
    136         logger.info("finished job %s" % str(self))
    137         self.status = States.COMPLETE
     138        self.state = States.PROCESSING
     139        self.player.callback = self._completed
     140        self.player.run()
     141
     142    def pause(self):
     143        if self.player:
     144            self.player.mplayer_pause()
     145
     146    def stop(self):
     147        if self.player:
     148            self.player.callback = self._stopped
     149            self.player.mplayer_stop()
     150
     151    def _completed(self):
     152        if self.state != States.PROCESSING:
     153            raise InvalidJobStateException(self.state)
     154        logger.info("completed job %s" % str(self))
     155        self.state = States.COMPLETE
     156        self.player = None
     157
     158    def _canceled(self):
     159        if self.state != States.PROCESSING:
     160            raise InvalidJobStateException(self.state)
     161        logger.info("canceled job %s" % str(self))
     162        self.state = States.CANCELLED
     163        self.player = None
     164
     165    def _stopped(self):
     166        if self.state != States.PROCESSING:
     167            raise InvalidJobStateException(self.state)
     168        logger.info("stopped job %s" % str(self))
     169        self.state = States.STOPPED
     170        self.player = None
     171
     172    def _aborted(self):
     173        if self.state != States.PROCESSING:
     174            raise InvalidJobStateException(self.state)
     175        logger.info("aborted job %s" % str(self))
     176        self.state = States.ABORTED
     177        self.player = None
    138178
    139179    ######################################################################
     
    149189        return ipp.JobName(self.name)
    150190
    151     # XXX: we need to actually calculate this!
    152191    @property
    153192    def job_originating_user_name(self):
    154193        return ipp.JobOriginatingUserName(self.creator)
    155194
    156     # XXX: we need to actually calculate this!
    157195    @property
    158196    def job_k_octets(self):
     
    161199    @property
    162200    def job_state(self):
    163         return ipp.JobState(self.status)
     201        return ipp.JobState(self.state)
    164202
    165203    @property
     
    175213        pass
    176214
    177     def send_document(self,
    178                       document,
    179                       document_name=None,
    180                       document_format=None,
    181                       document_natural_language=None,
    182                       requesting_user_name=None,
    183                       compression=None,
     215    def send_document(self, document, document_name=None,
     216                      document_format=None, document_natural_language=None,
     217                      requesting_user_name=None, compression=None,
    184218                      last_document=None):
    185219
    186         if self.status != States.HELD:
    187             raise InvalidJobStateException(self.status)
    188        
    189         self.document = document
     220        if self.state != States.HELD:
     221            raise InvalidJobStateException(self.state)
     222
     223        self.player = Player(document)
     224
     225        if self.size == 0:
     226            self.size = os.path.getsize(document.name)
     227       
    190228        self.document_name = str(document_name)
    191229        self.document_format = str(document_format)
     
    193231        self.creator = str(requesting_user_name)
    194232        self.compression = str(compression)
    195         self.status = States.PENDING
     233        self.state = States.PENDING
    196234
    197235        logger.debug("document for job %d is '%s'" % (self.id, self.document_name))
Note: See TracChangeset for help on using the changeset viewer.