Czy funkcja w gRPC może trwać w nieskonczoność ?

0

Zastanawiam się nad koncepcja strumienie w gRPC,
czy zamiast odpytywać w nieskończonej pętli serwer
można zrobić jedno zapytanie które trwa w nieskończoność ?

np.

service DataStreamService
{
  rpc BinaryStream(BinaryRequest) returns (stream BinaryReply) {}
}

// The response message containing the greetings
message BinaryReply {
  bytes data = 1;
}

message BinaryRequest {
  string id = 1;
}

Po stronie serwera w implementacji BinaryStream , raz uruchomiona funkcja wysyła dane w nieskończoność

BinaryReply reply;
while(true)
{
     reply.set_data(buf.data(),buf.size());
     bool _OK = writer->Write(reply);
}

po stronie klienta

BinaryReply reply;
auto result = stub->BinaryStream(&context, request); // klient uruchamia raz funkcję `BinaryStream`
if(result)
{
  while(result->Read(&reply))
  {
    // reply.data() // tutaj są dane     
  }
}
2

Co chcesz osiągnąć? Jak chcesz mieć strumień i mieć subskrypcje na otwrate połączenie cały czas nie lepszym rozwiązaniem będzie web socket?

0

@rjakubowski: chce uzyskaj jak najkrótszy czas pomiędzy kolejnymi porcjami danych.
WebSocket jeszcze nie używałem w c++, a dało by rade protobuf zapakować do websocket ?

2

@Marius.Maximus: przy websockecie masz dane w czasie rzeczywistym, więc idealnie Ci pasuje. Działa to tak, że inicjuesz połączenie, które jest podtrzymywane i możesz sobie wysyłać dane między klientem i serwerem do woli. Na pewno jest jakaś biblioteka, która Ci pomoże w C++ korzystać z Websocketa, ale tu Ci nie pomogę, bo jestem z .NETowego podwórka. Pytaj Google, API powinno być proste, bo Websocket to szeroko stosowany protokół 😉

3
rjakubowski napisał(a):

Co chcesz osiągnąć? Jak chcesz mieć strumień i mieć subskrypcje na otwrate połączenie cały czas nie lepszym rozwiązaniem będzie web socket?

Te rozwiązanie są podobne. gRPC jest lepsze, bo jest silniej typowane dzięki protobufom (włącznie z tym, czy jest to strumień w jedną stronę, obie czy pojedyńcze zapytanie) oraz możesz pytać ten sam serwer o wiele metod np. możesz zaimplementować chat za pomocą komunikacji dwustronnej a np. takie informacje o użytkowniku możesz wywołać za pomocą zwykłego blokującego zapytania. W websocketach musisz sam zaimplementować która wiadomość odnosi się do którego strumienia/zapytania. Oczywiście websockety mają taką zaletę, że działają w webie i są koncepcyjnie i technologicznie prostsze

Marius.Maximus napisał(a):

Zastanawiam się nad koncepcja strumienie w gRPC,
czy zamiast odpytywać w nieskończonej pętli serwer
można zrobić jedno zapytanie które trwa w nieskończoność ?

Możesz, ale musisz być gotowy na ponowienie transmisji, jeśli serwer się w wywali albo połączenie zostanie zerwane. Nie będziesz też miał skalowania z uwagi na to, że dany klient jest przyspawany do danego serwera, gdy rozpoczniesz transmisję. Jeśli zależy ci na skalowaniu albo mniejszym couplingu pomiędzy dwiema stronami to możesz pomysleć o użyciu kolejek (np. RabbitMQ), gdzie wiadomości przechodzą przez pośrednika (brokera kolejki)

Warto też się zainteresować nad alternatywami. Dobrym przypadkiem do użycia takiego streamingu jest wysyłanie poleceń i komunikatów np. w grach.

Niewłaściwym przypadkiem jest np. streamowanie danych, jeśli da się to ogarnąć w sposób synchroniczny. Np. utworzenie streamu na potrzeby wyciągnięcia danych z bazy SQL brzmi słabo, bo to samo można ogarnąć przy pomocy dobrej paginacji (https://www.cockroachlabs.com/docs/stable/pagination). W takim podejściu klient dostaje tyle informacji ile chce a dzięki użyciu paginacji (która trzyma stan pomiędzy kolejnymi batchami) nie ma potrzeby trzymania otwartego połączenia (mogę np. zapytać inny serwer co pozwala na lepsze skalowanie i availability)

0

@slsy: wymieniłeś zalety które dostrzegłem w gRPC, ten sam problem był robiony na pomocą zwykłych soketów ale złożoność problemu, dynamika zmian spowodowały ze zaczęło się rozjeżdżać , dokumentacja sobie, życie sobie , dochodziły jeszcze problemy ze klienci mieli na telefonach różne wersje aplikacji i rozne wersje API i masa innych problemów.
optymistycznie zakładam ze używanie plików proto trochę pomoże.

Zastanawiam sie jeszcze nad obejrzeniem projektu https://capnproto.org/

1
Marius.Maximus napisał(a):

optymistycznie zakładam ze używanie plików proto trochę pomoże.

Proto są bardzo dobre do API, które musi ewoluować w taki sposób, żeby redukować do zera ilość zmian, które nie są wstecz kompatybilne. Zmiany takie jak zmiana nazwy czy nawet dodanie/usunięcie repeated da się zrobić bez problemu w porównaniu np. do takiego JSONa.

Zastanawiam sie jeszcze nad obejrzeniem projektu https://capnproto.org/

Zostań przy proto/gRPC, jeśli twój problem nie wymaga ogromnej wydajności. Stack od googla jest popularny i dopracowany, jest dużo toolingu jak i wsparcia dla różnych języków w porównaniu do CapNProto

0 użytkowników online, w tym zalogowanych: 0, gości: 0