55. Locking mechanisme in Brocade

55.1. Inleiding

Laat ons een situatie uit de praktijk schetsen: een Brocade gebruiker wenst om een of andere reden een authority code te schrappen. Hierbij wenst hij of zij van het computersysteem antwoorden op volgende vragen:

  • Wordt er naar deze authority code gelinkt in een of ander catalografisch record ?

  • Zijn er misschien eindgebruikers die verwijzen naar deze authority code ?

  • Zijn er misschien andere plaatsen in de databank die naar deze code verwijzen ?

Hoewel er in het verleden inspanningen zijn gebeurd om op het formulier een antwoord te geven, zoals bvb. automatisch onthouden in welke catalografische records authority codes worden gebruikt als onderwerpscodes, toch zijn hier hiaten als je als ontwikkelaar niet heel goed oplet: heb je er bijvoorbeeld aan gedacht dat authority codes wel eens in titels kunnen voorkomen ?

En eigenlijk wil je zo een geheugen niet alleen voor bepaalde loi types (a = authority records), gebruikt in records van bepaalde loi types (c = catalografische records), maar eigenlijk voor zo goed als alle zinnige combinaties.

Bovendien moet het zo zijn dat de inspanningen van de ontwikkelaar 'eenmalig' moeten zijn: het kan niet zijn dat er aparte software moet geschreven worden om loi records van type x af te scannen naar loi records van type y, telkens de x of de y een andere betekenis krijgt.

We zoeken dus naar een generiek locking mechanisme in Brocade, die toelaat om te onthouden welke loi objecten er door welke loi objecten worden gebruikt.

55.2. Definitie

Het locking mechanisme in Brocade (beschikbaar vanaf release 4.30) stelt drie pijlers ter beschikking:

  • Een uitbreiding van de definitie van het loi type dat een antwoord beschrijft op volgende vragen:

    • Hoe herken je loi identifiers van dit type in de databank ?

    • Waar in de databank vindt men de loi identifiers van dit type ?

    • Gegeven een loi identifier, waar staat de data behorend tot deze loi ?

    • Hoe is een loi identifier opgebouwd ?

    • Welke types loi identifiers wil men in deze records scannen en zoeken ?

  • Een middel dat toelaat om een gegeven loi record af te scannen naar loi identifiers, en dit onthoudt.

  • Een middel dat toelaat om snel te weten welke loi identifiers er voorkomen in een gegeven record.

  • Een middel dat toelaat om snel te weten in welke records een gegeven loi identifier voorkomt.

Important

Hetgeen het locking mechanisme niet is: een automatische blokkering van het schrappen van een record.

Het is uiteindelijk de ontwikkelaar die bovenstaande middelen ter beschikking krijgt, die beslist wat hij of zij hiermee gaat doen: het schrappen van een record blokkeren, informatie geven over de gelockte records, ...

55.3. Plan van aanpak

Het opstarten en inbouwen van het locking mechanisme in Brocade kan je verdelen in drie delen:

55.3.1. Deel 1: Voorbereiding: uitgebreide definitie van het loi type

Bij de definitie van een loi type zijn er een aantal essentiële meta-elementen die het locking proces gaan voeden. Het invullen hiervan is eenmalig werk en is in principe kant en klaar voor alle Brocade systemen. Het is ook de enige plaats waar hiervoor extra meta-informatie wordt bewaard.

Voor het herkennen van loi identifiers in de databank dienen volgende velden:

  • Scan patroon ($scanpat)

  • Toegelaten karakters in de loi ($scanacc)

Voor het bewaren van diverse crosslinks:

  • Reservoir voor de locks ($lockglobal)

Voor het terugvinden van de data:

  • Global referentie ($contgrf)

  • Global lister node ($globexe)

  • Samenstelling loi aan de hand van de global referentie ($globexe)

  • Initialisatie als gelockt item ($setexe)

  • Is het laatste deel van een loi een teller ? ($numeric)

  • Bepaling van het tijdstip van laatste wijziging ($mdexe)

Deze gegevens worden allemaal beschouwd als statisch : na elke wijziging hiervan dient in principe een herberekenening van de locking indexen te gebeuren.

55.3.2. Deel 2: Het (her)berekenen van de locking indexen

Dit kan gebeuren op verschillende manieren:

  • In batch, voor alle records van een gegeven loi type: voorbeeld : mutil -exe 'd %LockAll^gxblk("tg")'

    In dit voorbeeld worden alle indexen (her)berekend van het type tg .

  • In batch, voor alle records van alle mogelijke loi types: mutil -exe 'd %LockAll^gxblk("*")'

  • In batch, voor records, gewijzigd sinds een gegeven tijdstip: mutil -exe 'd %LockAll^gxblk("*",,,,$h-1_",")'

  • Op individuele basis, door volgende macro uit te voeren, of in te bouwen in de software:

    macro lockLoi($loi):
        '''
        $synopsis: (Her)indexeer de locks van een gegeven loi instance
        $loi: de loi instance
        $example: m4_lockLoi(RDcloi)
        '''
        «d %RX^gxblk($loi)»
    
  • Op individuele basis, maar uitgesteld, via de background verwerking:

    m4_setBackgroundTransaction(loi="c:lvd:27364", action="lock")

  • Automatisch, via het proces standard.locking, dat normalerwijze een maal per dag loopt: dit proces herberekent de locks van alle records, die sinds gisteren zijn gewijzigd, en herberekent gedurende een uur de locking indexen van alle records (er wordt gestart, waar de vorige dag is gestopt). Bij het berekenen van de 'gewijzigde' records moet evenwel de nodige meta informatie aanwezig zijn bij het loi type.

Hoewel het berekenen van de locking indexen vrij snel verloopt, kan het dus wel - afhankelijk van systeem en omvang - meerdere dagen duren vooraleer de locking indexen helemaal zijn herberekend.

55.3.3. Deel 3: Het testen van voorkomende lockings

Om informatie over de voorkomende lockings te bekomen, heeft de ontwikkelaar drie macro's ter zijner beschikking:

  • Om het aantal records te weten die door een gegeven loi gelockt worden (dit gebeurt op een zeer snelle wijze):

    macro getLocksCount($return, $loic):
        '''
        $synopsis: bepaal hoeveel lois een gegeven loi locken
        $return: return variabele. bevat het aantal
        $loic: de gegeven loi, die lockt
        $example: m4_getLocksCount(cnt,"a::920.19")
        '''
        «s $return=$$%GetLC^gxblk($loic)»
    
  • Om de locks op te sporen, gelockt door een gegeven loi record:

    macro getLocks($array, $loi, $gather=0):
        '''
        $synopsis: geef de lois op, die een gegeven loi momenteel lockt.
        $array: naam van de return array. Deze is van de vorm (gebruikte loi)=[set waartoe loi behoort]. Deze wordt voorafgaandelijk gekilled.
        $loi: loi id, die de lois lockt
        $gather: Optioneel. 0=de gefilede locks, 1=de berekende locks uit de loi data
        $example: m4_getLocks(RAlocks,RDcloi)
        $example: m4_getLocks(RAlocks,RDcloi,gather=1)
        '''
        «d:'$gather %GetL^gxblk(.$array,$loi) d:$gather %Gather^gxblk(.$array,$loi)»
    
  • Om het aantal records te weten die een gegeven loi locken (dit gebeurt op een zeer snelle wijze):

    macro getLocksByCount($return, $loic, $array=0):
        '''
        $synopsis: bepaal hoeveel lois door een gegeven loi gelockt worden. Dit is een *snelle* operatie.
        $return: return variabele. bevat het aantal
        $loic: de gegeven loi, die wordt gelockt
        $array: Optioneel. Return array. Bevat de aantallen per set. Is van de vorm $array(set)=aantal
        $example: m4_getLocksByCount(cnt,"a::920.19")
        $example: m4_getLocksByCount(cnt,"a::920.19",RAcnt)
        '''
        «s $return=$$%GetUBC^gxblk($loic)»
            if «$array isEqualTo "0"»
        «s $return=$$%GetUBC^gxblk($loic,.$array)»
    
  • Om de records op te sporen die een gegeven loi locken:

    macro getLocksBy($gref, $loic, $set, $max):
        '''
        $synopsis: bepaal de lois, die een gegeven loi locken
        $gref: referentie, die de lois zal bevatten in het subscript.Deze wordt voorafgaandelijk *niet* gekilled. Ze is van de vorm @$gref@(gelockte loi)=set, waartoe gelockte loi behoort.
        $loic: de gegeven loi, die wordt gelockt
        $set: Optioneel. Beperk je locks tot bepaalde sets (gescheiden door ,)
        $max: Optioneel. Maximum aantal terug te geven lois.
        $example: m4_getLocksBy(RGdead,"a::920.19")
        $example: k RAtmp m4_getLocksBy("RAtmp","a::920.19")
        $example: k RAtmp m4_getLocksBy("RAtmp","a::920.12:1.1")
        $example: k RAtmp m4_getLocksBy("RAtmp","a::920.19","c:lvd")
        $example: k RAtmp m4_getLocksBy("RAtmp","a::920.19",max=1000)
        '''
        «s MDa=$na(@$gref) d %GetUB^gxblk(MDa,$loic,$set,$max)»
    

Het is aan de ontwikkelaar om deze macro's op te roepen op de plaatsen waar ze nuttig geacht worden.