🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: pl.comp.programming
Article #217019

Re: Embedded HTTP Server

#217019
From: Maciej Sobczak
Date: Mon, 08 Jun 2020 19:20
88 lines
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-mail
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>

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