Article View: pl.comp.programming
Article #217019Re: Embedded HTTP Server
From: Maciej Sobczak
Date: Mon, 08 Jun 2020 19:20
Date: Mon, 08 Jun 2020 19:20
88 lines
6151 bytes
6151 bytes
> Żeby Twojego rozwiązania użyć w jakimś normalnym programie, trzeba stworzyć wątek.
Cała jedna linijka kodu. Której w prostych programach nawet nie trzeba (patrz przykłady).
> Wygodne użycie, to byłoby coś takiego:
>
> 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?
> // tu się dzieje magia, która programista uprawia
> // a gdy się kończy scope, to server się sam zamyka
> }
Się tak łatwo nie zamyka, jeśli ma callbacki.
> > Natomiast, nic nie stoi na przeszkodzie, żeby sobie zawołać funkcję server_start() 5 razy z różnymi portami, z 5 różnych wątków, bo ta funkcja i tak nie ma stanu globalnego. Nie trzeba mieć do tego klasy.
>
> 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ć?
Jeśli moja biblioteka miałaby swoją ułomnością powstrzymać kogoś przed tą perwersją, to nawet uznałbym to za moralny sukces. :-)
> 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ć?
> 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ę.
Można to rozwiązać wprowadzając dodatkowe mechanizmy typu select() albo poll(), ale zrobienie tego dobrze to złożoność porównywalna z całą resztą kodu i to są właśnie problemy, których nie chciałem rozwiązywać w wersji 1.0.
Ten problem jest rozwiązany w bibliotece YAMI4, ale to zupełnie inna liga.
> 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.
> 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.
> 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ę.
> > A po co? Bez przesady z tą walidacją. Walidować należy input z zewnątrz (i nawet opisałem to w przykładzie 3, z parametrami) a nie własne literały.
>
> Bo programista się czasem myli, więc powinien się koncentrować na błędach w kodzie, który pisze, a nie którego używa.
Ale dlaczego ma się koncentrować na błędach w kodzie, którego używa, skoro takich nie znalazł a za to ma błędy w swoim? :-)
I czym się różni pomyłka polegająca na użyciu pustego wskaźnika od pomyłki polegającej na użyciu wskaźnika do niewłaściwej funkcji?
Otóż niczym się nie różni - a kompleksowe rozwiązanie tego zagadnienia (czyli zapewnienie, że programista sięgnął po właściwą funkcję) nie leży po stronie użytej biblioteki. To jest jedno z częstych nieporozumień w temacie weryfikacji albo defensywnego kodowania.
Na tej podstawie zakładam, że programista poda wskaźnik do właściwej funkcji. To założenie jest częścią kontraktu tej biblioteki.
> > A jakieś inne testy byś chciał?
>
> 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.
--
Maciej Sobczak * http://www.inspirel.com
Technical Details
Message-ID:
<d95ffe9d-570f-455c-bb22-0831b8c0a0dfo@googlegroups.com>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!fu-berlin.de!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mailReferences:
<d423a072-9378-441b-ba06-e0657a1fa53bo@googlegroups.com> <3e267b62-0fdf-41c2-9f9c-c316f98b85c6o@googlegroups.com> <7cd03711-5fee-4322-b02a-c803fcf43b31o@googlegroups.com> <a0edbb57-72ba-48f1-bf82-7060d1cec401o@googlegroups.com>Show Full Headers
Complete Article Headers
X-Received: by 2002:a37:6196:: with SMTP id v144mr23996227qkb.337.1591644038960; Mon, 08 Jun 2020 12:20:38 -0700 (PDT) X-Received: by 2002:ad4:4cce:: with SMTP id i14mr223441qvz.207.1591644038701; Mon, 08 Jun 2020 12:20:38 -0700 (PDT) Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!fu-berlin.de!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail Newsgroups: pl.comp.programming Date: Mon, 8 Jun 2020 12:20:38 -0700 (PDT) In-Reply-To: <a0edbb57-72ba-48f1-bf82-7060d1cec401o@googlegroups.com> Complaints-To: groups-abuse@google.com Injection-Info: google-groups.googlegroups.com; posting-host=213.108.152.51; posting-account=bMuEOQoAAACUUr_ghL3RBIi5neBZ5w_S NNTP-Posting-Host: 213.108.152.51 References: <d423a072-9378-441b-ba06-e0657a1fa53bo@googlegroups.com> <3e267b62-0fdf-41c2-9f9c-c316f98b85c6o@googlegroups.com> <7cd03711-5fee-4322-b02a-c803fcf43b31o@googlegroups.com> <a0edbb57-72ba-48f1-bf82-7060d1cec401o@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <d95ffe9d-570f-455c-bb22-0831b8c0a0dfo@googlegroups.com> Subject: Re: Embedded HTTP Server From: Maciej Sobczak <see.my.homepage@gmail.com> Injection-Date: Mon, 08 Jun 2020 19:20:38 +0000 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit