---
myst:
html_meta:
"description": ""
"property=og:description": ""
"property=og:title": ""
"keywords": ""
---
# `Bjoern`
[bjoern](https://github.com/jonashaag/bjoern) is an HTTP/1.1 WSGI Server for CPython2 and 3 written in C.
It claims to be the fastest, smallest and most lightweight WSGI server.
```{note}
In a [load test](https://zope.readthedocs.io/en/latest/operation.html#test-criteria-for-recommendations) involving `bjoern`, `cheroot`, `gunicorn`, `waitress` and `werkzeug`, `bjoern` (version: 3.0.0) was the clear speed winner against both a ZEO and a non-ZEO Zope instance.
```
## Prerequisites
`Bjoern` uses `libev` and you will need to install both the library and the development header files on your box:
```shell
$ sudo apt install libev-dev
```
## Use `bjoern` in our buildout
````{sidebar} Build now
Run buildout for this section:
```shell
buildout -c bjoern.cfg
```
````
[bjoern](https://github.com/jonashaag/bjoern) can be integrated using a shim package called [dataflake.wsgi.bjoern](https://dataflakewsgibjoern.readthedocs.io/en/latest/).
You can use this package together with `plone.recipe.zope2instance` to build a `bjoern` based WSGI setup:
```ini
[instance]
recipe = plone.recipe.zope2instance
user = admin:admin
zeo-client = on
zeo-address = 8100
shared-blob = on
blob-storage = ${buildout:directory}/var/blobstorage
eggs =
Plone
wsgitraining.site
dataflake.wsgi.bjoern
wsgi-ini-template = ${buildout:directory}/templates/bjoern.ini.in
```
In addition to adding `dataflake.wsgi.bjoern` to the `eggs` list we specify the location of our `bjoern.ini` configuration file.
Note that this file is not automatically created for us, we have to provide it ourself.
In addition to the PasteDeploy entry point and the p.r.zope2instance integration, `dataflake.wsgi.bjoern` provides facilities to create a set of Zope configuration files for `bjoern` with the included `kbjoerninstance` utility.
We will however not use this option since it is easier to provide a custom template for the `wsgi.ini` file to `plone.recipe.zope2instance`.
A suitable template is included in the buildout for the training (file `bjoern.ini.in` in the `templates` folder).
It is basically a copy from the template contained in the buildout recipe with a slightly changed `[server:main]` section:
```ini
[server:main]
use = egg:dataflake.wsgi.bjoern#main
listen = %(http_address)s
reuse_port = True
```
````{note}
Let's run some checks in order to verify that `bin/instance` actually invokes bjoern:
Let's first find the processes' PID:
```console
$ ps -ef | grep wsgi.ini
thomas 20009 20006 0 10:26 pts/1 00:00:22 /home/thomas/devel/plone/minimal52/bin/python /home/thomas/devel/plone/minimal52/parts/instance/bin/interpreter /home/thomas/.buildout/eggs/cp37m/Zope-4.1.1-py3.7.egg/Zope2/Startup/serve.py /home/thomas/devel/plone/minimal52/parts/instance/etc/wsgi.ini -d debug-mode=on
```
Using the above PID we can check the process map to see whether bjoern's C extension has been loaded:
```console
thomas@blake:~$ pmap 17245 | grep bjoern
17245: /home/thomas/devel/plone/minimal52/bin/python /home/thomas/devel/plone/minimal52/parts/instance/bin/interpreter /home/thomas/.buildout/eggs/cp37m/Zope-4.1.1-py3.7.egg/Zope2/Startup/serve.py /home/thomas/devel/plone/minimal52/etc/bjoern.ini -d debug-mode=on
00007f7537fa5000 44K r-x-- _bjoern.cpython-37m-x86_64-linux-gnu.so
00007f7537fb0000 2048K ----- _bjoern.cpython-37m-x86_64-linux-gnu.so
00007f75381b0000 4K r---- _bjoern.cpython-37m-x86_64-linux-gnu.so
00007f75381b1000 4K rw--- _bjoern.cpython-37m-x86_64-linux-gnu.so
```
````
### Exercise 1
Additional PasteDeploy entrypoints are available for the [werkzeug entrypoints](https://pypi.org/project/dataflake.wsgi.werkzeug) and [cheroot entrypoints](https://pypi.org/project/dataflake.wsgi.cheroot) WSGI servers.
Pick one and use it to run Plone behind [werkzeug](https://palletsprojects.com/p/werkzeug/) or [cheroot](https://cheroot.cherrypy.dev/en/latest/).
````{dropdown} Solution
:animate: fade-in-slide-down
:icon: question
**cheroot:**
You will need to create two files, an `.ini` template and the buildout configuration.
As a starting point, copy `bjoern.cfg` to `cheroot.cfg` and `templates/bjoern.ini.in` to `templates/cheroot.ini.in` in your buildout directory:
```shell
$ cp bjoern.cfg cheroot.cfg
$ cp templates/bjoern.ini.in templates/cheroot.ini.in
```
Then edit the files so they pull in `cheroot` as WSGI server rather than bjoern.
`cheroot.cfg`:
```{code-block} ini
:emphasize-lines: 11-12
[instance]
recipe = plone.recipe.zope2instance
user = admin:admin
zeo-client = on
zeo-address = 8100
shared-blob = on
blob-storage = ${buildout:directory}/var/blobstorage
eggs =
Plone
wsgitraining.site
dataflake.wsgi.cheroot
wsgi-ini-template = ${buildout:directory}/templates/cheroot.ini.in
```
And `templates/cheroot.ini.in`:
```{code-block} ini
:emphasize-lines: 1-4
[server:main]
use = egg:dataflake.wsgi.cheroot#main
host = localhost
port = 8080
[app:zope]
```
Note that the `dataflake.wsgi.cheroot` shim doesn't understand either `reuse_port` nor `listen`.
This means we cannot use the `http-address` parameter passed by `plone.recipe.zope2instance`.
We resolve to specifying host and port in the template instead.
`dataflake.wsgi.cheroot` accepts a couple of other options in the `.ini` file that we will not consider for this exercise.
Next run buildout with the new configuration:
```shell
(wsgitraining) $ buildout -c cheroot.cfg
```
You can now start your instance as usual:
```shell
(wsgitraining) $ bin/instance fg
2019-10-07 12:43:08,856 INFO [Zope:45][MainThread] Ready to handle requests
Starting server in PID 3906.
```
**werkzeug:**
For `werkzeug` the steps are pretty much the same.
Copy the configuration files:
```shell
$ cp bjoern.cfg werkzeug.cfg
$ cp templates/bjoern.ini.in templates/werkzeig.ini.in
```
Edit them.
`werkzeug.cfg`:
```{code-block} ini
:emphasize-lines: 11-12
[instance]
recipe = plone.recipe.zope2instance
user = admin:admin
zeo-client = on
zeo-address = 8100
shared-blob = on
blob-storage = ${buildout:directory}/var/blobstorage
eggs =
Plone
wsgitraining.site
dataflake.wsgi.werkzeug
wsgi-ini-template = ${buildout:directory}/templates/werkzeug.ini.in
```
`templates/werkzeug.ini.in`:
```{code-block} ini
:emphasize-lines: 1-4
[server:main]
use = egg:dataflake.wsgi.werkzeug#main
host = localhost
port = 8080
[app:zope]
```
After running `buildout -c werkzeug.cfg` you can start your Plone instance:
```shell
(wsgitraining) $ bin/instance fg
2019-10-07 12:58:54,660 INFO [Zope:45][MainThread] Ready to handle requests
Starting server in PID 4337.
2019-10-07 12:58:54,661 INFO [werkzeug:122][MainThread] * Running on http://localhost:8080/ (Press CTRL+C to quit)
```
Like the `cheroot` shim, `dataflake.wsgi.werkzeug` accepts a couple of additional options in the `.ini` file that we will not use here.
````