Sirko Engine
It is a solution for supporting users during navigation. Learning how users navigate the engine precaches resources (pages, JS and CSS files) a user might need in a next transition. The precached resources get accumulated for offline use and get served when the user is offline. Precaching resources and offline work improve user's experience and engagement rate.
Motivation and technical details are described in that article.
Currently, this solution is only recommended for pages which meet the following criteria:
- pages aren't too diverse. For instance, if you have online store with lots of products, this solution won't work well. To make correct predictions for a such site, historical data of users' purchases, views and other stuff must be used.
- pages are served over a secure connection (HTTPS). The client part is based on a service worker.
Users on mobile devices
Navigation on mobile devices might be different, thus, to make correct predictions for desktop and mobile users we need to split them in the prediction model. It might be developed later.
Browser support
The solution works in browsers which support service workers.
Table of contents
Installation
There are at least 3 ways to install the engine. The easiest one is to install it with Docker or Docker Compose (it installs Neo4j along with the engine). But, if you have reasons not to use Docker, follow this instruction.
IMPORTANT: The instructions (besides the one about Docker Compose) suppose that Neo4j 3.0 or greater is already installed on your server or you got an account from one of Neo4j cloud hosting providers. If you decide to host a Neo4j instance on your server, please, make sure you have at least 2 Gb of free RAM.
Docker
Install with-
Download a config file:
$ wget https://raw.githubusercontent.com/sirko-io/engine/v0.4.1/config/sirko.conf
-
Define your settings in the config file:
$ nano sirko.conf
-
Launch a docker container:
$ sudo docker run -d --name sirko -p 4000:4000 --restart always -v ~/sirko.conf:/usr/local/sirko/sirko.conf dnesteryuk/sirko:latest
IMPORTANT: If you host the Neo4j instance on your server, you have to be sure the engine has access to it. To do that, use a network argument while launching the container:
$ sudo docker run -d --name sirko -p 4000:4000 --restart always --network host -v ~/sirko.conf:/usr/local/sirko/sirko.conf dnesteryuk/sirko:latest
-
Verify what happens to the engine:
$ sudo docker logs sirko
If you see a message like this:
2017-02-26 10:22:02.551 [info] Expecting requests from http://localhost
the engine is running and it is ready to accept requests.
Docker Compose
Install with-
Download a config file:
$ wget https://raw.githubusercontent.com/sirko-io/engine/v0.4.1/config/sirko.conf
-
Define your settings in the config file:
$ nano sirko.conf
Please, use a
http://neo4j:7687
url for theneo4j.url
setting. -
Create a docker-compose.yml file:
$ nano docker-compose.yml
copy and past the following content:
version: '2' services: neo4j: image: neo4j:3.1.1 restart: always environment: - NEO4J_AUTH=none ports: - "7687:7687" sirko: image: dnesteryuk/sirko:latest restart: always volumes: - ./sirko.conf:/usr/local/sirko/sirko.conf ports: - "4000:4000" links: - neo4j
-
Launch the engine and Neo4j:
$ sudo docker-compose up -d
-
Verify what happens to the engine:
$ sudo docker-compose logs sirko
If you see a message like this:
2017-02-26 10:17:19.408 [info] Expecting requests from http://localhost
the engine is running and it is ready to accept requests.
Install without containers
IMPORTANT: Currently, the compiled version of the engine can only be launched on Debian/Ubuntu x64. If you use another distributive, consider the use of the docker container.
The instruction supposes that you have a ubuntu user, please, don't forget to replace it with an appropriate user for your sever.
-
Download the latest release:
$ wget https://github.com/sirko-io/engine/releases/download/v0.4.1/sirko.tar.gz
-
Unpack the archive:
$ sudo mkdir /usr/local/sirko $ sudo chown ubuntu:ubuntu /usr/local/sirko $ cd /usr/local/sirko $ tar xfz /home/ubuntu/sirko.tar.gz
-
Setup Systemd which will manage the engine:
sudo nano /lib/systemd/system/sirko.service
copy and past the following content:
[Unit] Description=Sirko Engine After=network.target [Service] Type=simple ExecStart=/usr/local/sirko/bin/sirko start ExecStop=/usr/local/sirko/bin/sirko stop Restart=on-failure RemainAfterExit=yes RestartSec=5 User=ubuntu Environment=LANG=en_US.UTF-8 [Install] WantedBy=multi-user.target
Note: You are welcome to use any other alternative to Systemd.
-
Define your settings in a config file:
$ nano /usr/local/sirko/sirko.conf
-
Launch the engine:
$ sudo systemctl daemon-reload $ sudo systemctl enable sirko.service $ sudo systemctl start sirko.service
To make sure, it is successfully launched, check its status:
$ systemctl status sirko.service
If you see a response like this:
โ sirko.service - Sirko Engine Loaded: loaded (/lib/systemd/system/sirko.service; static; vendor preset: enabled) Active: active (running) since Mon 2017-01-23 16:45:01 UTC; 17s ago
the engine is running and it is ready to accept requests.
Nginx virtual host
-
Create a nginx virtual host for the engine:
$ sudo touch /etc/nginx/sites-available/sirko $ sudo ln -s /etc/nginx/sites-available/sirko /etc/nginx/sites-enabled/sirko $ sudo nano /etc/nginx/sites-available/sirko
-
Copy and past the following content:
upstream sirko { server 127.0.0.1:4000; } server{ listen 80; server_name sirko.yourhostname.tld; location / { include proxy_params; proxy_redirect off; proxy_pass http://sirko; } }
-
Restart Nginx:
$ sudo service nginx restart
Client integration
Once you've got the engine installed, you need to integrate the client part of the solution to your site. The sirko client is a JavaScript library which prepares data and sends them to the engine.
To get it in your site, add the following code before </head>
:
<script>
(function(w,m){w[m]=function(){w[m].q.push(arguments);};w[m].q=[];})(window,'sirko');
sirko('engineUrl', '__URL_TO_ENGINE_HERE__');
</script>
<script async src="__URL_TO_ENGINE_HERE__/assets/client.js"></script>
Note: Please, don't forget to replace the placeholder with a real url.
The next step is to serve the service worker script from the root of your domain, example:
http://demo.sirko.io/sirko_sw.js
The easiest way is to proxy the request to the engine. If you use Nginx, here is an example:
# other directives
location = /sirko_sw.js {
proxy_pass http://127.0.0.1:4000/assets/sirko_sw.js;
}
Another way is to copy this script and serve it via your backend.
Once you've integrated the client, visit your site, open a development webtool (F12) and make sure that requests to the engine have status 200. If you use Chrome, click on the Application tab, then click on the Service workers item in the left sidebar. There you should see all registered service workers on your page. You need to find a sirko_sw.js
service worker, it should have the activated and running
state and no errors.
Offline work
By default, all precached resources get removed once the user navigates to a next page. It is a necessary step to avoid shipping stale pages. If you want your site to work offline, you might enable an offline mode by adding:
sirko('offline', true);
to the script block where you've defined the url to the engine. This option means all precached resources should be kept in the cache and served when the user is offline. Only pages which were predicted by the engine will work offline.
If you want to cache the entire site for offline use, you need to open the config/sirko.conf
file and set
# now all pages will pass the threshold
sirko.engine.confidence_threshold = 0
# hopefully, your site has less number of pages than this value
sirko.engine.max_pages_in_prediction = 1000000000
This configuration means that all pages will be fetched whenever the user moves to another page. Even if they are cached, they will be fetched again to keep the most fresh version. The load on your backend might be reduced if you set expiration for your resources, a Fetch API which is used in precaching resources respects the Cache control header.
Getting accuracy
If you want to know accuracy of predictions made for your site, you might integrate the sirko client with a tracking service which is able to track custom events and execute formulas over written data. Use the following code as an example:
<script>
window.onload = function() {
sirko('predicted', function(currentPrediction, isPrevCorrect) {
if (isPrevCorrect !== undefined) {
console.info('The previous prediction was', isPrevCorrect ? 'correct' : 'incorrect');
// call your tracking service here
}
});
};
</script>
Note: The second argument is undefined when it is a first visit of the current user. In this case, there is nothing to track.
The code example uses the onload callback to be sure that all dependencies get loaded, But, the sirko client can be called earlier, just verify the documentation to your tracking service when you can send custom events. Some tracking services can be called without waiting for loading the whole content.
Catching errors
You might want to catch errors which happen to the engine and report them. The engine got integrated with Rollbar which notifies you about errors via an email or a messenger (it supports a few). To start using it, register an account and add your rollbar access token to the sirko.conf
.
License
The project is distributed under the GPLv3 license.