Article View: pl.comp.programming
Article #217018Re: Embedded HTTP Server
From: Wojciech Muła
Date: Mon, 08 Jun 2020 10:25
Date: Mon, 08 Jun 2020 10:25
77 lines
5948 bytes
5948 bytes
On Saturday, June 6, 2020 at 9:00:07 PM UTC+2, Maciej Sobczak wrote:
> > Po pierwsze, to aż się prosi, żeby ten serwer był zwykłą klasą. Czemu ktoś nie miałby sobie stworzyć 5 serwisów WWW działających na różnych portach?
>
> No właśnie. I tu poruszamy ważną kwestię. Bo piszesz, że aż się prosi, ale potem okazuje się, że nikt nie prosi, tylko czemu ktoś by miał nie prosić.
Czyli ograniczasz użytkowników do jednego przypadku i to w sytuacji, gdy dodanie jednego stopnia swobody nie kosztuje ani użytkownika, ani Ciebie nic.
> A mi chodziło o to, żeby pakiet 1.0 przekroczył próg używalności a nie o to, żeby rozwiązać problemy typu "czemy ktoś nie miałby".
Żeby Twojego rozwiązania użyć w jakimś normalnym programie, trzeba stworzyć wątek. Wygodne użycie, to byłoby coś takiego:
int main() {
auto server = std::make_unique<http::Server>(8008, ".");
// tu sobie programista coś inicjalizuje
server->start();
// tu się dzieje magia, która programista uprawia
// a gdy się kończy scope, to server się sam zamyka
}
> 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. A, że masz ją współdzieloną, to też masz radosnego mutexa w głównej pętli.
> > Po drugie, nie ma sposobu na zamknięcie serwera, poza zabiciem procesu. Chyba, że ja czegoś nie widzę.
>
> Tak. Funkcja server_stop() już istniała, ale ją usunąłem. To nie jest oczywiste, jak zamknąć serwer, który ma callbacki, niektóre zapewne w trakcie pracy.
> Wszystkie problemy da się rozwiązać, ale nie o to chodziło w wersji 1.0.
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.
> > Mówiąc o API: 6 wariantów register_{generic,html,text}_{post,get}_action można by sprowadzić do 2. register_action(const char* name, {post_action_type, get_action_type} callback, const char* mime_type).
>
> Nie, bo po pierwsze generic i html różnią się obsługą a po drugie nie chciałem przeciążać funkcji register, bo bardziej naturalne wydaje mi się przeciążenie funkcji akcji dla get i post:
>
> void my_action(to-co-trzeba-dla-get) { ... }
> void my_action(to-co-trzeba-dla-post) { ... }
>
> I wtedy nie dałoby rady:
>
> register(my_action);
To jest koślawe, sorry. W HTTP masz nie tylko akcje GET i POST, ale i chyba ze 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.
> > Zresztą, może lepiej byłoby przyjmować jako argument mapę akcji - czyli to co masz teraz w get_actions/post_actions. Niech user sobie przygotuje takie mapy w sposób, jaki mu pasuje, a ty pozbędziesz się potrzeby blokowania tych struktur.
>
> Ale teraz obsługa jest prostsza, właśnie dlatego, że user nie musi robić takich map.
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".
> Można by było pomyśleć o akcji catch-all. Tam user dostawałby wszystko (co nie było obsłużone) i mógłby sobie tam zrobić takie mapy, jakie zechce.
>
> > Czasem funkcje przyjmują const char*, czase std::string& co jest niespójne.
>
> Bo chodziło o przewidywane użycie. Tam gdzie przewidywałem literał, jest const char*.
const char* to nie tylko literały, tego założenia nie da się odczytać z API.
> > W ogóle nie walidujesz, czy wskaźniki są niepuste. Tak samo z std::function.
>
> 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.
> > Zero testów. Serio? :)
>
> Są testy. W katalogu, który dla zmylenia przeciwnika nazywa się examples. :-)
>
> 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ć.
w.
Technical Details
Message-ID:
<a0edbb57-72ba-48f1-bf82-7060d1cec401o@googlegroups.com>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!goblin1!goblin3!goblin.stu.neva.ru!news.misty.com!border2.nntp.dca1.giganews.com!nntp.giganews.com!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>Show Full Headers
Complete Article Headers
X-Received: by 2002:a0c:e941:: with SMTP id n1mr21867971qvo.105.1591611957848; Mon, 08 Jun 2020 03:25:57 -0700 (PDT) X-Received: by 2002:a05:620a:4d8:: with SMTP id 24mr9269643qks.219.1591611957545; Mon, 08 Jun 2020 03:25:57 -0700 (PDT) Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!newsfeed.pionier.net.pl!goblin1!goblin3!goblin.stu.neva.ru!news.misty.com!border2.nntp.dca1.giganews.com!nntp.giganews.com!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 03:25:57 -0700 (PDT) In-Reply-To: <7cd03711-5fee-4322-b02a-c803fcf43b31o@googlegroups.com> Complaints-To: groups-abuse@google.com Injection-Info: google-groups.googlegroups.com; posting-host=131.228.2.21; posting-account=VFwkXwoAAADdT4-lLKRZrMYkTjizGoyn NNTP-Posting-Host: 131.228.2.21 References: <d423a072-9378-441b-ba06-e0657a1fa53bo@googlegroups.com> <3e267b62-0fdf-41c2-9f9c-c316f98b85c6o@googlegroups.com> <7cd03711-5fee-4322-b02a-c803fcf43b31o@googlegroups.com> User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <a0edbb57-72ba-48f1-bf82-7060d1cec401o@googlegroups.com> Subject: Re: Embedded HTTP Server From: Wojciech Muła <wojtek.mula@gmail.com> Injection-Date: Mon, 08 Jun 2020 10:25:57 +0000 Lines: 127 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit