• Ei tuloksia

5. HINTAPALVELIMEN TOTEUTUS

6.2. Parannusehdotuksia

Jos haluaisimme hintapalvelimen toteutuksenkin täyttävän kaikki mainitut seitsemän peruskriteeriä, pitäisi myös puuttuvat tiedon puskurointi ja palveluhakemisto toteuttaa. Näistä puskuroinnin merkitys kasvaisi, jos järjestelmä siirrettäisiin ympäristöön, joka sisältää hitaita tietoliikenneyhteyksiä. Jos puskuroinnissa käytettäisiin esimerkiksi LRU-sivunkorvausalgoritmia harvoin käytettyjen tietojen korvaamiseen muistin täyttymistapauksissa, olisi puskurimuistin toteuttaminen hyvinkin yksinkertaista.

Itse asiassa hintapalvelimen tapauksessa puskurimuistin täyttyminen olisi hyvinkin harvinaista johtuen noteerattavien instrumenttien kohtuullisen pienestä määrästä. Näin ollen jokainen kysytty tieto löytyisi hyvin todennäköisesti aina puskurimuistista, jos sitä on kysytty tai tilattu kerrankin aikaisemmin.

Toisaalta puskurimuistin toteuttamiseen on myöskin tarjolla useita valmiita ratkaisuja tai työkaluja, jolloin vaatimuksen täyttäminen kävisi entistäkin helpommaksi.

Palveluhakemiston toteuttaminenkaan ei vaatisi erityisen vaikeiden ongelmien ratkaisemista.

Palvelujen sijaintiläpinäkymättömyys voitaisiin toteuttaa rakentamalla palvelin, johon hintapalvelin- API ottaisi yhteyttä RPC-kutsulla aina tilausta aloitettaessa tai kyselyä tehtäessä. Palvelin palauttaisi niiden hintapalvelimien osoitteet, joita tarvittaisiin tämän kyselyn tai tilauksen toteuttamiseen. Tämän tiedon palveluhakemisto saisi hintapalvelimilta Publish-toiminnossa. Tiedon saatuaan hintapalvelin- API suorittaisi tilaukset tai kyselyt näiltä osoitteiden tarkoittamilta hintapalvelimilta. Tämän jälkeen kaikki kyseiseen tilaukseen tai kyselyyn liittyvä tapahtuisi hintapalvelimen ja hintapalvelin-API:n (siis asiakasohjelman) välillä. Kaikki tämä toiminnallisuus olisi piilotettu hintapalvelin-API:n ja palveluhakemiston sisälle, jolloin sijaintiläpinäkyvyys asiakasohjelman kannalta toteutuisi. Ainoastaan siinä tapauksessa, jolloin rinnakkaiset hintapalvelimet palvelisivat osittain samoja tietoja, saattaisi

palveluhakemistolla olla useita mahdollisia vastauksia samaan kysymykseen. Silloin palveluhakemisto voisi palauttaa niiden palvelimien osoitteet, jotka ovat vähiten kuormitettuja. Näin palveluhakemisto voisi tasata kuormaa eri palvelimien välillä. Jos jonkin palvelimen ja asiakasohjelman välinen yhteys vikaantuisi, voisi hintapalvelin-API kysyä automaattisesti uudestaan palveluhakemistolta haluttua hyödykettä palvelevan palvelimen osoitteen ja jatkaa yhteyttä sen kanssa. Vain siinä tapauksessa, että kyseistä palvelua ei löydy miltään toimivalta palvelimelta, välitetään asiakasohjelmalle tieto palvelun vikaantumisesta. Näin vikasietoisuuta voitaisiin lisätä monimutkaistamatta asiakasohjelmien toimintaa.

Myös palveluhakemistoja voisi käynnistää useita rinnakkain. Näiden palveluhakemistojen osoitteet olisivat asiakasohjelmien luettavissa niiden käynnistyessä. Hintapalvelin-API:n sisään olisi piilotettu toiminto, jossa yritetään saada yhteys peräkkäin eri palveluhakemistoihin, kunnes jokin niistä vastaa.

/.YHTEENVETO

Kun tarkastelemme hintapalvelimen toteutusta, havaitsemme useiden määrittelyissä olleiden ominaisuuksien puuttuvan järjestelmän toteutusvaiheesta. Ne jätettiin toteuttamatta työn teettäjän päätöksestä ja päätöksen syynä oli lähinnä ajanpuute. Toisin sanoen yrityksen muiden ATK- hankkeiden toteutusta pidettiin sillä hetkellä kiireellisempänä, ja puuttuvien ominaisuuksien lopullinen toteutus siirrettiin tuonnemmaksi. Työn edistyessä huomattiin kuitenkin esitettyjen perusvaatimusten toteuttamisen olevan suhteellisen yksinkertaista. Ominaisuuksien toteuttamiseen vaadittujen valmiiden algoritmien ja työkalujen melko suuri määrä aiheuttaa sen, että toteutusvaihe on hyvin suoraviivainen ja aikataulujen kannalta hyvin ennalta arvioitavissa. Oman ratkaisun määritteleminen ja toteutus antoi hyvää lisäapua saatavilla olevien valmiiden ratkaisujen arviointiin. Samalla parannusehdotusten pohtiminen toi esiin lisäkysymyksiä, joita ei kuitenkaan työn rajaamiseksi käsitelty.

Jos yritämme löytää syitä siihen, miksi valitsisimme ongelman ratkaisuksi valmiin järjestelmän, silmiinpistävin ominaisuus valmiissa järjestelmissä oli niiden monet vikasietoisuutta parantavat ominaisuudet. Useita näitä ominaisuuksia ei vertailua tehtäessä erikseen mainittu. Kaikkien näiden ominaisuuksien tuominen itse tehtyyn järjestelmään olisi todennäköisesti melko työlästä. Valmiita järjestelmiä käytettäessä joudutaan ehkä tinkimään joistain esitetyistä vaatimuksista vikasietoisuuden hyväksi. Toisin sanoen valmiit ratkaisut eivät koskaan ole määrittelemämme ihanneratkaisun mukaisia.

Valmiin ihanneratkaisun rakentaminen vaatisi toteuttajakseen resursseiltaan huomattavasti vahvemman tekijän. Käytännön ratkaisuihin riittävän hyviä järjestelmiä on kuitenkin markkinoilla saatavana, kuten luvussa kolme esitetty katselmus osoittaa.

Hintapalvelin otettiin käyttöön ensimmäisenä rakennettaessa SOM:n reaaliaikaista vakuuslaskenta- ja valvontajärjestelmää. Tämän järjestelmän toteutus oli hyvin yksinkertainen ja suoraviivainen, koska ohjelman vaatiman tiedonjakelun ongelmia ei jouduttu erikseen ratkaisemaan ohjelmaa rakennettaessa.

Järjestelmä on vastuussa vain vastaanotetun tiedon käsittelystä ja esittämisestä. Järjestelmällä kyetään laskemaan jokaisen SOM:ssa kauppaa käyvän asiakkaan tiliaseman vakuusvaatimus käytännössä reaaliajassa ottaen huomioon kaikki tiliaseman arvoon vaikuttavat markkinatiedot. Samalla voidaan seurata vakuudeksi asetetun omaisuuden arvoa myös reaaliajassa. Järjestelmällä voidaan seurata näiden tietojen suhdetta toisiinsa ja vastaanottaa hälytyksiä mahdollisista tilanteista, joissa asiakkaalla on laskennan perusteeksi asetettujen sääntöjen mukaan vakuusvajaus. Näin mahdollisiin toimenpiteisiin voidaan ryhtyä välittömästi tilanteen syntyessä. Tilanteen nopeasta havaitsemisesta on hyötyä kummallekin osapuolelle eli markkinapaikalle (SOM) ja tiliaseman omistajalle. Tiliaseman omistajalle rahallinen hyöty tästä nopeasta havaitsemisesta saattaa olla hyvinkin suuri, koska näin voidaan estää

tiliaseman turha sulkeminen eli tappioiden realisoiminen. Riippuen markkinatilanteesta, tämä nopea tappioiden realisoiminen saattaa olla sijoittajalle hyvinkin kohtalokasta.

Hintapalvelimen osana syntynyttä Multicast-kirjastoa hyödynnettiin myös sijoittajille kehitetyn analyysi- ja hinnanseurantaohjelmiston tiedonvälityksessä. Kirjaston käyttöönotto mahdollisti myös ohjelman käytön internetin välityksellä. Samalla toteutettiin tietääksemme ensimmäinen reaaliaikaisen pörssitiedon elektronisella kolikkorahalla maksettava välitysjärjestelmä. Siinä sijoittaja maksaa seuraamastaan hintatiedosta viidentoista minuutin välein pienen maksun tietokoneessaan olevalla eletronisella kukkarolla.

LÄHDELUETTELO

[1] Andrews G.R. Concurrent Programming-Principles and Practice, Benjamin/Cummings, 1991

[2] Black, Fisher, Scholes. The Pricing of Options and Corporate Liabilities, Journal of Political Economy, touko - kesäkuu 1973, volyymi 81, s. 637-659

[3] Bloomer J. Power Programming with RPC, O’Reilly & Associates Inc., 1992, s. 11

[4] Brandom S. An Introduction to the OpenTrade API, Management Technologies Inc., 1996, (URL: http://www.mtits.co.uk/)

[5] Hoare C.A.R. Monitors, An Operating System Structuring Concept, Commun. Of the ACM, 1974, s. 549-557

[6] HP-UX Release 10.20, Hewlett-Packard Company, kesäkuu 1996, (URL: http://www.hp.com/)

[7] Invision: Technical Overview (Version 2.1), Quay Financial Software Limited, 1994, (URL: http://www.csksoftware.com/)

[8] Leffler, McKusick, Karels, Quarterman. The Design and Implementation of the 4.3 BSD UNIX Operating System, Addison Wesley, 1989

[9] Madura J. Financial Markets and Institutions, West Publishing Company, 1989, s. 4

[10] Microsoft Windows for Workgroups Resource Kit, Microsoft Corporation, 1992, s. 11.3-11.25, (URL:

http://www.microsoft.com/)

[11] OpenTrade Platform, Management Technologies Inc, 1995, (URL: http://www.mtits.co.uk/)

[12] Reuters White Paper Series: Reuters SSL 4.0, Reuters, 1996, (URL: http://www.reuters.com/)

[13] Software product description: Reliable Transaction Router Version 3.1B for UNIX, Digital Equipment Corporation, 1996, (URL: http://www.digital.com/)

[14] Tanenbaum, A.S. Modern operating systems, Prentice-Hall International Editions, 1992

[15] Tibco White Papers: Rendezvous Information Bus, Tibco Inc., 1996, (URL: http://www.rv.tibco.com/)

[16] Valtionvarainmisteriön työryhmämuistioita: Sijoituspalvelutyöryhmän muistio, Valtiovarainministeriö, 1994, s. 2-3, (URL: http://www.vn.fi/vm/)

LIITE A. MONITOR SENDBUFFER

Lähetyspuskurin käsittelyn havainnollistamiseksi sen esittämisessä käytetään monitoria [5]. Sitä ei käytetä tässä tapauksessa lainkaan ohjelman oikeellisuuden todistamiseen. Monitori sisältää proseduureja, muuttujia ja tietorakenteita. Sen tärkein ominaisuus on se, että se voi olla vain yhden prosessin tai säikeen hallussa kerrallaan. Toisin sanoen eri prosessit eivät voi olla suorittamassa monitorin proseduureja yhtä aikaa. Tästä poikkeuksena mni-kutsu, jonka parametrina annettua ehtoa jäädään odottamaan ja samalla vapautetaan monitori toisten prosessien käyttöön. Kun vra/i-kutsusta palataan, monitori on taas kyseisen prosessin hallussa. Ehdon mahdollisesta voimaantulosta kerrotaan signal- ja signalAll-kutsuilla. S/gna/-kutsulla herätetään yksi kyseistä ehtoa odottavista ja signalAll- kutsulla kaikki. Signal- ja SignalAll-kutsut eivät vielä vapauta monitoria, vaan se vapautuu vasta monitori-proseduurin loppuessa. Herätetyt säikeet kilpailevat monitorista sen vapautuessa.

Monitoria esitettäessä käytetään Andrewsm notaatiota [1]. Siinä if-lauseen syntaksi on seuraava:

if bx -> st П ...

[] bn -> s„

fi

Jos useampi kuin yksi if-lauseen ehdoista B¡ on tosi, suoritettava käsky S¡ valitaan epädeterminisesti.

Jos mikään ehdoista ei ole tosi, suoritetaan skip, eli tyhjä komento. Toistolauseen syntaksi on seuraava:

do Bt -> Sí

П ...

[] BN -> SN od

Toistoa jatketaan niin kauan kun vähintään yksi ehdoista B¡ on tosi. Jos useampi kuin yksi ehdoista on tosi, suoritettava käsky S¡ valitaan epädeterminisesti.

Monitor SendBuffer

/* N = lähettäjäsäikeitten määrä */

/* n = kiertävän sanomapuskurin koko var buf[l:n] : DataT

finishstarted : bool := FALSE;

/* lähetettävät sanomat */

/* montako kopiota lähettämättä */

/* säikeen seuraava viesti */

/* viestien kokonaismäärä */

notFull : cond; notEmpty : cond; Empty : cond

/* kirjoittaa viestin lähetyspuskuriin */

procedure AddMessage (msg : DataT; var out status Status!) if -ifinishstarted ->

do count = N -> wait (notFull) od buf[rear] := msg; tosend[rear] = N

rear := (rear mod n) + 1; count ;= count + 1

/* lopettaa lähetyspuskurin toiminnan */

procedure Finish ()

/* lukee viestin lähetyspuskurista */

procedure GetMessage (msgout : DataT; SenderNo : int) do -ifinish A count = 0 -> wait (notEmpty) od

if -ifinish ->

if front[SenderNo] <> rear ->

msgout := buf[front[SenderNo]]

tosend[front[SenderNo]] := tosend[front[SenderNo]] - 1 if tosend[front[SenderNo]] = 0 -> count := count - 1; fi front[SenderNo] := (front[SenderNo] mod n) + 1

fi

if count = 0 -> signalAll (Empty); fi if count < n -> signalAll (notFull); fi [] finish -> msgout : = EMPTY ;

fi end

end

Lähetyspuskurin käyttö Multicast kirjastossa

Multicast-kirjaston funktiot käyttävät monitoria Sendbuffer seuraavalla tavalla:

Proseduuri Sender on yhtä linjaa palveleva säie, joka lukee viestejä lähetyspuskurista ja kirjoittaa niitä linjalleen. Se jatkaa toimintaansa kunnes lähetyspuskurin toiminta lopetetaan.

procedure Sender (SenderNo : int) var msg : DataT

Proseduurilla Mclnit aloitetaan Multicast-kirjaston toiminta. Se käynnistää lähetyspuskuria lukevat Sender- toiminnot. Todellisuudessa kukin Sender-Xoxmmto käynnistetään silloin, kun tietoa vastaanottava asiakasohjelma ottaa yhteyden. Toimintaa on tässä yksinkertaistettu esityksen selventämiseksi.

Proseduurilla McSend kirjoitetaan viesti lähetyspuskuriin. Kaikki Sender-toiminnot havaitsevat lähetyspuskuriin kirjoitetun viestin ja lähettävät sen linjalleen. Jos toiminto onnistuu, muuttujan status arvo AddMessage-kuism jälkeen on OK. Jos toiminto epäonnistuu, muuttujan status arvo on FAILURE.

procedure McSend (msg : DataT; var out status Status!) SendBuffer.AddMessage (msg, status)

end

Proseduuri McClose lopettaa lähetyspuskurin toiminnan.

procedure McClose () SendBuffer.Finish () end

LIITE В. HINTAPALVELIN API

Tässä liitteessä kuvataan tarkemmin Hintapalvelin API:n toiminta ja syntaksi. Kunkin funktion kohdalla esitellään ensin sen C-kielinen syntaksi, jonka jälkeen kerrotaan tarkemmin sen toiminnasta.

Funktioiden nimien kaksi ensimmäistä kirjainta tulevat sanoista Price Info.

void *PIConnect (char *server, int port)

Lähettää yhteyspyynnön hintapalvelimen ‘server’ portille numero ‘port’. Toiminto palauttaa tyypittömän osoitteen, jota käytetään muissa Pinfo-kutsurajapinnan palveluissa. PIConnect varaa tämän osoittimen osoittaman muistialueen kutsujan muistiavaruudesta yhteyteen liittyviä toimintoja varten.

Alue vapautetaan PIDisconnect-kutsussa. Tätä osoitinta kutsutaan myöhemmin yhteystunnisteeksi. Jos yhteyden muodostaminen ei onnistu, niin toiminto palauttaa nolla-osoittimen. Jokaista onnistunutta yhteyspyyntöä vastaa yksi looginen socket-yhteys. Kaikki muut kutsut koskevat kerrallaan yhtä tällaista socÅei-yhteyttä. Toiminnossa luodaan socket ja luodaan sen avulla yhteys palvelimen porttiin.

Palvelin palauttaa yhteystunnisteen yleiseen esitysmuotoon muutettuna. Toiminto muuttaa palautetun yhteystunnisteen vastaanottavan koneen sisäiseen muotoon ja palauttaa kutsujalle tämän muunnetun yhteystunnisteen. Näihin esitysmuotojen välisiin muutoksiin käytetään SUN-RPC:n tarjoamaa XDR- kirjastoa.

int PISubscribe (void *vpic, char *item, elinktype ltype)

Tilaa yhteystunnisteen vpic’ tarkoittamalta palvelimelta hyödykkeen ‘item’ tulevat ‘ejinkjype’- tyyppiset hintamuutokset. ‘e link type ’ voi saada toistaiseksi arvot: bid, ask, last. Nämä tarkoittavat hyödykkeen parasta ostotarjousta, parasta myyntitarjousta ja viimeistä kauppahintaa. Toiminto palauttaa onnistumispalautteen, joka voi saada arvot: SUBSCRIBE_FÁILURE - tilaus epäonnistui, SUBSCRIBE STARTED- tilaus onnistui ja ensimmäinen arvo on tulossa, SUBSCRIBE_FETCHING - tilaus onnistui, mutta arvo joudutaan hakemaan, koska sitä ei löytynyt palvelimen muistipuskurista.

Ensimmäisen arvon saapuminen viivästyy. Jos haku toiselta palvelimelta ei onnistunut, ensimmäisessä viestissä kerrotaan, että tilaus epäonnistui. Viestien muunnoksiin käytetään XDR-kirjastoa, kuten edellisessä.

int PIPatternSubscribe (void *vpic, char *item, e link type ltype)

Suorittaa samat toimenpiteet kuin toiminto PISubscribe, mutta ‘item ’ on säännöllinen lauseke ja kaikki tämän säännöllisen lausekkeen hyväksymät hyödyketunnukset tilataan. Säännöllisenä lausekkeena käytetään regexp, h:n [6] määrittelemää syntaksia.

int PlUnsubscribe (void *vpic, char *item, elinktype ltype)

Lopettaa ‘item ’ hyödykkeen hintamuutosten tilauksen vpic ’:n tarkoittamalta palvelimelta. Jo matkalla olevat viestit saapuvat vielä luettavaksi ja viimeisenä saapuu tilauksen lopetusviesti, jonka jälkeen tästä tilauksesta ei ole enää odotettavissa uusia viestejä.

int PIPatternUnsubscribe (void *vpic, char *item, e link type ltype)

Suorittaa samat toimenpiteet kuin toiminto PlUnsubscribe, mutta ‘item ’ on säännöllinen lauseke ja kaikki tämän säännöllisen lausekkeen hyväksymien hyödyketunnusten tilaus lopetetaan.

int PIDisconnect (void *vpic)

Katkaisee yhteyden hintapalvelimeen koskien yhteystunnistetta ‘vpic Vielä matkalla olevat viestit saapuvat perille, jonka jälkeen yhteys katkeaa. Yhteyden katkeaminen havaitaan socket yhteyden katkeamisena. Katkaisun jälkeen yhteystunniste ‘vpic ’ on käyttökelvoton ja tällä yhteystunnisteella tehtävät muut toiminnot epäonnistuvat.

void PIReadLoop (void *vpic, void (*receive_func)0, void *clientp)

Kuuntelee ‘vpic ’ yhteystunnisteen tarkoittamaa yhteyttä ja kutsuu jokaisen viestin saavuttua kutsussa annettua ‘receive June ’-proseduuria antaen sille parametriksi kutsussa annetun ‘clientp ’-osoittimen, ja osoittimen viestiin. Toiminto pyörii ikuisessa silmukassa, josta poistutaan vain yhteyden katketessa tai virhetilanteessa.

pinfo result t *PIRead (void *vpic)

Lukee yksittäisen viestin ‘vpic ’ yhteystunnisteen tarkoittamasta yhteydestä. Toiminto odottaa, kunnes uusi viesti on luettavissa, yhteys katkeaa tai syntyy virhetilanne. Toiminto palauttaa osoitteen muistiin, johon uusi viesti on tallennettu. Jos yhteys katkeaa tai syntyy virhetilanne, toiminto palauttaa

nollaosoittimen. Kun saapunut viesti on luettu, voidaan toimintoa kutsua uudelleen seuraavaa viestiä varten. Palautetun muistialueen vapauttaminen on kutsujan vastuulla. Tähän suositellaan käytettäväksi PIResultFree-kutsua.

pinfo result t *PIGet (void *vpic, char *item, e link type ltype)

Kysyy yhteystunnisteen ‘vpic ' tarkoittamalta palvelimelta hyödykkeen ‘item ’ ‘ejinktype ’-tyyppisen viimeisen noteerauksen. Toiminto ei liity mihinkään tilaukseen. Palautetun muistialueen vapauttaminen on kutsujan vastuulla. Tähän suositellaan käytettäväksi PIResultFree-kutsua.

PIResultFree (pinfo_result_t *result)

Vapauttaa ‘result’-osoittimen osoittaman muistialueen. Tarkoitettu käytettäväksi toimintojen ‘PIRead’

ja ‘PIGet’ jälkeen, kun niiden palauttama viesti on luettu. Vapauttaa myöskin ‘result '-osoittimen osoittaman muistialueen sisällä olevien osoittimien osoittamat muistialueet.

int PISocket (void *vpic)

Palauttaa vpic '-yhteystunnisteen tarkoittaman yhteyden käyttämän loogisen yhteyden socket- tunnisteen. Tätä arvoa voidaan käyttää esimerkiksi haluttaessa tehdä asynkronista I/O:ta käyttäen hyväksi socÄei-kirjaston se/eci-kutsua.

"OULU1

;UAXi'0,