Morn!
Morn!
Morgen!
Morn!
Morn!
Morn!
God morgen!
Har nettopp omkalfatret et sideprosjekt til å bruke FC/IS-arktitektur (functional core, imperative shell - se https://parenteser.mattilsynet.io/fkis-jz/). En problemstilling jeg ikke har en god løsning på ennå er avhengigheter mellom effects. For eksempel: et http request kommer inn, og kjernen lager effects for å skrive til database og å returnere et svar:
{:effects [{:effect/kind :db/transact
:effect/data tx-data}
{:effect/kind :http/sse-response
:effect/data {:patches [(h/html (business-settings-page updated-account))]}}]}
Vel og bra, men hva om db-transaksjonen feiler? Kanskje ikke så sannsynlig da vi har kontroll på database og dataene som skal inn, men problemet gjelder alle I/O-operasjoner, som et API-kall mot en tredjepart..
Min løsning hittil er å si at visse effekter er kritiske, og om de feiler så utfører vi ikke flere effekter. Om vi skulle gjøre et http-response så lager vi i stedet en generisk feil-response.
Men dette modelleres altså ikke i effektene. Det er en generisk “fail-fast”-løsning. Man kunne hatt det som en del av effektene, definert hva som skal skje ved feil etc for hver av dem.
Spent på å høre om dere har noen erfaringer?En problemstilling jeg ikke har en god løsning på ennå er avhengigheter mellom effects.Om du bruker FC/IS er vel målet å unngå dette i første omgang? Ikke at jeg sier det nødvendigvis er mulig, bare at premisset for at FC/IS skal fungere bra er at du ikke har (mange) slike situasjoner. Da jeg jobbet med betaling hadde vi en slags FC/IS-tilstandsmaskin som beregnet et og et steg, og gjorde maks to endringer per steg (oppdatering av database, samt en operasjon til eksternt betalingssystem). Men dette var primært for å forsikre oss om at maskinfeil eller strømbrudd ikke ville medføre til dobbelttransaksjoner etc. Å forstå hva koden gjorde overordnet var et herk.
Har ikke prøvd det selv, men høres ut som å gå fra én kommandokø til flere køer i systemet kunne løst problemet. Kun oppdater tilkoblede klienter etter at transaksjonen har gått gjennom. Datomic har txReportQueue: https://blog.datomic.com/2013/10/the-transaction-report-queue.html https://docs.datomic.com/javadoc/datomic/Connection.html#txReportQueue() Edit: innser at man ikke trenger flere køer. "transaksjon har gått gjennom" må kunne lyttes på og trigge oppdatering av kilentene.
Det er ikke transaksjoner på tvers av tjenester, nei. Vi har også en sånn fail fast-tilnærming per nå. Vi sorterer da effects i rekkefølgen mest til minst kritisk 😅 Oppdater databasen først! Vi gjør så mye validering som mulig i planleggingssteget, slik at det stort sett bare er tekniske problemer som kan stoppe en effekt (nettverk, etc). Om vi gjør et HTTP-kall til Outlook og får en valideringsfeil så er det en bug i systemet vårt. Sånne feil bør plukkes opp i planleggingen og ikke bli til en effekt. Med denne modellen kan bli mer robust ved at også effektene legges på en kø slik at vi kan ha retries osv.
Som du sier er det også mulig å se for seg mer finkorna funksjonalitet per effekt for dette. Dette er i praksis et ikke-problem i vårt system, så jeg ser ikke for meg at det blir en prioritet å gjøre så mye med.