Did you know ... | Search Documentation: |
![]() | Making your web-server scalable |
Using SWI-Prolog 5.9.x, you can create web-servers that handle significant numbers of concurrent clients. Older versions of SWI-Prolog have severe limits on the number of threads and scale much worse.
The concurrency model of the server is organised as follows.
workers(Count)
argument of http_server/2:
..., http_server(http_dispatch, [ workers(10) ]),
In addition to the above model, a worker can spawn a new thread to
complete the request while the worker returns to the acceptor-queue.
This can be achieved in two ways: by `hand' using http_spawn/2 or
centralised using the option spawn(+Spec)
in the option-list of
http_handler/3. This mechanism can create threads in two ways: unbounded
or bounded by a dynamic pool. Unbounded creation carries the risk of
running out of resources. Pool-bounded creation is therefore often the
way to go.
Pools are created using thread_pool_create/3. A pool has a name, maximum number of workers and some additional parameters. Using multiple pools, we can create separate bounds for different tasks of the server, such as CPU intensive tasks or tasks sending large files. You do not want too many concurrent users with CPU intensive jobs, while you may want many concurrent users that merely download large files (an operation that can take long if the connection is slow). Here is a simple example with two pools:
:- use_module(library(thread_pool)). :- thread_pool_create(compute, 10, []). :- thread_pool_create(media, 100, []). :- http_handler('/solve', solve, [spawn(compute)]). :- http_handler('/files', serve_files, [spawn(media)]).
Attached, you find scale.pl. The file is commented and handles the following topics:
If you run this demo, it is advised to run the thread-monitor. This can be started from the plwin.exe menu or by typing:
?- prolog_ide(thread_monitor).
NOTE thread-specific CPU-time statistics are not provided on MacOS. If you know a way to get this figure from the OS, please let us know.