[[!meta title="Obsluha mnoha klientů"]] [[!toc]] Cíl === Hlavním cílem této úlohy je implementovat jednoduchou serverovou aplikaci a optimalizovat její výkon tak, aby zvládala obsluhu velkého množství klientů a požadavků. **Pro implementaci serveru si můžete zvolit jakoukoli platformu** (HW, OS, programovací jazyk, framework, …). Vedlejší cíle jsou naučit se pracovat s dokumentací a zdrojovými kódy použitých platforem (zejména těch založených na open source softwaru), aplikace znalostí nabytých na přednáškách a získání přehledu o výkonnosti jednotlivých platforem. Zadání úkolu ============ Vytvořte serverovou aplikaci komunikující protokolem [HTTP][], která bude sloužit k počítání unikátních slov v datech zaslaných klienty. Na server jsou kladeny následující požadavky: - Klienti posílají data pomocí [metody POST][POST] s cestou `/osp/myserver/data`. Data jsou ve formátu čistého textu (text/plain) v kódování UTF-8. - Server obsahuje "čítač jedinečných slov". Při spuštění serveru je tento čítač roven 0. - Server si vede evidenci o slovech zaslaných v jednotlivých požadavcích a pro každé nové slovo, které ještě nemá v evidenci zvýší čítač jedinečných slov o jedna. - Na požadavek [GET][] s cestou `/osp/myserver/count` server odpoví aktuální hodnotou čítače jedinečných slov a tento čítač vynuluje. Hodnota se přenáší jako dekadické číslo v UTF-8 kódování. - Server musí zvládnou obsluhovat velké množství (cca 100) současně připojených klientů. [HTTP]: http://tools.ietf.org/html/rfc2616 [POST]: http://tools.ietf.org/html/rfc2616#section-9.5 [GET]: http://tools.ietf.org/html/rfc2616#section-9.3 Příklad ------- Předpokládejme, že náš server běží na adrese 127.0.0.1 (t.j. localhost) na portu 8000. Použijeme program `curl` k posílání požadavků serveru: curl 127.0.0.1:8000/osp/myserver/data --data-binary "první pokus" curl 127.0.0.1:8000/osp/myserver/data --data-binary "druhý pokus" curl 127.0.0.1:8000/osp/myserver/count --output - Výstupem posledního příkazu bude řetězec "3". Místo posledního příkazu můžete použít i webový prohlížeč nasměrovaný na adresu . Výkon serveru ------------- Výkon serveru bude měřen testovacím programem, který bude serveru posílat větší množství dat a poté se zeptá na aktuální hodnotu čítače jedinečných slov. Bude se měřit celkový čas od odeslání prvního požadavku typu POST do příjmu hodnoty čítače jedinečných slov. Akceptována budou řešení jejichž **celkový čas bude dvakrát menší** než čas naměřený s níže uvedeným ukázkovým serverem bežícím na školním počítači v laboratoři. Ukázkový server =============== Zde uvádíme jednoduchý server napsaný v jazyce Python, který splňuje výše uvedené požadavky (kromě výkonnosti). Můžete ho použít jako referenci či startovací bod pro vaší implementaci. [[!format py """ #!/usr/bin/python3 from http.server import HTTPServer, BaseHTTPRequestHandler words = {} class OSPHTTPHandler(BaseHTTPRequestHandler): def do_POST(self): global words if self.path == "/osp/myserver/data": length = int(self.headers.get('Content-Length')) text = self.rfile.read(length).decode("utf-8") for word in text.split(): words[word] = 1; self.send_response(204) # No Content self.end_headers() else: self.send_response(404) self.end_headers() def do_GET(self): global words if self.path == "/osp/myserver/count": self.send_response(200) self.send_header("Content-type", "text/plain") self.end_headers() self.wfile.write(str(len(words)).encode()) words = {} else: self.send_response(404) self.end_headers() httpd = HTTPServer(('', 8000), OSPHTTPHandler) print("Listening on port", httpd.server_port) httpd.serve_forever() """]] Testování a měření výkonu ========================= Pro testování připravujeme odevzdávací systém, který bude měřit výkon jednotlivých implementací jak je popsáno výše a bude sestavovat pořadí jednotlivých studentů. Pět nejlepších studentů dostane 1 až 5 bonusových bodů. Odevzdávací systém bude připraven během příštího týdne. Do té doby můžete použít program `osp-server-tester`, který je nainstalován školních počítačích. Pro testování ukázkového serveru spusťte program následovně: osp-server-tester localhost 8000 Pokud testovací program spustíte následovně osp-server-tester localhost 8000 --more ukázkový server bude přetížen a čas od času bude klienty odmítat. Takže prvním krokem vašeho řešení může být zjištění příčiny tohoto chování a její napravení.