<?xml version="1.0"?>
<?xml-stylesheet href="scheduler.xsl" type="text/xsl"?>

<!--$Id: dynamic_configuration.xml 5854 2008-08-14 08:22:14Z jz $-->

<description
    title               = "Konfiguration aus Hot Folders"
    base_dir            = ""
    parent_page         = "index.xml"
    author              = "$Author: jz $"
    date                = "$Date: 2008-08-14 10:22:14 +0200 (Do, 14 Aug 2008) $"
>
    <p>
        Jobs, Job-Ketten, Daueraufträge, Prozessklassen und Sperren (im folgenden Objekte genannt)
        können in einzelnen Dateien gehalten werden, die der Job Scheduler automatisch nach Änderung übernimmt.
        Der Job Scheduler überwacht Verzeichnisse (<em>Hot Folders</em>), für die hinzugefügte,
        geänderte und gelöschte Dateien als entsprechende Operationen zum Hinzufügen, Ändern
        und Entfernen von Jobs, Job-Ketten etc. ausgeführt werden. 
    </p>
    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->

    <scheduler_table_of_content/>

    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->

    <h2>Konfigurationsverzeichnis</h2>
    
    <p>
        Die Dateien liest der Job Scheduler aus dem Konfigurationsvereichnis und dessen Unterverzeichnissen.
        Das Konfigurationsverzeichnis kann eingestellt werden mit
    </p>
    <ul>
        <li>
            <scheduler_element name="config" attribute="configuration_directory"/>,
            voreingestellt ist das Verzeichnis <code>./config/live</code> im Verzeichnis der Konfigurationsdatei.
        </li>
        <li>
            <scheduler_option name="config"/>. 
            Die Konfigurationsdatei erwartet der Scheduler dann im Konfigurationsverzeichnis (Voreinstellung <code>./config</code>)
            unter dem Namen <code>scheduler.xml</code>.
        </li>
    </ul>
    
    <p>
        Der Job Scheduler überwacht das Konfigurationsverzeichnis und seine Unterverzeichnisse
        und übernimmt hinzugefügte und geänderte Dateien.
        Löschen einer Datei führt zum Löschen des entsprechenden Objekts im Job Scheduler.
    </p>

    <p>
        Unter Windows verwendet der Job Scheduler die Verzeichnisüberwachung des Betriebsystems, 
        bemerkt Änderungen also sofort.
        Außerdem prüft er die Verzeichnisse im Minutenabstand.
    </p>
    <p>
        Unter Unix überwacht der Job Scheduler die Verzeichnisse im Abstand von zwischen 5 und 60 Sekunden.
        Nach einer Änderung verkürzt er den Abstand auf fünf Sekunden und 
        verlängert ihn, wenn keine Änderung vorliegt, bis auf 60 Sekunden.
    </p>

    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->

    <a name="files"/>
    <h2>Dateien für Prozessklassen, Sperren, Jobs, Job-Ketten und Daueraufträge</h2>

    <p style="margin-bottom: 1em;">
        Die Dateien enthalten die XML-Elemente für die Definition des Objekts und werden
        aufgrund folgender Namenskonventionen verarbeitet:       
    </p>
    <table cellspacing="0" cellpadding="0">
        <tr>
            <th style="padding-right: 2ex">
                Objekt
            </th>
            <th style="padding-right: 2ex">
                Dateiname
            </th>
            <th style="padding-right: 2ex">
                XML-Element
            </th>
        </tr>
        <tr>
            <td style="padding-right: 2ex">
                Prozessklasse
            </td>
            <td style="padding-right: 2ex">
                <code><i>name</i>.process_class.xml</code>
            </td>
            <td style="padding-right: 2ex">
                <scheduler_element name="process_class"/>
            </td>
        </tr>
        <tr>
            <td style="padding-right: 2ex">
                Sperre
            </td>
            <td>
                <code><i>name</i>.lock.xml</code>
            </td>
            <td style="padding-right: 2ex">
                <scheduler_element name="lock"/>
            </td>
        </tr>
        <tr>
            <td style="padding-right: 2ex">
                Job
            </td>
            <td style="padding-right: 2ex">
                <code><i>name</i>.job.xml</code>
            </td>
            <td style="padding-right: 2ex">
                <scheduler_element name="job"/>
            </td>
        </tr>
        <tr>
            <td style="padding-right: 2ex">
                Job-Kette
            </td>
            <td style="padding-right: 2ex">
                <code><i>name</i>.job_chain.xml</code>
            </td>
            <td style="padding-right: 2ex">
                <scheduler_element name="job_chain"/>
            </td>
        </tr>
        <tr>
            <td style="padding-right: 2ex">
                Dauerauftrag
            </td>
            <td style="padding-right: 2ex">
                <code><i>jobchainname</i>,<i>orderid</i>.order.xml</code>
            </td>
            <td style="padding-right: 2ex">
                <scheduler_element name="order"/>
            </td>
        </tr>
    </table>

    <p>
        Das Attribut <code>name=</code> 
        <!--(oder <code>job_chain=</code> und <code>id=</code> bei Aufträgen)-->
        sollte nicht angegeben werden.
        Wird es angegeben, muss es dem Dateinamen entsprechen.
    </p>
    <p>
        Die Attribute <code>replace=</code> und <code>spooler_id=</code> sind nicht zulässsig.
    </p>

    <br/><br/>

    <br/><u>Beispiel eines Jobs (auftragsgesteuert): Datei <code>hello_world.job.xml</code>:</u><br/>
    <pre>&lt;job order="yes"&gt;
    &lt;script language="shell"&gt;&lt;![CDATA[
      echo hello world
    ]]&gt;&lt;/script&gt;
&lt;/job&gt;</pre>

    <br/><u>Beispiel einer Job-Kette: Datei <code>echo_hello.job_chain.xml</code>:</u><br/>
    <pre>&lt;job_chain&gt;
    &lt;job_chain_node  state="<i>start</i>" job="<i>hello_world</i>" next_state="<i>success</i>" error_state="<i>error</i>"/>
    &lt;job_chain_node  state="<i>success</i>"/>
    &lt;job_chain_node  state="<i>error</i>"/>
&lt;/job_chain&gt;</pre>

    <br/><u>Beispiel eines Auftrags: Datei <code>echo_hello,echo_trigger.order.xml</code>:</u><br/>
    <pre>&lt;order&gt;
    &lt;run_time&gt;
      &lt;period repeat="3600"/&gt;
    &lt;/run_time&gt;
&lt;/order&gt;</pre>

    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
    
    <h2>Spiegelung des Verzeichnisses im Job Scheduler</h2>

    <p>
        Der Job Scheduler legt für jede Datei mit bekannter Dateinamensendung (<code>.job</code> usw.)
        ein entsprechendes Objekt im Job Scheduler an und verbindet es mit der Datei.
        Der Job Scheduler überwacht den Zeitstempel der Datei und geht bei Änderung wie folgt vor.
    </p>
    
    <ul class="big">
        <li>
            Ein hinzugefügter Dateiname führt zur Anlage eines neuen, noch leeren Objekts im Job Scheduler,
            das mit der Datei verbunden ist.
            Das Objekt ist mit <scheduler_element name="show_state"/> sichtbar.
            Z.B. wird eine Datei <code>xxx.job.xml</code> im Job Scheduler gespiegelt als ein Job
            <scheduler_element name="job" attribute="name" value="xxx"/>,
            auch wenn die Datei nicht lesbar ist.
        </li>
        <li>
            Eine gelöschte Datei führt zum Löschen des Objekts.
            Das Löschen wird in der Regel verzögert, 
            weil z.B. bei einem Job das Ende der Tasks abgewartet werden muss.
        </li>
        <li>
            Wenn während des Löschens die Datei wieder angelegt wird,
            geht der Job Scheduler wie bei einer geänderten Datei vor.
        </li>
        <li>
            Nach einer Änderung einer Datei (der Zeitstempel hat sich geändert) liest der Job Scheduler die Datei.
            Kann die Datei geladen werden, 
            dann tauscht er Prozessklassen und Sperren direkt,
            während er Jobs, Job-Klassen und Daueraufträge verzögert tauscht,
            weil noch die laufenden Operationen des zu ersetzenden Objekts abgewartet werden müssen (Details unten).
        </li>
        <li>
            Ein Fehler beim Lesen einer Datei beeinflusst nicht ein bereits vorhandenes Objekt.
            Der Job Scheduler vermerkt den Fehler im Objekt und verschickt eine eMail.
            <scheduler_element name="show_state"/> zeigt den Fehler.
        </li>
        <li>
            Objekte mit denselben (Datei)Namen können mehrfach in unterschiedlichen Verzeichnissen
            vorhanden sein. Der Job Scheduler unterscheidet diese Objekte anhand ihres Pfads.
            Wenn auf Objekte aus anderen Verzeichnissen verwiesen wird, z.B.
            <pre>&lt;job  process_class="<i>/my_project/multi.process_class.xml</i>"/&gt;</pre>
            <pre>&lt;job_chain_node  job="<i>/other_project/hello_world</i>"/&gt;</pre>
            dann müssen absolute oder relative Pfade angegeben werden.
        </li>
    </ul>

    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->

    <h2>Wirkung der Kommandos zum Ändern und Löschen</h2>

    <p>
        Kommandos zum Ändern von Objekten ändern nicht die Dateien.
    </p>
    <p>
        Kommandos zum Löschen von Objekten löschen die zugrundliegende Datei
        (die Debug-Version des Schedulers versieht den Dateinamen mit dem Anhängsel "<code>-REMOVED</code>").
    </p>

    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->

    <h2>Verhalten der einzelnen Objekttypen</h2>

    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->

    <h3>Prozessklassen</h3>

    <p>
        Änderungen an einer Prozessklasse übernimmt der Job Scheduler sofort.
    </p>
    <p>
        Beim Löschen einer Prozessklasse beendet der Job Scheduler alle zugehörigen Tasks.
        Erst wenn keine Task mehr läuft, löscht er die Prozessklasse.
        Bis dahin startet der Job Scheduler keine weiteren Tasks, uns verhält sich als ob die Prozessklasse erschöpft wäre.
    </p>

    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->

    <h3>Sperren</h3>

    <p>
        Änderungen an einer Sperre übernimmt der Job Scheduler sofort.
    </p>
    <p>
        Beim Löschen einer Sperre beendet der Job Scheduler alle zugehörigen Tasks.
        Erst wenn keine Task mehr läuft, löscht er die Sperre.
        Bis dahin startet der Job Scheduler keine weiteren Tasks, und verhält sich als ob die Sperre belegt wäre.
    </p>

    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->

    <h3>Jobs</h3>

    <p>
        Einen geänderten Job übernimmt der Job Scheduler, nachdem er alle Tasks beendet hat.
    </p>
    <p>
        Beim Löschen verfährt der Job Scheduler ebenso.
        Keine neue Tasks werden gestartet.
    </p>
    <p>
        Fehlt dem Job die Prozessklasse oder eine Sperre, wirkt das so, 
        als ob die Prozessklasse erschöpft oder die Sperre nicht verfügbar wäre.
    </p>

    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->

    <h3>Job-Ketten</h3>

    <p>
        Eine geänderte Job-Kette übernimmt der Job Scheduler, nachdem alle Aufträge ihren Job-Schritt beendet haben.
        Weitere Job-Schritte werden solange verhindert.
    </p>
    <p>
        Aufträge in Job-Kettenknoten mit gleichem Auftragszustand übernimmt der Job Scheduler in die geänderte Job-Kette.
    </p>
    <p>
        Beim Löschen verfährt der Job Scheduler ebenso.
    </p>
    <p>
        Fehlt der Job-Kette ein Job, dann sammeln sich die Aufträge im Job-Kettenknoten,
        als wäre der Job nicht zur Auftragsausführung bereit.
    </p>

    <h3>Verschachtelte Job-Ketten</h3>
    <p>
        Fehlt der Job-Kette eine verschachtelte Job-Kette <scheduler_element name="job_chain_node.job_chain"/>,
        dann ist die gesamte Job-Kette nicht bereit.
        Alle untergeordneten Job-Ketten müssen bekannt sein, 
        damit der Job Scheduler die Eindeutigkeit der Auftragskennungen sicherstellen kann.
    </p>
    <p>
        Ebenso wird eine untergeordnete Job-Kette erst gelöscht,
        wenn auch die übergeordnete Job-Kette gelöscht ist.
    </p>
    

    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->

    <h3>Daueraufträge</h3>
    <p>
        Daueraufträge werden anders behandelt als die anderen Objekte.
        Zum einen haben sie einen zusammengesetzten Namen (<code>job_chain=</code> und <code>id=</code> statt <code>name=</code>),
        zum anderen werden Dateiänderungen nicht jederzeit beachtet.
        Eine gelöschte oder geänderte Auftragsdatei wird nur beachtet,
        wenn 
    </p>
    <ul>
        <li>
            der Auftrag nicht bekannt,
        </li>
        <li>
            der Auftrag noch nicht gestartet worden oder
        </li>
        <li>
            der Auftrag wegen <scheduler_element name="run_time"/> wiederholt, aber noch nicht gestartet worden ist.
        </li>
    </ul>

    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->

    <h2>Kommando &lt;show_state></h2>

    <p>
        Das Kommando liefert zu jedem dateibasiertem Objekt ein
        <scheduler_element directory="xml/answer/" name="file_based"/> mit Angaben zur Datei.
    </p>
    <p>
        Wenn eine Ersetzung im Gang ist, zeigt <scheduler_element directory="xml/answer/" name="replacement"/> dies an.
    </p>
    <p>
        Wenn eine Datei gelöscht ist, aber das dazugehörige Objekt noch nicht,
        wird <scheduler_element directory="xml/answer/" name="removed"/> geliefert.
    </p>

    <!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->

</description>
