--- /dev/null
+[[!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
+<http://127.0.0.1:8000/osp/myserver/count>.
+
+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í.