Er Event-Driven Architecture noget rod?

En af de udfordringer, der kan følge med udvikling af et beskedsbaseret, event-drevet system er, at det kan føles sværere at holde overblikket over, hvad der sker – og hvornår.

Der introduceres en del ny “indirection”, hvilket påvirker os på to måder:

  • Psykologisk: Hvis jeg deler min kode op i meget mindre, mere adskildte dele, og hvor interaktion udføres asynkront, hvordan ved jeg, at alt udføres som jeg ønsker det?
  • Udvikling: Hvordan beholder jeg overblikket over min kode?

Et eksempel er brugeroprettelse. Lad os sige, at der ved brugeroprettelse er følgende krav til hvad der skal ske, når en bruger opretter sig: (1) en mail skal sendes til den nye bruger, (2) en mail skal sendes til admins, (3) brugeren skal tildeles adgang til udvalgte systemressourcer, (4) der skal sendes et brev med posten.

I en traditionel løsning kunne man forestille sig at der ville være en CreateNewUser()-metode, som udfører de forskellige handlinger igennem kald til andre metoder / services (hvor services her er klasser i andre namespaces / projekter, eller på andre web services). Men dette ikke en tilgang uden problemer (læs “Hvorfor er synkron integration så problematisk?” her).

I en EDA-løsning ville man lave en CreateNewUser()-metode, der opretter en bruger via  domænemodellen, der så publicerer et UserCreatedEvent – og denne metode gør kun dette. UserCreatedEvent ville et antal services være abonnenter på, og i dem vil et antal message handlers, i dette tilfælde 4 i alt, reagere på dette event og udføre de handlinger, som skal ske på baggrund af UserCreatedEvent.

Den psykologiske udfordring

Hvis du er vant til at arbejde med metodekald, der udfører mange forskellige ting under samme transaktion, så har du ganske sikkert opbygget en følelse af kontrol, der udfordres med EDA. Du kan se fra ende til anden i dine metoder (eller følge eksekveringen ned igennem metodehierarkiet), og alt udføres korrekt eller transaktionen ruller tilbage ved fejl.

Dette virker sikkert som et catch-all svar – men at implementere EDA uden frygt handler i høj grad om at have tillid til infratrukturen. Med web services er vi vant til at den er oppe eller nede, at den gennemfører eller ej – dog uden egentlig at tænke så meget over, hvad vi så egentlig skal gøre, når den er nede eller ikke gennemfører (hvilket håndtering af kan blive noget rod). Men det føles mere ligetil at forstå.

Med et beskedsbaseret system er tingene lidt anderledes: Hvis en besked ikke når frem til modtageren (system nede), gemmes den i en fejlkø – og kan trækkes ind igen til afsendelse når modtagersystemet igen er oppe – eller gemmes i servicens indkø (service nede). Det samme gælder hvis en message handler ikke kan gennemføre sit arbejde (error) – beskeden havner i en fejlkø, og kan afprøves igen senere. Udfaldsrummene bliver flere end blot gik godt / gik ikke godt, men den positive side af dette er, at det så kan ende med, at antallet af virklig fatale fejl mindskes – det er blot et spørgsmål om tid, før en fejlslagen processering kan afprøves igen. Og det er godt for forretningen!

Med andre ord: måske giver man slip på en mere alt-eller-intet orienteret tilgang, hvilket kan føles ubehageligt, men man erstatter den faktisk med en tilgang, hvor man bl.a. er bedre stillet når der opstår fejl (der er sågar flere fordele!).

Dertil kommer, at en EDA-løsning kan give mere overblik inden for den enkelte service – da de autonome SOA services bliver mere specialiserede. Hvis din service har til ansvar at håndtere brugerprofiler, ja, så gør den det og gør det godt. Det er overskueligt. Hvad der sker i andre services på baggrund af det UserCreatedEvent, der udsendes fra denne service er mindre interessant. Det løses “et andet sted”.

Udvikling

Men hvordan beholder man overblikket i en løsning, der indeholder mange event-definitioner – og mange message handlers?

En ting jeg gjorde tidligere var, at at lægge mange message handlers i en klynge, baseret på en eller anden kontekst. Dvs. vi havde eksempelvis en AdminEmailHandler klasse, som håndterede alle udsendelser af mails til admins.

AdminEmailHandler

AdminEmailHandler, oprindelig definition

Dette gav dog en ulempe, når man ville søge i løsningen og få overblik over hvad der skete, ved UserCreatedEvent (Find Usages).

Søgeresultat

Find Usages Søgeresultat

Ovenstående giver jo ikke det bedste overblik (Hvad sker der egenetlig i AdminEmailHandler ved UserCreatedEvent?).

Mit forslag er at du overvejer én handler pr. klasse – og navngiv klassen ud fra hvad handleren gør – hvad dens formål er. Søgeresultatet vil så se sådan ud:

Nyt søgeresultat

Nyt søgeresultat

I det nye søgeresultat bliver overblikket meget bedre. Det er ret let at se, at når UserCreatedEvent publiceres, så sendes der en mailnotifikation til admin. Og det bliver kun bedre, når der er mange handlers til samme event (vel at mærke hvis de findes i samme VS solution).  Det understøtter også hensigten om, at message handlers kan / bør være enheder, der kan deployes separat.

Opsamling

Brug af EDA ændrer væsentligt ved den måde, vi udvikler systemer på. Baseret på mine egne erfaringer vil jeg til enhver tid tage ulemperne / mistilliden ved den “indirection”, der følger med, da den opvejes mange gange med forhøjet tillid til, at systemet består – med en (acceptabel) forsinkelse i forbindelse med problemer, i stedet for fejl.

PS. UserCreatedEvent er i øvrigt, i retrospekt, en mindre god navngivning, der læner sig meget op ad CRUD handlinger. Kan være i orden, afhængig af konteksten, men man kunne måske finde et bedre navn…

Christer Ø. on twitterChrister Ø. on linkedin
Christer Ø.
Software Development Consultant stratal ApS
Christer Østergaard er freelance forretningsanalytiker og softwarearkitekt med mere end 16 års erfaring. Har arbejdet med STAR (tidl. Arbejdsmarkedsstyrelsen), DSB, Kommunernes Landsforening, Digitaliseringsstyrelsen, Egmont, Banedanmark, Elsparefonden, Armada Shipping, Unik HR, Fødevareministeriet og Ministeriet for Flygtninge, Indvandrere og Integration, Knowledge Cube, mikz.com, Ankestyrelsen m.fl. Dertil et par Open Source projekter. Lige nu læser Christer Data and Reality. Christer er klar til at sikre leverance af nye softwareprodukter fra 1. Januar 2016.