summaryrefslogtreecommitdiffstats
path: root/_build/content/articles
diff options
context:
space:
mode:
Diffstat (limited to '_build/content/articles')
-rw-r--r--_build/content/articles/cowboy2-performance.asciidoc80
-rw-r--r--_build/content/articles/gun-2.0.0-pre.2.asciidoc59
2 files changed, 139 insertions, 0 deletions
diff --git a/_build/content/articles/cowboy2-performance.asciidoc b/_build/content/articles/cowboy2-performance.asciidoc
new file mode 100644
index 00000000..269be791
--- /dev/null
+++ b/_build/content/articles/cowboy2-performance.asciidoc
@@ -0,0 +1,80 @@
++++
+date = "2020-12-07T07:00:00+01:00"
+title = "Cowboy 2 performance"
+
++++
+
+https://github.com/sponsors/essen[You can now reward my work via GitHub Sponsors].
+
+Recently an article was published by Stressgrid entitled
+https://stressgrid.com/blog/cowboy_performance/[Survey of Cowboy Webserver Performance]
+that compares Cowboy performance across the different versions
+as well as Erlang/OTP versions. The results are not very surprising
+to me personally (although the drop is bigger than I expected),
+but they might be to others.
+
+This prompted an experiment that I will now describe in two parts.
+The first part is about modifying Cowboy to use `active,N` instead
+of `active,once` to reduce the amount of time spent in the TCP
+driver. The second part is about writing a stream handler in order
+to squeeze the most performance out of Cowboy 2.
+
+In order to support both HTTP/1.1 and HTTP/2 with a common interface
+(as well as HTTP/3 in the future), Cowboy 2 switched from the model
+of "one process per connection" to "one process per connection +
+one process per request". This is required because from HTTP/2
+onward requests are processed concurrently rather than sequentially,
+not to mention the protocols include a number of control messages
+that must be handled at the same time.
+
+But this necessarily has some impact on the performance of HTTP/1.1
+connections, and this is what the Stressgrid benchmarks show. Note
+that while I will demonstrate in this article that it is indeed the
+use of multiple processes that causes this reduction in performance,
+I do not really know why this happens, though.
+
+After reading the blog post I started experimenting. I took Cowboy's
+`hello_world` example and added https://github.com/rabbitmq/looking_glass[Looking Glass]
+to the release. I then ran a quick benchmark against the example with
+Looking Glass enabled:
+
+``` erlang
+$ make run
+...
+(hello_world_example@host)1> lg:trace([
+ {app, ranch}, {app, cowlib}, {app, cowboy}, {app, stdlib}
+], lg_file_tracer, "traces.lz4", #{mode => profile, running => true}).
+ok
+... Run the benchmark here for a few seconds.
+(hello_world_example@host)2> lg:stop().
+ok
+(hello_world_example@host)3> lg_callgrind:profile_many("traces.lz4.*", "callgrind.out", #{running => true}).
+ok
+(hello_world_example@host)4> q().
+...
+$ qcachegrind _rel/hello_world_example/callgrind.out
+```
+
+The benchmark can be done with `wrk` for example:
+
+``` bash
+$ wrk -c100 -d10s http://localhost:8080
+```
+
+The benchmark results don't matter, what we want is to see what
+`qcachegrind` tells us about what happened in the system while
+the benchmark was running.
+
+// @todo Need to run the above again in order to extract a picture to put here.
+
+What we can see in the above picture is that around 8% of the
+active time (the time when processes are not waiting for messages)
+is spent in `ranch_tcp:setopts/2`. This is when Cowboy sets
+`active,once`. Turns out this is really expensive, at least
+with synthetic benchmarks, if not more.
+
+A few years ago Steve Vinoski added `active,N` to Erlang/OTP
+to reduce the amount of time spent in the TCP driver. Instead
+of having to call `setops/2` for every packet we want to get
+from the socket, we can tell the driver how many packets we
+want and reduce the number of `setopts/2` calls.
diff --git a/_build/content/articles/gun-2.0.0-pre.2.asciidoc b/_build/content/articles/gun-2.0.0-pre.2.asciidoc
new file mode 100644
index 00000000..441e27aa
--- /dev/null
+++ b/_build/content/articles/gun-2.0.0-pre.2.asciidoc
@@ -0,0 +1,59 @@
++++
+date = "2019-09-27T07:00:00+01:00"
+title = "Gun 2.0 pre-release 2"
+
++++
+
+Gun `2.0.0-pre.2` has been released!
+
+The second pre-release version of Gun 2.0 has been released!
+Gun 2.0 adds a ton of features along with a small number of
+breaking changes.
+
+The main highlight of this pre-release is the support for
+a pluggable cookie store mechanism. Gun 2.0 comes with a
+cookie store engine that can automatically process cookies
+and store them to and retrieve them from a pluggable backend.
+
+Gun 2.0 comes with the `gun_cookies_list` backend which can
+be enabled via the new `cookie_store` option. This backend
+will keep cookies in-memory on a per-connection basis and
+without any persistence built-in. It should however be easy
+to create a backend on top of this one to add persistence
+or share the cookie store backend between multiple connections
+should that be necessary.
+
+The cookie store engine implements the RFC6265bis draft that
+will become a proper RFC in the nearby future and includes
+all the most recent improvements to cookies that modern
+browsers have implemented. Gun is not a browser however so
+some features were skipped (at least for now): there is no
+support for setting cookies from the Erlang side; and there
+is no SameSite checks because Gun does not have a concept of
+a "browsing context".
+
+Please consult the link:/articles/gun-2.0.0-pre.1/[announcement for the first pre-release]
+for information about other Gun 2.0 features.
+
+Gun 2.0 currently requires Erlang/OTP 22 or above and is tested
+and supported on Linux, FreeBSD, macOS and Windows.
+
+A complete
+list of changes can be found in the migration guide:
+https://ninenines.eu/docs/en/gun/2.0/guide/migrating_from_1.3/[Migrating from Gun 1.3 to 2.0].
+
+I will have more free time available for consulting or for
+paid open source development starting from next week. If you
+are interested, drop me an email at mailto:[email protected][[email protected]].
+A feature that may be useful for some of you could be for
+example an implementation for the "Happy Eyeballs" mechanism
+(RFC 8305) as this would allow faster connections to servers
+on dual IPv4 and IPv6 environments.
+
+You can donate to this project via
+https://github.com/sponsors/essen[GitHub Sponsors].
+These funds are used to pay for additional servers for
+testing.
+
+As usual, feedback is appreciated, and issues or
+questions should be sent via Github tickets. Thanks!