Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add node-example #42

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions node-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# GraalVM demos: Graal.js application


This repository contains the code for a demo application for [GraalVM](graalvm.org).

## Prerequisites
* [GraalVM](http:https://graalvm.org)

## Preparation

Download or clone the repository and navigate into the `node-example` directory:

```
git clone https://github.com/graalvm/graalvm-demos
cd graalvm-demos/node-example
```

Build the application before running. The application requires python libraries for plotting the graph. You can manually execute all the commands from `build.sh` file line-by-line, but that is more convenient to execute `build.sh` script as it is shown below.

Execute:
```
bash build.sh
```

After this export the GraalVM home directory as the `$GRAALVM_HOME`, e.g.:

```
export GRAALVM_HOME=/home/${USER}/graalvm/graalvm-$GRAALVM_VERSION
```

## Running the application

To run the application, you need to execute the `taylor.js` file. You can run it with the following command (or run the `run.sh` script):

```
$GRAALVM_HOME/bin/node taylor.js
```

Open [localhost:5000](localhost:5000) in your browser to see the output of the example app.

The application tabulates sin(x) function using Taylor series, plots a graph of this function and responses to a client with the image of the graph.

## Benchmarking

You can use `ab` (Apache benchmark) tool for benchmarking while the server is running this way:

```
ab -n 50 localhost:5000/
```

This will perform 50 requests to the server and print results of benchmarking.

## Notes about the application

This application uses [matplotnode](https://www.npmjs.com/package/matplotnode) package to plot the graph. This package requires Python 2.7 and matplotlib installed. Scripts to install them and their dependencies are in `build.sh` file.
8 changes: 8 additions & 0 deletions node-example/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
sudo apt install python-dev
sudo apt-get build-dep python-matplotlib
sudo apt-get install python-pip
sudo apt-get install python-tk
python -m pip install -U pip
sudo python -m pip install -U matplotlib
npm install matplotnode
3 changes: 3 additions & 0 deletions node-example/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

$GRAALVM_HOME/bin/node taylor.js
79 changes: 79 additions & 0 deletions node-example/taylor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
const http = require('http');
const plt = require('matplotnode');
const fs = require('fs');

const file = './plot.png';

//-----------------------Creating-server------------------------------

const server = http.createServer((req, res) => {
plt.close('all');
outputSinGraph(res);
});

const PORT = process.env.PORT || 5000;

server.listen(PORT, () => console.log(`Server running on localhost:${PORT}`));

//-----------------------Evaluating-Taylor-series---------------------

const factorial = x => (x < 1) ? 1 : x * factorial(x - 1);

function outputSinGraph(res) {
let data = {
x : [],
y : []
};

let t1 = getNanoSecTime();
data = tabulateSin(-Math.PI * 4, Math.PI * 4, 0.1);
let time = getNanoSecTime() - t1;
console.log(`\nEvaluations took ${time} nanoseconds.\n`);

function taylorSin(x) {
let sum = 0, n = 0, elem = 1, eps = 0.0000001;

while(Math.abs(elem) > eps) {
elem = Math.pow(-1, n) * (Math.pow(x, 2 * n + 1) / factorial(2 * n + 1));
sum += elem;
n++;
}
return sum;
}

function tabulateSin(left, right, step) {
let x = left;
let d = {
x : [],
y : []
};
while(x <= right) {
let y = taylorSin(x);
console.log(`sin(${Math.round(x * 100) / 100}) = ${Math.round(y * 100000) / 100000} --- actual ${Math.round(Math.sin(x) * 100000) / 100000}`);
d.x.push(x);
d.y.push(y);
x += step;
}
return d;
}


//-----------------------Plotting-graph-------------------------------

plt.title(`Evaluations took ${time} nanoseconds.`);
plt.plot(data.x, data.y, 'color=b', 'label=sin(x)');
plt.legend();

plt.save(file);

let imageStream = fs.createReadStream(file);
res.writeHead(200, {'Content-Type': 'image/png'});
imageStream.pipe(res);
}

//-----------------------Time-measurement-----------------------------

function getNanoSecTime() {
let hrTime = process.hrtime();
return hrTime[0] * 1000000000 + hrTime[1];
}