Introduktion til Finagle

1. Oversigt

I denne vejledning ser vi hurtigt på Finagle, Twitters RPC-bibliotek.

Vi bruger det til at opbygge en simpel klient og server.

2. Byggesten

Inden vi går ind i implementeringen, skal vi lære de grundlæggende koncepter, vi bruger til at opbygge vores applikation, at kende. De er almindeligt kendte, men kan have en lidt anden betydning i Finagles verden.

2.1. Tjenester

Tjenester er funktioner repræsenteret af klasser, der tager anmodninger og returnerer a Fremtid indeholder det endelige resultat af operationen eller oplysninger om fejlen.

2.2. Filtre

Filtre er også funktioner. De tager en anmodning og en tjeneste, udfører nogle operationer på anmodningen, sender den til tjenesten, udfører nogle operationer på den resulterende Fremtidog returner endelig finalen Fremtid. Vi kan betragte dem som aspekter, da de kan implementere logik, der sker omkring udførelsen af ​​en funktion og ændre dens input og output.

2.3. Fremtid

Futures repræsenterer de endelige resultater af de asynkrone operationer. De kan være i en af ​​de tre stater: ventende, lykkedes eller mislykkedes.

3. Service

Først implementerer vi en simpel HTTP-hilsen-tjeneste. Det tager navneparameteren fra anmodningen og svarer og tilføjer den sædvanlige "Hej" -meddelelse.

For at gøre det skal vi oprette en klasse, der udvider abstraktet Service klasse fra Finagle-biblioteket, gennemførelse af dens ansøge metode.

Det, vi laver, ligner implementeringen af ​​en funktionel grænseflade. Interessant nok kan vi dog ikke faktisk bruge den specifikke funktion, fordi Finagle er skrevet i Scala, og vi udnytter Java-Scala-interoperabiliteten:

offentlig klasse GreetingService udvider Service {@Override public Future anvendes (Anmodningsanmodning) {String greeting = "Hej" + request.getParam ("navn"); Læserlæser = Reader.fromBuf (ny Buf.ByteArray (greeting.getBytes (), 0, greeting.length ())); returner Future.value (Response.apply (request.version (), Status.Ok (), reader)); }}

4. Filtrer

Dernæst skriver vi et filter, der vil logge nogle data om anmodningen til konsollen. Svarende til Service, bliver vi nødt til at gennemføre Filter'S ansøge metode, der tager anmodning og returnerer en Fremtid svar, men denne gang vil det også tage tjenesten som den anden parameter.

Det basale Filter klasse har fire typeparametre, men meget ofte behøver vi ikke ændre typer anmodninger og svar inde i filteret.

Til det vil vi bruge SimpleFilter der fletter de fire typeparametre i to. Vi udskriver nogle oplysninger fra anmodningen og påberåber os derefter blot ansøge metode fra den leverede tjeneste:

offentlig klasse LogFilter udvider SimpleFilter {@Override public Future anvendes (Anmodningsanmodning, servicetjeneste) {logger.info ("Anmod vært:" + anmodning.host (). getOrElse (() -> "")); logger.info ("Request params:"); request.getParams (). forEach (post -> logger.info ("\ t" + entry.getKey () + ":" + entry.getValue ())); return service. ansøg (anmodning); }} 

5. Server

Nu kan vi bruge tjenesten og filteret til at opbygge en server, der rent faktisk lytter til anmodninger og behandler dem.

Vi forsyner denne server med en tjeneste, der indeholder både vores filter og vores service lænket sammen med og så metode:

Service serverService = nyt LogFilter (). Og derefter (nyt GreetingService ()); Http.serve (": 8080", serverService);

6. Klient

Endelig har vi brug for en klient til at sende en anmodning til vores server.

Til det opretter vi en HTTP-tjeneste ved hjælp af det praktiske newService metode fra Finagle's Http klasse. Det er direkte ansvarligt for at sende anmodningen.

Derudover bruger vi det samme logfilter, som vi har implementeret før, og kæder det med HTTP-tjenesten. Så bliver vi bare nødt til at påberåbe sig ansøge metode.

Den sidste handling er asynkron, og dens eventuelle resultater gemmes i Fremtid eksempel. Vi kunne vente på dette Fremtid at lykkes eller mislykkes, men det ville være en blokering, og vi vil måske undgå det. I stedet kan vi implementere et tilbagekald, der skal udløses, når Fremtid lykkes:

Service clientService = nyt LogFilter (). Og derefter (Http.newService (": 8080")); Anmodningsanmodning = Request.apply (Method.Get (), "/? Name = John"); request.host ("localhost"); Fremtidigt svar = clientService.apply (anmodning); Await.result (respons .onSuccess (r -> {assertEquals ("Hello John", r.getContentString ()); returner BoxedUnit.UNIT;}) .onFailure (r -> {smid ny RuntimeException (r);})) ;

Bemærk, at vi vender tilbage BoxedUnit.UNIT. Vender tilbage Enhed er Scalas måde at klare ugyldig metoder, så vi gør det her for at opretholde interoperabilitet.

7. Resume

I denne vejledning lærte vi, hvordan man bygger en simpel HTTP-server og en klient ved hjælp af Finagle samt hvordan man opretter kommunikation mellem dem og udveksler meddelelser.

Som altid kan kildekoden med alle eksemplerne findes på GitHub.