About this site
The idea to start the project came into my head while I was on a vacation in Amsterdam. What a wonderful city! That magical and unreal combination of beautiful old architecture, high-tech and nature! š
Iāve been long interested in procedural content generation in general, and map generation in particular, and all kinds of process simulation. I usually acted as a theorist, but when it came to implement something I took the tool I was the most proficient with ā JVM, and with a high degree of perfectionism I was designing the system architecture, polish to perfection, until my enthusiasm was gone. So nothing was coming out and I had to find my way, fight perfectionism, find tools that make it faster to get results, and thank you crew4ok for keeping shouting on me āGET SHIT DONE!!!ā :D. Now, Iāve stopped upon Python as it suits me because there are so many scientific libraries in its ecosystem implementing all kinds of algorithms and data structures (often in C/C++ making them really fast). The only thing that I am missing is strong typing, but still you can attach it to Python if you want. Python greatly shortens the time period from the idea to implementation and reserve of enthusiasm is spent more efficiently.
So, on my way to Amsterdam and back I was reading some articles and blog posts about landscape and world map generation. As it turned out, not as few people are interested in the subject as I expected. They were writing about different approaches and ideas theyāve tried and what theyāve got out of them. But what Iāve noticed is that in the Summary section some of the authors were saying that one of the most useful ideas in their experiments was blogging. It forced them getting deeper into the subject, filling the gaps in their knowledge and organizing it in their heads so they can publish that knowledge in text form. Also it was motivating not to give up the project. So Iāve decided to try blogging myself despite my introversion š .
Just as always I was not looking for easy ways and havenāt registered an account on Blogspot or somewhere else, but inspired by motherfuckingwebsite.com, bettermotherfuckingwebsite.com and thebestmotherfucking.website I decided to set up my own server with light and fast back-end and same light and fast front-end. Herewith I didnāt feel like supporting all browsers altogether, so Iāve limited support to Firefox and Chrome not to support ancient revolting mammoth poop like IE.
My main work tools in the recent time are Kotlin and Python
, and my favorite language, undoubtedly, is Rust
. Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety. I didnāt like using JVM-based languages because Iāve simply got tired of them, and there are not that many variants of the technology: thatās either bare netty, or relatively heavy servers like vertx or Tomcat/jetty+Spring MVC. And I wouldnāt sleep well if my blog that by design should efficiently use computing resources was written in interpreted language such as Python
. In this way, I was happy to exclude all options to make Rust win š. According to the arewewebyet.org at the moment there are a few web frameworks in Rustās ecosystem. At first I was looking at Rocket just because I like how routes are specified with directives above functions and negligible amount of boilerplate to write. But while I was writing this post Iāve stumbled upon a benchmark that showed Rocket sucks at performance. Instead there was a leader in rust called actix-web (see actix-raw).
At first I almost did everything as is customary: posts are in database, registration, comments, etc. But roughly weighing how much effort it will take, and recent GDPR issues which I didnāt want do deal with⦠I even was lazy to set up and support a database. So I decided to put posts under version control and leave everything that is needed to run the blog here: github.com/vstepchik/mold-web.
Of course, I had thoughts that if I have no registration, comments, but only static blog posts, I don't need any dynamic server. Just take Nginx, a bunch of HTML and CSS files and go. But no, itās boring! Besides that, Iād have to implement one of the conceived features with JavaScript: the day/night theme switcher. There is too much entropy in this world to write even more JS. I confess, I still had to write one line of JavaScript to make that feature work: switching the day/night color theme. This line contains single expression that toggles the night CSS class on the html element and sets the corresponding cookie so the server would know if it needs to render pages with the night theme when you visit another page. I like it more than the JS solution: page loads always light, and then when JS is loaded, it checks the cookie and sets the corresponding class. It also may cause some irritating blinking on some devices when navigating the website.
As I wrote above, Iāve chosen actix-web as a web server, the pages are stored as templates, and are rendered on the server side, they contain single JS line of code, and a tiny bit of CSS so your eyes wonāt bleed. All the UI graphics is SVG and favicon.ico is generated in several sizes out of SVG too. Iāve chosen Maud as a template engine - I like how it accepts macros as Rust templates and bakes them into static strings at compile time. It all sounds good and well, like it will run fast and take little space, but I was not satisfied yet and thought that if templates are baked into binary file, it would be cool to also include all the static resources into it! All of them: styles, graphics, fonts, whatever. And it turned out there is a library for that: includedir. No sooner said then done. The includedir crate takes contents of specified directory and puts it into a binary as byte arrays which are mapped by their relative paths with the phf crate. So Iāve used the phf crate to map articles by their path-id as well.
The compiled binary of the Rocket version took around 4Mb disk space because Rust by default does static linking with the all dependencies required to run, which is exactly what I wanted. But I thought I could make the file even smaller. Among all optimization options tried, the most helpful was enabling link time optimization, as it decreased the file size to 1.4Mb, so Iāve turned it on for release builds. Thereās another tool called UPX that compressed the binary to only around 900Kb. But how I was surprised when the debug build in actix-web variant took 70Mb! Fortunately, the release build took only 5.8Mb and UPX-packed variant just 2Mb.
When I was done with the blog server, I got curious about how good is the actix-web+maud bundle in terms of performance. To test the latency I took the WRK Toolkit and ran the server on the following setup:
The test lasted for 5 minutes from my laptop connected via LAN, utilizing 8 cores and 10 000 concurrent connections, and shown the following results:
# wrk -c 10000 -t 8 -d 300 --latency http://192.168.1.5:80
Running 5m test @ http://192.168.1.5:80
8 threads and 10000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 45.93ms 28.09ms 703.36ms 97.10%
Req/Sec 10.60k 3.13k 20.04k 74.83%
Latency Distribution
50% 41.55ms
75% 46.64ms
90% 50.17ms
99% 248.66ms
25305739 requests in 5.00m, 23.90GB read
Socket errors: connect 0, read 189, write 12017, timeout 0
Requests/sec: 84333.95
Transfer/sec: 81.55MBThe hecking 84K req/sec! And 90% of the requests finished in under 50ms! There are only 12K unsuccessful requests out of 25M total (0.048%) under such a load. Under the same conditions Rocket was serving 21K req/sec while 90% of the requests finished in under 368ms and much higher error rate.
The server job was to parse the HTTP request, properly route it, read the theme cookie, render the page template with dynamic article list and theme considered, and return the response. Actix-web, in contrast to Rocket, did the gzip compression of the responses as well.
As a summary, I was satisfied with this experience. I love how the blog server performs, love the design, and thoughts about this blog pushed me to finish this job to the end š.