Pengantar Finagle

1. Ikhtisar

Dalam tutorial ini, kita akan melihat sekilas Finagle, perpustakaan RPC Twitter.

Kami akan menggunakannya untuk membangun klien dan server sederhana.

2. Balok Penyusun

Sebelum kita menggali implementasinya, kita perlu mengetahui konsep dasar yang akan kita gunakan untuk membangun aplikasi kita. Mereka dikenal luas tetapi dapat memiliki arti yang sedikit berbeda di dunia Finagle.

2.1. Jasa

Layanan adalah fungsi yang direpresentasikan oleh kelas yang menerima permintaan dan mengembalikan Future yang berisi hasil akhir dari operasi atau informasi tentang kegagalan.

2.2. Filter

Filter juga berfungsi. Mereka mengambil permintaan dan layanan, melakukan beberapa operasi berdasarkan permintaan, meneruskannya ke layanan, melakukan beberapa operasi pada Future yang dihasilkan , dan akhirnya mengembalikan Future terakhir . Kita dapat menganggapnya sebagai aspek karena mereka dapat mengimplementasikan logika yang terjadi di sekitar eksekusi suatu fungsi dan mengubah input dan outputnya.

2.3. Futures

Futures merepresentasikan hasil akhir dari operasi asynchronous. Mereka mungkin berada di salah satu dari tiga status: menunggu keputusan, berhasil, atau gagal.

3. Layanan

Pertama, kami akan menerapkan layanan ucapan HTTP sederhana. Ini akan mengambil parameter name dari permintaan dan menanggapi dan menambahkan pesan "Halo" biasa.

Untuk melakukannya, kita perlu membuat kelas yang akan memperluas kelas Layanan abstrak dari pustaka Finagle, mengimplementasikan metode terapannya .

Apa yang kami lakukan terlihat mirip dengan menerapkan antarmuka fungsional. Menariknya, kami tidak dapat benar-benar menggunakan fitur spesifik itu karena Finagle ditulis dalam Scala dan kami memanfaatkan interoperabilitas Java-Scala:

public class GreetingService extends Service { @Override public Future apply(Request request) { String greeting = "Hello " + request.getParam("name"); Reader reader = Reader.fromBuf(new Buf.ByteArray(greeting.getBytes(), 0, greeting.length())); return Future.value(Response.apply(request.version(), Status.Ok(), reader)); } }

4. Filter

Selanjutnya, kami akan menulis filter yang akan mencatat beberapa data tentang permintaan ke konsol. Serupa dengan layanan , kami akan perlu untuk mengimplementasikan Filter 's menerapkan metode yang akan membawa permintaan dan mengembalikan Masa Depan respon, tapi kali ini juga akan mengambil layanan sebagai parameter kedua.

Kelas Filter dasar memiliki empat tipe-parameter tetapi seringkali kita tidak perlu mengubah tipe permintaan dan tanggapan di dalam filter.

Untuk itu, kita akan menggunakan SimpleFilter yang menggabungkan empat tipe-parameter menjadi dua. Kami akan mencetak beberapa informasi dari permintaan dan kemudian menjalankan metode terapkan dari layanan yang disediakan:

public class LogFilter extends SimpleFilter { @Override public Future apply(Request request, Service service) { logger.info("Request host:" + request.host().getOrElse(() -> "")); logger.info("Request params:"); request.getParams().forEach(entry -> logger.info("\t" + entry.getKey() + " : " + entry.getValue())); return service.apply(request); } } 

5. Server

Sekarang kita dapat menggunakan layanan dan filter untuk membangun server yang benar-benar akan mendengarkan permintaan dan memprosesnya.

Kami akan menyediakan server ini dengan layanan yang berisi filter dan layanan yang dirantai bersama dengan metode andThen :

Service serverService = new LogFilter().andThen(new GreetingService()); Http.serve(":8080", serverService);

6. Klien

Akhirnya, kami membutuhkan klien untuk mengirim permintaan ke server kami.

Untuk itu, kita akan membuat layanan HTTP menggunakan metode newService yang nyaman dari kelas Http Finagle . Ini akan bertanggung jawab langsung untuk mengirim permintaan.

Selain itu, kami akan menggunakan filter logging yang sama yang kami terapkan sebelumnya dan menghubungkannya dengan layanan HTTP. Kemudian, kita hanya perlu menjalankan metode terapkan .

Operasi terakhir itu asinkron dan hasil akhirnya disimpan dalam instance Future . Kita bisa menunggu Masa Depan ini berhasil atau gagal tetapi itu akan menjadi operasi pemblokiran dan kita mungkin ingin menghindarinya. Sebagai gantinya, kita bisa mengimplementasikan callback yang akan dipicu ketika Future berhasil:

Service clientService = new LogFilter().andThen(Http.newService(":8080")); Request request = Request.apply(Method.Get(), "/?name=John"); request.host("localhost"); Future response = clientService.apply(request); Await.result(response .onSuccess(r -> { assertEquals("Hello John", r.getContentString()); return BoxedUnit.UNIT; }) .onFailure(r -> { throw new RuntimeException(r); }) );

Perhatikan bahwa kami mengembalikan BoxedUnit.UNIT. Returning Unit adalah cara Scala untuk mengatasi metode void , jadi kami melakukannya di sini untuk menjaga interoperabilitas.

7. Ringkasan

Dalam tutorial ini, kita belajar bagaimana membangun server HTTP sederhana dan klien menggunakan Finagle serta bagaimana membangun komunikasi di antara mereka dan bertukar pesan.

Seperti biasa, kode sumber dengan semua contoh dapat ditemukan di GitHub.