ArmClientHandler

Der ArmClientHandler repräsentiert den eigentlichen generischen Teil der Performance Instrumentierung auf Seiten des Clients. Mit diesem soll es möglich sein, alle Stränge der Axis Clientseite zu instrumentieren. Zur Realisierung dieses Handlers müssen einige Kriterien beim Entwurf berücksichtigt werden. Damit eine Messung korrekt ist, muss es zu jedem start einer ARM Transaktion auch ein stop geben. Der stop Aufruf erfolgt allerdings in einer ganz anderen Instanz des Handlers als der start Aufruf. Somit ist es notwendig, in Java das Transaction Objekt und in C++ das Transaction Handle weiter zu reichen. Dies erfolgt über die Propertys im MessageContext. Damit die Möglichkeit besteht, mehrere Handler diese Typs in Axis einzuklinken, kann man nicht einfach das Transaction Object bzw. das Transaction Handle in den Propertys ablegen. Es wäre dann auf dem Rückweg nicht mehr feststellbar, welches Handle zu welcher Transaktion gehört. Man muss allerdings für korrekte Messungen die Reihenfolge reproduzieren können. Da die Handler im response flow in umgekehrter Reihenfolge wieder aufgerufen werden sollen als im request flow, bietet sich die Verwendung eines Stacks an. Dieser wird im request flow mit Transaction Objekten bzw. mit Transaction Handles aufgebaut und auf dem Rückweg wieder abgebaut. Die Notwendigkeit, einer ARM Transaction einen eindeutigen Namen geben zu müssen, macht ebenfalls die Verwendung eines Stacks attraktiv. Der Name kann als Teil die Größe des Stack enthalten. Die Eindeutigkeit des Transaktionsnamens ist damit ebenso gewährleistet. Das ist die Namensgebung, die per default verwendet wird. Ebenso ist es natürlich möglich, im Deployment Descriptor Transaktionsname und Applikationsname zu vergeben. Dabei kann es natürlich bei inkorrekter Nutzung dieses Feature dazu kommen, dass der Transaktionsname nicht mehr eindeutig ist, was wiederum auch zu falschen Messergebnissen führt. Ein weiteres wichtiges Entwurfskriterium ist das Erzeugen einer ARM Applikation innerhalb eines Handlers. Eine bzw. meherere ARM Transaktionen müssen immer innerhalb einer ARM Applikation laufen. Eine ARM Applikation erzeugt man normalerweise für jeden Prozess, nicht unbedingt mehrere Applikationen innerhalb eines Prozesses. Das heißt für den Entwurf des Handlers, dass dieser, wenn er zum ersten mal aufgerufen wird, eine neue ARM Applikation erzeugt und wenn er das letzte mal im response flow aufgerufen wird, diese auch wieder stoppt und zerstört. Wenn der Handler aufgerufen wird, prüft er, ob schon eine Instanz die ARM Applikation erzeugt hat, indem er in den Propertys nachschaut, ob dort schon ein Application Objekt (Java) oder eine applicationId (C++) liegt. Sind diese vorhanden, muss er nur eine neue ARM Transaktion erstellen und diese starten. Sind diese nicht vorhanden, muss er diese erzeugen. Das bedeutet, dass dies der erste aufgerufene Handler ist. Um festzustellen ob der Handler der letzte aufgerufene im response flow ist, macht man sich wieder das Konzept des Stacks zunutze. Wenn auf dem Stack keine Elemente mehr liegen, bedeutet das für den Handler, dass er die ARM Applikation stoppen und im Falle von C++ auch zerstören kann, da keine Transaktionen mehr vorliegen. Der ARM Correlator wird bei diesem Handler lediglich als Property des MessageContext übertragen.
Thomas Termin 2005-02-24