Kuidas luua Opusega ilusaid torujuhtmeid Elixiril

Ma pole kindel, kas Zorbashil oli idee luua Opus, kui töötasime Quiqupis sama projekti kallal, kuid kui selles on üks, milles võin kindel olla, siis tema idee päästis meid raskesti loetavatest moodulitest, mis olid segamini äriloogika orkestriga. "Mida sa silmas pead? Eliksiiril on ilus süntaks ”, küsite te. Ja ma olen nõus, kuid me saame alati teha tööd selle paremaks muutmiseks.

Hallid tunnelid - autor: Patrick Hendry (Unsplash)

Kasutusjuhtum

Quiqupis on meil olemas ärimudel, mis nõuab, et meie autojuhid teeksid erinevaid töid. Näiteks sõltuvalt sellest, kes tellib, võivad meie autojuhid vajada lihtsalt restoranist ettetellitud toidu kogumist või poodi sisse kõndimist ja paljude üksuste valimist. Samuti peavad nad mõnikord kohapeal kliendi nimel maksma ja kui jah, siis peame neile sellest teatama. Teinekord nad seda ei tee. Need on vaid maitseks paljudele otsustele, mida meie autojuhid ja tugimeeskonnad peavad tegema vaid ühe toimingu jooksul.

Seistes silmitsi sellise keeruka olukorraga, kus on nii palju liikuvaid osi, otsustasime luua torustikmoodulid, millele saaksime viidata ja teada saada, ilma et peaksime rakendusse süvenema, kuidas selliste otsuste protsess toimib.

See on koht, kus avaldus särab. Me tulime välja midagi sellist:

Pole just kõige ilusam vaatamisväärsus - me teame. Ehkki seda pole täiesti võimatu lugeda, võime ette kujutada, kui kohutav oleks seda säilitada ja laiendada, kui meie ärinõuded muutuvad keerukamaks. Rääkimata Pandora kastist, mis toimib nagu create_next_stage? ja create_stage võivad avaneda, kuna segule lisatakse üha rohkem otsuseid.

Opus appi

Nagu Opuse lugemiskavas mainitud, said inspiratsiooni dry.rb (tehing) ja trailblazer (operatsioon) kasutada raudteele orienteeritud programmeerimismeetodit.

Lühidalt öeldes oleks eespool nimetatud koodinäite ekvivalent Opus kasutades järgmine:

Enne kaevamist mõlemasse ülaltoodud koodi rida, mõelgem põhitõed.

Kuidas Opus töötab?

Märkus: see artikkel on kirjutatud versiooni 0.5.1 jaoks

Opuse põhiaspekt on Opus.Pipeline ja saate seda moodulis kasutada nii, et see töötab torustikuna. Torujuhtme all peame silmas seda, et esialgne sisend, mille peame andma, läbib selle torujuhtme eri etappe ja iga etapp annab väljundi, mis on järgmiseks sisendiks järgmisele etapile.

Vaadake allolevat pilti, mis on välja võetud ametlikest dokumentidest:

Samuti väärib mainimist, et torujuhe pole protsess ja see ei hoia olekut.

Vaikimisi ei leki gaasijuhe ühtegi erandit, mis võib selle sees tekkida. Selle asemel naaseb see kas {: ok, any ()} või {: viga,% Opus.PipelineError {}}. Kuid saate seda käitumist muuta, pannes Opuse lekkima kas erandeid või konkreetseid, kogu torujuhtme või konkreetsete etappide jaoks. Lisateave rakendamise kohta allpool.

Kui tagastatakse {: tõrge,% Opus.PipelineError {}}, tähendab see, et Opus peatus teatud etapis ega käivitanud järgmisi.

Torujuhtmele helistamiseks ja esialgse väljundi sisestamiseks helistate funktsioonikõnele / 1, mille moodul Opus rakendab, kui kasutate moodulis Opus.Pipeline:

Pärast seda kutsub Opus esimese etapi. Meie näites on see kontrollietapp. Igal etapil on oma töö viis (üksikasjad allpool).

Etapid

Üldiselt saab iga etapp täidetava funktsiooni nime atomiseeritud kujul (nt valide_order). Kõiki neid funktsioone tuleb rakendada ariteediga 1 ja antud argumendiks on praegused torujuhtme andmed. Torujuhtmele on mugav lisada kas konstruktsioon või kaart.

Sellegipoolest see töötab nii (vaadake kõiki üksikasju ametlikust dokumendist):

Kontrollima

Funktsioon peab tagastama tõeväärtuse. Kui see on tõsi, lubab Opus gaasijuhtme jätkumist ja helistab järgmisele etapile, andes samad torujuhtme andmed, mis sellele etapile anti. Kui see on vale, peatab Opus torujuhtme ja tagastab kordsuse {: error,% Opus.PipelineError {}}.

Võite valida vea teate: aatom | Sellele etapile saab valiku String.t abil kinnitada valideerimisvea, nt: check: valid_params ?, error_message:: invalid_initial_input või kasutada kasutatavat elegantset viga, nt: check: valid_params ?, error_message: "Invalid input. Oodatav : käsk anda. " Antud väärtus tagastatakse% Opus.PipelineError {} sees.

samm

Funktsioon viib läbi mis tahes toimingu ja tagastab uue torujuhtme andmed, mis tuleb saada järgmisse etappi. Sellegipoolest võite sama vastuvõetud torujuhtme tagastada, kui selles on rohkem andmeid, või uue kaardi koos teiste andmetega ja algsisend kaob.

See etapp on kasulik ka selleks, et lihtsalt lisada torustikku uusi andmeid ilma midagi erilist tegemata. Meie näites on meil samm: määrake_kuller, kes seda teeb, näiteks järgmiselt:

See on kasulik ettevalmistamisel olevale millelegi juurdepääsu lahti sidumiseks või lipu lisamiseks, mis aitab teil järgmistes etappides otsuseid vastu võtta, näiteks:

link

Saab veel ühe Opuse torujuhtme mooduli. See on kasulik, kui soovite teha torustikus igal ajal midagi keerukamat ja soovite selleks kasutada mõnda muud torustikku. Opus kutsub oma funktsiooni .call / 1 ja mooduli viimase etapi tagasitulekuks on praeguse mooduli uued torujuhtme andmed.

See oli meie jaoks oluline, kuna saime järgmises tellimisjärgus sõltuvalt nälkjatest täita teistsugust püsivust. Nii et ühise sammu asemel: persist_stage, jõudsime välja näiteks:

Ja see üleskutse? / 1 (mis võib muidugi olla segane) viidi ellu nii, et saaksime kasutada võimalust, mille Opus meile annab (üksikasjad allpool). See võimaldab meil kontrollida, kas peaksime nimetama seda konkreetset püsivust, tuginedes praegustele torujuhtme andmetele.

tee

See on sama, mis samm, välja arvatud juhul, kui juhtub midagi halba, ei peata Opus gaasijuhet ega tagasta ühtegi {: viga, _}. See on kasulik, kui soovite teha midagi, mis võib olla valesti, kuid te ei soovi seda käsitleda veana. Selle asemel saate selle kuhugi sisse logida ja edasi liikuda.

Meie puhul tahtsime helistada välisele teenusele ja kuna miski pole 100% ajast saadaval, ei taha me torujuhtme peatamist ega vea tagastamist millelegi, mida võime hiljem uuesti proovida.

Lavavalikud

Opus annab teile igas etapis mõned uskumatud võimalused, näiteks anonüümse funktsiooniga toimingu tegemine või tingimuslausete kasutamine teatud etapi juurutamiseks ainult siis, kui tingimus on tõene (nagu me eespool nägime).

Selle kohta lisateabe saamiseks vaadake ametlikku dokumentatsiooni.

Kõike kokku pannes saate teha järgmist:

Me kasutasime:

  • koos: aktsepteerib anonüümset täidetavat funktsiooni, vältides vajadust määratleda funktsiooninimi, mille andsite argumendina;
  • error_message: kuna Opusel on {: viga,% Opus.PipelineError {}} vastuvõtmisel veateate loomiseks oma tava, saate määratleda etapi jaoks oma veateate;
  • tõsta: Opus ei tõsta ühtegi viga, kui te seda ei luba. See tähendab, et võite anda väärtuse tõene (vaikeseade on vale), siis ei leia Opus selle etapi jaoks ühtegi tõstatatud erandit või võite anda erandite loendi, nii et ka Opus neid ei taba.

Selle valiku saab anda kasutusmakro jaoks, näiteks:

  • instrument ?: kui soovite keelata mõõteriistad (rohkem allpool), seadke see väärtusele vale (vaikeseade on tõene).
  • kui: täidab selle etapi ainult siis, kui antud tingimus on tõene.
  • retry_times: ülimalt kasulik, kui peate tegema midagi välist, mis võib-olla pole saadaval (peab olema täisarv).
  • retry_backoff: viivitus iga korduse vahel. Töötab koos retry_times ja see võtab vastu funktsiooniga seotud aatomi või anonüümse funktsiooni. See funktsioon peab tagastama numbri.t, milles on nii palju numbreid kui kordusperioodidele antud korduskorraldusi. Opus kasutab kapoti all rakendust ElixirRetry, mis võimaldab teil kasutada selliseid funktsioone nagu lin_backoff / 2 ja cap / 2.

Kindlale etapile helistamine

Testimiseks on super kasulik helistada konkreetsele etapile või kutsuda kogu torujuhtme, välja arvatud teatud etapp. Näiteks meie puhul kasutasime torujuhtme kaheks või enamaks plokiks jagamiseks ja iga osa eraldi katsetamist. Ja õnneks annab Opus meile selle jõu:

Instrumentatsioon

See on tõenäoliselt Opuse üks hämmastavamaid funktsioone. See võimaldab meil luua seadmeid oma torujuhtme sees või täielikult lahti siduda.

Põhimõtteliselt on olemas kolm konksu, enne_etapp, etapp lõpetatud, etapp_komplekteeritud, torujuhtme algus ja torujuhtme_komplektne ning saate neid mooduli sees "kuulata" järgmiselt:

või looge mõõdikute moodul, lisades selle oma konfiguratsiooni / *. ekss, näiteks:

config: opus,: mõõteriistad, [PipelineInstrumentation]

Samuti saate keelata mõõteriistade teatud etapis, nagu ülaltoodud suvandites mainitud, või kogu mooduli jaoks, näiteks:

Vaadake dokumentatsiooni, et leida rohkem näiteid aparaatide kohta.

Graafik

Opus viib Graphvizi abil kasutusele torujuhtme voo visualiseerimise. Nagu ülalpool mainitud, rakendame keeruka äriloogikaga ülesandeid, mida meie armsad kullerid peavad täitma, ja see funktsioon on meie toodete sisedokumentatsiooni lisana väga kasulik.

Käivitage Opus.Graph.generate (: teie_rakendus) ja siis juhtub kogu maagia. See käsk tagastab genereeritud kujutisega staatusetud tüübi.

See näeb välja selline:

Uue näite saamiseks vaadake dokumentatsiooni.

Mis järgmiseks?

Opuse peatsel avaldamisel on 0.6.0 ja ta lisab uue etapi, mille nimi on skip. Nii see töötab:

Funktsiooni nime saamise asemel saab see funktsiooni if::, mis muudab voolu juhtimise rohkem kui etapi enda vahele. Kui see funktsioon vastab tõele, siis torujuhe peatatakse, kuid Opus tagastab {: ok,: vahele jäänud}.

vahelejätmist tuleks kasutada siis, kui soovite kontrollida, kuid ei soovi vea tagastada, kui kontroll ebaõnnestub. Järgmine etapp võtab vastu praegused torujuhtme andmed, nagu see juhtub kontrollietapil.

Kui soovite sellega mängida, võite proovida installida Opus, viidates põhialale.

Järeldus

Opus aitas meil kirjutada loetavaid, lahti ühendatud ja hooldatavaid gaasijuhemooduleid. Ma ei suuda mõelda muule võimalusele, kuidas saaksime oma loogikat laiendada ja neid nii hõlpsalt ja puhtalt rakendada.

Tore oleks näha teisi kasutusjuhtumeid ja mõtteid Opuse ümbruses, nii et kui olete sellega mingil hetkel mänginud, jagage meiega mõnda koodi!

Õnnelik kood ja elage alkeemia o /