E.5.3 Klassen zur Verwaltung der Speicher und der Auftraege (c_joblist, c_orgalists)

# -------------------------------------------------------------
# Projekt : Digitale Bibliotheken Projekt
# Uni-Frankfurt/M, Professur Telematik und
# verteilte Systeme, Prof. O. Drobnik
# Diplomarbeit, Matzen,Hans, 1997
# Dateiname :
# Datum : 03.11.1997
# letzte Änderung :
# Autor : Hans Matzen, 1997, Frankfurt/M, Deutschland
# Sprache : Python v1.4
# Beschreibung : Hier werden zwei Klassen definiert, die
# die Verwaltung der angemeldeten Speicher und
# der laufenden Auftraege uebernehmen
# Anmerkungen :
#
# -------------------------------------------------------------
 
 
# -------------------------------------------------------------
# Klasse zur Verwaltung der beim Broker angemeldeten Speicher
# Dabei wird zu jedem Speicher eine laufende Nummer, der Name
# des Speichers, die Adresse fuer zu sendende Auftraege
# (host,port) und der Zustand des Speichers gespeichert.
# -------------------------------------------------------------
class c_replist:
 
    #
    # Konstruktor
    #
    def __init__(self):
        # Variablen initialisieren
        self.count=0
        self.repdict={}
        self.IDLE="idle"
        self.BUSY="busy"
        self.PAUSED="paused"
 
        # Eintrag in repdict:
        # ( lfdnr, repname, hostname, port, state)
 
    #
    # fuegt einen neuen Speicher mit Namen name, der unter
    # host, port auf Auftraege wartet in die Liste ein.
    # Gibt die laufende Nummer innerhalb der Liste zurueck
    #
    def addrep(self,name,host,port):
        self.count=self.count+1
        self.repdict[self.count]=(self.count,name,host,port,self.IDLE)
        return self.count
 
    #
    # loescht den Speicher mit laufender Nummer repnr aus
    # der Liste
    #
    def removerep(self,repnr):
        if self.repdict.has_key(repnr):
            del self.repdict[repnr]
            return repnr
        else:
            return -1
 
    #
    # liefert die Nummer eines Speichers zurueck, der momentan keinen
    # Auftrag verarbeitet und setzt den Zustand des Speichers auf busy
    #
    def get_idlerep(self):
        i=0
        erg=(-1,"","",-1,-1)
        while i<=self.count:
            if self.repdict.has_key(i):
                nr,n,h,p,s=self.repdict[i]
                 
                if s==self.IDLE:
                    erg=(nr,n,h,p,s)
                    del self.repdict[i]
                    self.repdict[i]=(nr,n,h,p,self.BUSY)
                    i=len(self.repdict)+1
            i=i+1
        return erg
 
    #
    # setzt den Zustand des Speichers mit der laufenden
    # Nummer repnr auf idle
    #
    def set_idle(self,repnr):
        if self.repdict.has_key(repnr):
            nr,n,h,p,s=self.repdict[repnr]
            del self.repdict[repnr]
            self.repdict[nr]=(nr,n,h,p,self.IDLE)
            return repnr
        else:
            return -1
 
    #
    # setzt den Zustand des Speichers mit der laufenden
    # Nummer repnr auf angehalten
    #
    def set_paused(self,repnr):
        if self.repdict.has_key(repnr):
            nr,n,h,p,s=self.repdict[repnr]
            del self.repdict[repnr]
            self.repdict[nr]=(nr,n,h,p,self.PAUSED)
            return repnr
        else:
            return -1
 
    #
    # gibt eine Liste alle in der Liste befindlichen
    # Speicher zurueck
    #
    def get_replist(self):
        return self.repdict
 
    #
    # sucht den Speicher mit Namen nam und gibt die repnr
    # zurueck
    #
    def get_repbyname(self,nam):
        for i in self.repdict.keys():
            if self.repdict[i][1]==nam:
                return self.repdict[i][0]
        return -1
 
 
 
# imports fuer c_joblist
import string
# -------------------------------------------------------------
# Klasse zur Verwaltung der offenen Auftraege.
# Die Groesse der Liste muß bei der Instanziierung mit angegeben
# werden, wenn sie nicht 50 sein soll.
# Die Klasse ermoeglicht die Zurordnung der Auftraege zu den
# bearbeitenden oder auftraggebenden Instanzen ueber Sockets
# -------------------------------------------------------------
class c_joblist:
    #
    # Konstruktor
    #
    def __init__(self,maxjobs=50):
        # initialisiere leere Listen und Dictionaries
        self.maxjobs=maxjobs
        self.ifdict={}
        self.repdict={}
        self.repnrdict={}
        #
        # e = empty, u =used
        #
        self.slots ="X"+ "e" * maxjobs
        #
        # e=empty, c=connected, w=waiting for reply, f=failed, d=disconnected
        #
        self.ifstates ="X"+ "e" * maxjobs
        self.repstates ="X"+ "e" * maxjobs
        # clearing fd dictionaries
        for i in range(1,maxjobs+1):
            self.ifdict[i] = -1
            self.repdict[i] = -1
            self.repnrdict[i] = -1
 
        self.count=0
         
    #
    # fueht einen neuen Auftrag ein
    # if_fd - Fildeskriptor des Sockets der Schnittstellenkomponente
    # ifstate - unbenutzt
    # repnr - laufende Nummer des Speichers aus der Speicherliste
    # rep_fd - Fildeskriptor des Sockets des Speichers der den
    # Auftrag ausfuehrt
    # repstate- Zustand des Speichers
    #
    # Bei Fehler wird -1 zurueckgegeben, sonst die Auftragsnummer
    #
    def addjob(self,if_fd,ifstate,repnr,rep_fd=-1,repstate=""):
        self.count=self.count+1
        if self.count>self.maxjobs:
            self.count=self.maxjobs
            return -1
        else:
            jnr=string.find(self.slots,"e")
            self.slots=self.slots[:jnr]+"u"+self.slots[jnr+1:]
 
            self.ifdict[jnr]=if_fd
            self.repdict[jnr]=rep_fd
            self.ifstates=self.ifstates[:jnr]+ifstate+self.ifstates[jnr+1:]
            self.repstates=self.repstates[:jnr]+repstate+self.repstates[jnr+1:]
            self.repnrdict[jnr]=repnr
            return jnr
 
    #
    # setzt den Zustand der Schnittstellenkomponente, der der Auftrag jobnr
    # zugeordnet ist auf newstate (for debugging only)
    #
    def set_ifstate(self,jobnr,newstate):
        self.ifstates=self.ifstates[:jobnr]+newstate+self.ifstates[jobnr+1:]
        return 0
 
    #
    # setzt den Zustand des Speichers, dem der Auftrag jobnr
    # zugeordnet ist auf newstate
    #
    def set_repstate(self,jobnr,newstate):
        self.repstates=self.repstates[:jobnr]+newstate+self.repstates[jobnr+1:]
        return 0
 
    #
    # loescht den Auftrag mit Nummer jobnr aus der Liste
    #
    def remjob(self,jobnr):
        self.slots=self.slots[:jobnr]+"e"+self.slots[jobnr+1:]
 
    #
    # Ermittelt den Auftrag, der der Verbindung mit Filedeskriptor
    # if_fd zugeordnet ist und gibt die Nummer des Auftrags zurueck.
    #
    def get_job_by_iffd(self,if_fd):
        erg=-1
        for i in self.ifdict.keys():
            if self.ifdict[i]==if_fd:
                erg=i
        return erg
 
    #
    # Ermittelt den Auftrag, der der Verbindung mit Filedeskriptor
    # rep_fd zugeordnet ist und gibt die Nummer des Auftrags zurueck.
    #
    def get_job_by_repfd(self,rep_fd):
        erg=-1
        for i in self.repdict.keys():
            if self.repdict[i]==rep_fd:
                erg=i
        return erg
         
    #
    # gibt ein dictionary zurueck das alle relevanten Auftragsdaten
    # beinhaltet.
    #
    def get_joblist(self):
        i=0
        ergdict={}
        for i in range(1,self.maxjobs+1):
            ergdict[i]=(self.slots[i],self.ifdict[i],self.ifstates[i],self.repdict[i],self.repstates[i],self.repnrdict[jobnr])
        return ergdict
 
    #
    # gibt ein Dictionary zurueck, das alle laufenden Auftraege beinhaltet
    # in der Queue befindliche oder gestoppte Auftraege werden nicht
    # beruecksichtigt
    #
    def get_runningjobs(self):
        i=0
        ergdict={}
        for i in range(1,self.maxjobs+1):
            if self.slots[i]!="e":
                ergdict[i]=(self.ifdict[i],self.ifstates[i],self.repdict[i],self.repstates[i])
        return ergdict
 
    #
    # gibt zu einer gegebenen jobnr alle relevanten Informationen
    # zurueck
    #
    def get_jobdata(self,jobnr):
        return (jobnr,self.slots[jobnr],self.ifdict[jobnr],self.ifstates[jobnr],self.repdict[jobnr],self.repstates[jobnr],self.repnrdict[jobnr])