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 1 commit
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
63 changes: 63 additions & 0 deletions node-example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# 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. You can manually execute `npm install plotly`, but there's also a `build.sh` script included for your convenience.

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 [Plotly](https://plot.ly) library to plot the graph. Plotly provides API for plotting graphs, and requires username and API key indicated.

To get username and API key, proceed to the [Plotly](https://chart-studio.plot.ly/settings/api#/) site, log in or sign up, go to Settings->API Keys and click on `Regenerate Key` button. Then copy your username and API key and paste them there, on the top of the `taylor.js` file:

```
const plotly = require('plotly')('username', 'api_key');
```

This API key can be used 1000 times per 24h.
3 changes: 3 additions & 0 deletions node-example/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/usr/bin/env bash

npm install plotly
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
99 changes: 99 additions & 0 deletions node-example/taylor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
const plotly = require('plotly')('username', 'api_key');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the example use plotly offline (without auth) or another graph library that doesn't require accounts?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Plotly cannot be used offline. I'll use another library that doesn't require online accounts

const http = require('http');

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

const server = http.createServer((req, res) => {
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-------------------------------

var layout = {
title: {
text: `Evaluations took ${time} nanoseconds.`,
font: {
family: 'Courier New, monospace',
size: 24
},
xref: 'paper',
x: 0.05,
}
}

var trace1 = {
x: data.x,
y: data.y,
type: "scatter"
};

var figure = {
'data': [trace1],
'layout' : layout
};

var imgOpts = {
format: 'png',
width: 1000,
height: 500
};

plotly.getImage(figure, imgOpts, function (error, imageStream) {
if (error) return console.log (error);
res.writeHead(200, {'Content-Type': 'image/png'});
imageStream.pipe(res);
});
}

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

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