-
41. Data: 2020-06-23 09:33:05
Temat: Re: Embedded HTTP Server
Od: Wojciech Muła <w...@g...com>
On Monday, June 8, 2020 at 9:20:39 PM UTC+2, Maciej Sobczak wrote:
> > int main() {
> > auto server = std::make_unique<http::Server>(8008, ".");
> >
> > server->start();
>
> Czyli też jedna dodatkowa linijka kodu, w dodatku zawsze, nawet w najprostszym
programie.
> Więc na czym polega postęp?
Na braku konieczności ręcznego tworzenia i zarządzania wątkiem.
> Się tak łatwo nie zamyka, jeśli ma callbacki.
Co mnie jako twórcę biblioteki obchodzi, że ktoś ma burdel w callbackach. Ja
gwarantuję, że moje wątki się skończą jeśli skończą się callbacki.
> > Stoi, bo masz współdzieloną mapę routingu.
>
> Przyłapałeś mnie. Skupiłem się na portach - faktycznie mapa jest wspólna.
> Czyli twierdzisz, że ktoś będzie koniecznie chciał zrobić w jednym programie 5
serwerów na różnych portach, ale tak, żeby takie same linki robiły w nich różne
rzeczy?
> To brzmi jak ostra perwersja. Tylko dlaczego ja mam w tym uczestniczyć?
Bo np. na jednym porcie masz dane dla userów, na drugim możesz dawać output z
debuggera, profilera, co tam sobie robisz. Wiesz, to że Twój serwer jest prosty, nie
znaczy, że aplikacja która go użyje też jest prosta. Gdyby była prosta, pewnie nikt
by jej nie pisał w C++.
> > A, że masz ją współdzieloną, to też masz radosnego mutexa w głównej pętli.
>
> I w czym ten mutex przeszkadza, skoro go nawet nie widać?
Bo mutexy są kosztowne czasowo. I akurat tego jednego mogłoby nie być.
> > No i to jest defekt. Ja chcę, żeby mój program się zamykał w cywilizowany sposób.
> > Callbacki są wołane w wątkach, robisz sobie na nie barierę (czyli np. latch) po
zakończeniu głównej pętli i po kłopocie.
>
> O ile wszystkie wrócą. Zobacz przykład 6. Można go przepisać tak, że to funkcja
get_updates() będzie robić to, co activity(). Czyli nigdy nie wróci.
>
> Ale owszem, jest to możliwe rozwiązanie, tylko wymaga zmiany koncepcji komunikacji.
Teraz, w prostej implementacji, jest to komunikacja blokująca. Wątek obsługujący
połączenie nie wróci, jeśli utknął na odczycie z gniazda (a w tym stanie spędza
większość czasu), dopóki *klient* tego połączenia nie zamknie. Nie wystarczy sobie
ustawić flagę.
Ale w końcu wróci, choćby przez timeout. I o to chodzi.
> > To jest koślawe, sorry. W HTTP masz nie tylko akcje GET i POST, ale i chyba ze 20
innych.
>
> Ale ja nie obiecuję obsługi tych 20 innych.
Super, więc jak będę chciał mieć operację DELETE albo PUT, to muszę sobie szukać
innego rozwiązania.
> > Poza tym założenie, że ktoś będzie argumenty POST przesyłał w URL-u jest zdziebko
przestarzałe, o wiele wygodniej jest słać parametry w JSONie.
>
> Przecież właśnie tak jest. Dlatego funkcje dla POST mają dodatkowy argument istream
- tam są te dane, które normalni ludzie przekazują.
>
> I właśnie dlatego funkcje dla GET i POST *różnią się* sygnaturami.
No fajnie, tylko to sztuczne rozróżnienie. W protokole HTTP nie ma znaczenia typ
akcji, zawsze masz ten same input, w akcji GET też możesz wysłać dane, np. JSONa.
> > Pamiętanie o kilku wariantach funkcji nie jest prostsze. Już lepiej byłoby mieć
jedną przeciążoną metodę register i kilka pomocniczych funkcji w stylu
"make_get_action".
>
> Czyli że:
>
> register(make_get_action(my_action));
>
> jest lepsze od:
>
> register_get_action(my_action);
>
> Sorry - ani trochę.
Jest bardziej elastyczne i tyle. Ja wolę mieć jedną metodę i zrobić sobie odpowiednie
konstruktory.
Zresztą, najlepiej byłby mieć register(my_action) i wybierać wariant za pomocą
typetraits.
> > Np. testy jednostkowe parserów, których jest co najmniej ze 2. Jak widzę
> > 5-krotnie zagnieżdżony kod, to nie wiem, czego się spodziewać.
>
> Uwaga, szpan: pokrycie strukturalne zapewniłem testami systemowymi.
>
> Bez przesady z tymi testami.
Chciałeś review, to masz. Ja wiem, że parsery klepane ręcznie nie mające testów to
proszenie się o kłopoty, będą wcześniej, czy później.
w.
-
42. Data: 2020-06-23 23:13:07
Temat: Re: Embedded HTTP Server
Od: Maciej Sobczak <s...@g...com>
> > Więc na czym polega postęp?
>
> Na braku konieczności ręcznego tworzenia i zarządzania wątkiem.
Ale przecież nie ma takiej konieczności w żadnym z przykładów.
Natomiast w Twojej propozycji nie tyle nie ma takiej konieczności, co raczej nie ma
takiej możliwości, bo schowałeś to "zarządzanie" w jakimś obiekcie, którego API nie
podałeś.
> Co mnie jako twórcę biblioteki obchodzi, że ktoś ma burdel w callbackach. Ja
gwarantuję, że moje wątki się skończą jeśli skończą się callbacki.
To jest ciekawa propozycja na kolejną wersję biblioteki.
> Bo np. na jednym porcie masz dane dla userów, na drugim możesz dawać output z
debuggera, profilera, co tam sobie robisz.
I to trzeba mieć osobne porty do tego?
Ja na przykład w tej konkretnej chwili podłączam się przeglądarką do jednego portu
pod adresem groups.google.com a tam zdumiewające rzeczy, jedna grupa dla tych co
lubią C++, inna dla tych, co nie lubią, itd. Masa różnych rzeczy, dla różnych
odbiorców. Wyobrażasz sobie, różne rzeczy na jednym porcie mieć?
> Bo mutexy są kosztowne czasowo.
A tak w liczbach, mógłbyś?
W sensie - w porównaniu do całkowitego czasu, który przeglądarce zejdzie na pełnej
obsłudze, od konstrukcji zapytania GET do zakończenia wyświetlenia obrazu na ekranie?
> > > To jest koślawe, sorry. W HTTP masz nie tylko akcje GET i POST, ale i chyba ze
20 innych.
> >
> > Ale ja nie obiecuję obsługi tych 20 innych.
>
> Super, więc jak będę chciał mieć operację DELETE albo PUT, to muszę sobie szukać
innego rozwiązania.
Tak. Ewentualnie możesz zwrócić się do autora z uprzejmą prośbą, żeby to dorobił. Czy
ten schemat pracy to jest dla Ciebie jakieś nowe zjawisko?
> > I właśnie dlatego funkcje dla GET i POST *różnią się* sygnaturami.
>
> No fajnie, tylko to sztuczne rozróżnienie.
Ale użyteczne w kontekście docelowego użycia.
> > Czyli że:
> >
> > register(make_get_action(my_action));
> >
> > jest lepsze od:
> >
> > register_get_action(my_action);
> >
> > Sorry - ani trochę.
>
> Jest bardziej elastyczne i tyle. Ja wolę mieć jedną metodę i zrobić sobie
odpowiednie konstruktory.
> Zresztą, najlepiej byłby mieć register(my_action) i wybierać wariant za pomocą
typetraits.
Łomatko.
Więc najwyraźniej potrzebujesz innej biblioteki. Normalna sprawa.
> Chciałeś review, to masz. Ja wiem, że parsery klepane ręcznie nie mające testów to
proszenie się o kłopoty, będą wcześniej, czy później.
Nie zrozumiałeś. To, że testów nie ma w pakiecie razem z biblioteką, nie znaczy
wcale, że parser nie był przetestowany - ani tym bardziej, że w ogóle nie było
żadnych testów.
W ogóle pomysł, że razem z produktem dostaje się w tym samym pudełku jego stanowisko
testowe, to jakiś wymysł nie mający analogii w żadnej innej branży, nawet w tych
inżynierskich.
--
Maciej Sobczak * http://www.inspirel.com