mirror of
https://github.com/yldio/copilot.git
synced 2024-11-10 21:30:06 +02:00
metrics-service spike
This commit is contained in:
parent
2945190dbb
commit
3c1780342d
3
spikes/metrics-service/graphql/.gitignore
vendored
Normal file
3
spikes/metrics-service/graphql/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/node_modules
|
||||
/npm-debug.log
|
||||
.idea
|
16
spikes/metrics-service/graphql/package.json
Normal file
16
spikes/metrics-service/graphql/package.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "graphql",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"start": "node src/index.js"
|
||||
},
|
||||
"main": "src/index.js",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"graphql": "^0.7.2",
|
||||
"hapi": "^15.2.0",
|
||||
"hapi-graphql": "^1.0.1",
|
||||
"inert": "^4.0.2",
|
||||
"require-dir": "^0.3.1"
|
||||
}
|
||||
}
|
29
spikes/metrics-service/graphql/src/index.js
Normal file
29
spikes/metrics-service/graphql/src/index.js
Normal file
@ -0,0 +1,29 @@
|
||||
const requireDir = require('require-dir');
|
||||
const plugins = require('./plugins');
|
||||
const routes = requireDir('./routes');
|
||||
const Hapi = require('hapi');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const server = new Hapi.Server();
|
||||
|
||||
server.connection({
|
||||
host: 'localhost',
|
||||
port: 8000
|
||||
});
|
||||
|
||||
server.register(plugins, (err) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
Object.keys(routes).forEach((name) => {
|
||||
routes[name](server);
|
||||
});
|
||||
|
||||
server.start((err) => {
|
||||
server.connections.forEach((conn) => {
|
||||
console.log(`started at: ${conn.info.uri}`);
|
||||
});
|
||||
});
|
||||
});
|
15
spikes/metrics-service/graphql/src/plugins.js
Normal file
15
spikes/metrics-service/graphql/src/plugins.js
Normal file
@ -0,0 +1,15 @@
|
||||
module.exports = [
|
||||
require('inert'), {
|
||||
register: require('hapi-graphql'),
|
||||
options: {
|
||||
query: {
|
||||
pretty: true,
|
||||
graphiql: true,
|
||||
schema: require('./schema')
|
||||
},
|
||||
route: {
|
||||
path: '/graphql'
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
11
spikes/metrics-service/graphql/src/routes/home.js
Normal file
11
spikes/metrics-service/graphql/src/routes/home.js
Normal file
@ -0,0 +1,11 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = (server) => {
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/',
|
||||
handler: (request, reply) => {
|
||||
reply.file(path.join(__dirname, 'index.html'));
|
||||
}
|
||||
});
|
||||
};
|
28
spikes/metrics-service/graphql/src/routes/index.html
Normal file
28
spikes/metrics-service/graphql/src/routes/index.html
Normal file
@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script>
|
||||
const client = fetch('http://localhost:8000/graphql', {
|
||||
method: 'POST',
|
||||
body: `
|
||||
subscription {
|
||||
events(container:"1") {
|
||||
value,
|
||||
when
|
||||
}
|
||||
}
|
||||
`
|
||||
});
|
||||
|
||||
client.then((client) => {
|
||||
debugger;
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
18
spikes/metrics-service/graphql/src/routes/version.js
Normal file
18
spikes/metrics-service/graphql/src/routes/version.js
Normal file
@ -0,0 +1,18 @@
|
||||
const Pkg = require('../../package.json');
|
||||
|
||||
const internals = {
|
||||
response: {
|
||||
version: Pkg.version
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = (server) => {
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/ops/version',
|
||||
config: {
|
||||
description: 'Returns the version of the server',
|
||||
handler: (request, reply) => reply(internals.response)
|
||||
}
|
||||
});
|
||||
};
|
61
spikes/metrics-service/graphql/src/schema.js
Normal file
61
spikes/metrics-service/graphql/src/schema.js
Normal file
@ -0,0 +1,61 @@
|
||||
const graphql = require('graphql');
|
||||
|
||||
const {
|
||||
GraphQLID,
|
||||
GraphQLSchema,
|
||||
GraphQLObjectType,
|
||||
GraphQLString
|
||||
} = graphql;
|
||||
|
||||
const EventType = new GraphQLObjectType({
|
||||
name: 'EventType',
|
||||
fields: {
|
||||
value: {
|
||||
type: GraphQLString
|
||||
},
|
||||
when: {
|
||||
type: GraphQLString
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const EventSubscription = {
|
||||
type: EventType,
|
||||
args: {
|
||||
container: {
|
||||
type: GraphQLID
|
||||
}
|
||||
},
|
||||
start: function() {
|
||||
console.log('start', arguments);
|
||||
},
|
||||
stop: function() {
|
||||
console.log('stop', arguments);
|
||||
},
|
||||
resolve: function() {
|
||||
console.log('resolve', arguments);
|
||||
}
|
||||
};
|
||||
|
||||
const subscription = new GraphQLObjectType({
|
||||
name: 'RootSubscriptionType',
|
||||
fields: {
|
||||
events: EventSubscription
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = new GraphQLSchema({
|
||||
query: new GraphQLObjectType({
|
||||
name: 'Q',
|
||||
fields: {
|
||||
a: { type: GraphQLString },
|
||||
}
|
||||
}),
|
||||
mutation: new GraphQLObjectType({
|
||||
name: 'M',
|
||||
fields: {
|
||||
c: { type: GraphQLString },
|
||||
}
|
||||
}),
|
||||
subscription
|
||||
});
|
3
spikes/metrics-service/http1/.gitignore
vendored
Normal file
3
spikes/metrics-service/http1/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/node_modules
|
||||
/npm-debug.log
|
||||
.idea
|
14
spikes/metrics-service/http1/package.json
Normal file
14
spikes/metrics-service/http1/package.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "http1",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"start": "node src/index.js"
|
||||
},
|
||||
"main": "src/index.js",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"hapi": "^15.2.0",
|
||||
"inert": "^4.0.2",
|
||||
"require-dir": "^0.3.1"
|
||||
}
|
||||
}
|
29
spikes/metrics-service/http1/src/index.js
Normal file
29
spikes/metrics-service/http1/src/index.js
Normal file
@ -0,0 +1,29 @@
|
||||
const requireDir = require('require-dir');
|
||||
const plugins = require('./plugins');
|
||||
const routes = requireDir('./routes');
|
||||
const Hapi = require('hapi');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const server = new Hapi.Server();
|
||||
|
||||
server.connection({
|
||||
host: 'localhost',
|
||||
port: 8000
|
||||
});
|
||||
|
||||
Object.keys(routes).forEach((name) => {
|
||||
routes[name](server);
|
||||
});
|
||||
|
||||
server.register(plugins, (err) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
server.start((err) => {
|
||||
server.connections.forEach((conn) => {
|
||||
console.log(`started at: ${conn.info.uri}`);
|
||||
});
|
||||
});
|
||||
});
|
3
spikes/metrics-service/http1/src/plugins.js
Normal file
3
spikes/metrics-service/http1/src/plugins.js
Normal file
@ -0,0 +1,3 @@
|
||||
module.exports = [
|
||||
require('inert')
|
||||
];
|
11
spikes/metrics-service/http1/src/routes/home.js
Normal file
11
spikes/metrics-service/http1/src/routes/home.js
Normal file
@ -0,0 +1,11 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = (server) => {
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/',
|
||||
handler: (request, reply) => {
|
||||
reply.file(path.join(__dirname, 'index.html'));
|
||||
}
|
||||
});
|
||||
};
|
16
spikes/metrics-service/http1/src/routes/index.html
Normal file
16
spikes/metrics-service/http1/src/routes/index.html
Normal file
@ -0,0 +1,16 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script>
|
||||
var source = new EventSource(`${document.location.origin}/stats`);
|
||||
|
||||
source.onmessage = function(e) {
|
||||
document.body.innerHTML += "Message: " + e.data + '<br />';
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
21
spikes/metrics-service/http1/src/routes/metrics.js
Normal file
21
spikes/metrics-service/http1/src/routes/metrics.js
Normal file
@ -0,0 +1,21 @@
|
||||
let messageId = 0;
|
||||
|
||||
module.exports = (server) => {
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/stats',
|
||||
handler: (request, reply) => {
|
||||
request.raw.res.setHeader('Content-Type', 'text/event-stream');
|
||||
|
||||
const intervalId = setInterval(() => {
|
||||
messageId += 1;
|
||||
|
||||
const str = JSON.stringify({
|
||||
msg: messageId
|
||||
});
|
||||
|
||||
request.raw.res.write(`data:${str}\n\n`);
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
};
|
18
spikes/metrics-service/http1/src/routes/version.js
Normal file
18
spikes/metrics-service/http1/src/routes/version.js
Normal file
@ -0,0 +1,18 @@
|
||||
const Pkg = require('../../package.json');
|
||||
|
||||
const internals = {
|
||||
response: {
|
||||
version: Pkg.version
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = (server) => {
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/ops/version',
|
||||
config: {
|
||||
description: 'Returns the version of the server',
|
||||
handler: (request, reply) => reply(internals.response)
|
||||
}
|
||||
});
|
||||
};
|
3
spikes/metrics-service/http2/.gitignore
vendored
Normal file
3
spikes/metrics-service/http2/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/node_modules
|
||||
/npm-debug.log
|
||||
.idea
|
33
spikes/metrics-service/http2/cert.pem
Normal file
33
spikes/metrics-service/http2/cert.pem
Normal file
@ -0,0 +1,33 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFtTCCA52gAwIBAgIJAK4ScT3ylJVTMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
|
||||
aWRnaXRzIFB0eSBMdGQwHhcNMTYxMTAzMTQyNDIyWhcNMTcxMTAzMTQyNDIyWjBF
|
||||
MQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50
|
||||
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
|
||||
CgKCAgEA6gusYDdyFH9e6iNRT7epiZrGh7R9nwD930d1UM37cZiF5/6oKKY2rP/N
|
||||
pe9qnhC+k1LV2ItEZieEun1k4c+ayFSknWtbC+2tKaX5iNVIeqTKP+f0sG+FRpZk
|
||||
VMPZF4eAKze+BjFZDPoFFkvhKC9MOxEyleSR8cCzSmyhVlrgBTRWhhcSMn2BPh41
|
||||
lnUplVP/43lHUWfgs3Et5EDJihzHDjfw0jo2AZ5KtqlYxQSAMt9Z5UsvYQSRUKvD
|
||||
U7YUqHMUGo5F9wZCrcYyn/KbViiiIygX0A6uHU+0ajUyf2EnR1iJsdZ5oLgG6jyk
|
||||
gCwQcNstXi4JVvthXi5HPmHs+i5H1aAOnMy0t21ssARYiZUq3rSmJ2mPXzJw8SYC
|
||||
SLxCEo3WxBXTDOzzne7kzNl6TC0IHTfGDa80wIa3qitK7PaLQaVrGaFy2ITwt76B
|
||||
414+txdM1JINW4/P1S9jv59zkwYKaoFVGdCvnt33XtAlj7C6sManZLzgxvtHhj9i
|
||||
q//GjWswea2hPTezWcpzxJRVXDzVfJGu/lfoGTnZXSVRSQ5EbKQYbVRL3zI5x0hj
|
||||
MPx+w8vDV88qJgywbBZkRwLaunjAwwPdpuLUwsObc5WuwOMobe+G3ycYqHswQpjc
|
||||
6Mw1158nO4Kdx8DJUq7qyRDk3g7kkvp75cbF1xU4fxNzB3VJD6sCAwEAAaOBpzCB
|
||||
pDAdBgNVHQ4EFgQUyt+QUohMXTlCx4nOaozvYR3wbSowdQYDVR0jBG4wbIAUyt+Q
|
||||
UohMXTlCx4nOaozvYR3wbSqhSaRHMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpT
|
||||
b21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGSCCQCu
|
||||
EnE98pSVUzAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQBAZ4Wvcnoi
|
||||
dAZ3HMBODZTw9E6NZLKgl4aVQiktkCOBOwzJKxkzCrrrr+YQXYx4rHPi85FBevt/
|
||||
NkSsm/Ux+am5iNLjMOW3kDIt1VYYQ6Wn4iPEPUeWzCeyHCOfbG3gOsjDWC1GmWaY
|
||||
WIBi3Zh+7txvrzyhRdNwoS+pAZOzbljCisSDmt1an48tpojI/ZqLD+oGg0LEMuik
|
||||
sBWl227KxyW9DEwLcK9K3I0zhR3NKqWYt47XYvVDq+CqiVI7+/RMwnX/gtIjjGGS
|
||||
5gLdD7mS+Fjig0LtCasDqKYraNQfTAyW3afYITeU4QAKukpJXwwGil3SEP2PxG/y
|
||||
GBz2x6hgQZHB+8VzeA4Zxu5SmLOetJ3yxHRi8NWbiaIn/J+wdRLMjXZ0jTvv86mE
|
||||
VB9X9e0ltvCH/o/VrCOVWHuUXP0zNRawQqYB1qRZ7I7Z/Aes0TQTcQOD/RYUnsfK
|
||||
Mk9XhEpp9IQerufd4e0wlUq6BBA2sN6mkgy57Zsix+LAjU15z0hDRE2xWWNmbakY
|
||||
VBgUTQ8KObAMaSbzUwTildtbsDhtI6pYr8y096NjFiWqkon6R8dveZBfvv5vwoxc
|
||||
h2HTw85eGHyBDcWUe7c7+D+Tp7feNVOeeWtvF7LSRnmTlzqoHdMQ5ns9DxaoUu1Y
|
||||
kbIEE8WnLU0m72Vq5Jzvode8VP3tZpxyvw==
|
||||
-----END CERTIFICATE-----
|
51
spikes/metrics-service/http2/key.pem
Normal file
51
spikes/metrics-service/http2/key.pem
Normal file
@ -0,0 +1,51 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIJKQIBAAKCAgEA6gusYDdyFH9e6iNRT7epiZrGh7R9nwD930d1UM37cZiF5/6o
|
||||
KKY2rP/Npe9qnhC+k1LV2ItEZieEun1k4c+ayFSknWtbC+2tKaX5iNVIeqTKP+f0
|
||||
sG+FRpZkVMPZF4eAKze+BjFZDPoFFkvhKC9MOxEyleSR8cCzSmyhVlrgBTRWhhcS
|
||||
Mn2BPh41lnUplVP/43lHUWfgs3Et5EDJihzHDjfw0jo2AZ5KtqlYxQSAMt9Z5Usv
|
||||
YQSRUKvDU7YUqHMUGo5F9wZCrcYyn/KbViiiIygX0A6uHU+0ajUyf2EnR1iJsdZ5
|
||||
oLgG6jykgCwQcNstXi4JVvthXi5HPmHs+i5H1aAOnMy0t21ssARYiZUq3rSmJ2mP
|
||||
XzJw8SYCSLxCEo3WxBXTDOzzne7kzNl6TC0IHTfGDa80wIa3qitK7PaLQaVrGaFy
|
||||
2ITwt76B414+txdM1JINW4/P1S9jv59zkwYKaoFVGdCvnt33XtAlj7C6sManZLzg
|
||||
xvtHhj9iq//GjWswea2hPTezWcpzxJRVXDzVfJGu/lfoGTnZXSVRSQ5EbKQYbVRL
|
||||
3zI5x0hjMPx+w8vDV88qJgywbBZkRwLaunjAwwPdpuLUwsObc5WuwOMobe+G3ycY
|
||||
qHswQpjc6Mw1158nO4Kdx8DJUq7qyRDk3g7kkvp75cbF1xU4fxNzB3VJD6sCAwEA
|
||||
AQKCAgEAx0w/cgNk6p13totyjx6HiPy6eA6zNjYC+SIBfViZ+CZ4SJCqo0q+nlyJ
|
||||
wvZ35Le/gPZ10RrumMqoFKH4yO0fEd45+y7S7fprjV6feeyc9orjCr47uA6PAAfK
|
||||
0f+gGpAxDRw/fUiCWzGAKXdd+PklwdqoJ8nmmWWNhx+v1zg1MVlbIH3+6e3Do6DX
|
||||
4xJL4bQQ36SDnYeGaWdEO+0LcceFnc73DB2zpXckihz00Xg+rpNRGpcGdmgMUhSh
|
||||
lOQk/ThZcy+Z1nuHRjDTJS7TJfAd+TAH7wzBKYaYzCQWpy+U4gU746sOEVUD1mzj
|
||||
a52aNm/9Vwh+vYn8ZNWlpzJ+OKA2W8sDFGSQFwieRhTQhUC3YWmexmM7tED6b8GW
|
||||
Z0LlIBLwcgka2Jl9YVslPVPZLmWjnA+7mqRoZjfe7R+87ssN64ldPl8JTL+zAw3J
|
||||
UnqPefPZ/rkGsCO22FC9HmvPs55n9itWlZay/Fu/y0X0Ce6yfoqBhdWRR16U/xHL
|
||||
DbeSd/hUaw0HgpM74DAr5wqZA1jJYGxQno+UJOVLA8VPGhASTzQT0h7RHFIZaiOz
|
||||
Aj+HbruY8jR53xSATRGNxszJMh+PY3ZvGWMnb2WrFKEj6vfozcu11UCqL4fzFuJS
|
||||
yCJQI035Sg1ndgq+E55612WJT8w3txjgqoo+XP6vU83oA8CPzdECggEBAPzGmuai
|
||||
XzmEm3Uvt8MA9kw3nBhv50tGG/GNtJ3nHoFNYXzBj5Qez2yyT248aFFMZnbYnJoD
|
||||
Vmm9MJb8uMM6k/zp9U1xc27F39y/Fyxtdpt9OupmylBDkFztRA/L4boItnnCJJ/C
|
||||
oWfTR6rNoPKomw+j4u09W93qWTkt/yMgAUNT9UJSgg1Pmspjq1TeWi9wEh+XeYx9
|
||||
81HZN1uBlpvNLtbvT8KV65mbkLjrSeP96aUXFPBL4hDnJOTNP8Zxi8iL3REJkiUW
|
||||
Tfny68uCIYolEQ8GQuLJmR5z/DkZ3jtmL43bQty1tTeq6XsiMSoS1JibjBEJ+LRg
|
||||
kt43fd5wGjUkvuMCggEBAO0H6Hf9Ty+CtVPnQQAxmHBIyDLcSTmHK6pBQwh+zX9d
|
||||
2jUne3JDVRF2jspWY667f+lf7aUEOjLA3SM/huKulxVHLvEVSmvFWg4LXdStpeIO
|
||||
Xo2FFZjuKjorSuG3MNzn2fzTyPNTX1TYmkvR3v7lQdpx+t9ajOjWoj9bi49uyFPS
|
||||
3lmUcyR9BkDr4tA+ER9Qr2OBFwoXZ+fKO8cu9DV/61EGdmz3Re+l+BO+y0yWmofQ
|
||||
UC92CCMAM/zUCEZS68HNCdld35CULqmCPnUHL30bSDIBa5SHR8HTfwr8lgkekWRw
|
||||
DxhHHQQ7BRepZDvdVqBK90j4g4LAUUUZWf3znucIPpkCggEAW8ALAaP2RH5pnwOP
|
||||
A+0ZeVjGA+i6X4w3IFp7MMVvQSfBNvNbFjyItb+TLUQn6Tp+Bq1hSlXjy8WsGWHp
|
||||
/pMInEifjVicuZyBQTLrSmkBIDc4Z1SgIrojcFd+2Oz8JfZ7pX5epM6Un4cFAG5a
|
||||
+TlR7z9hYxNegRJLCII1lZ5MVw/meghQxFwcp1G+IrQCsC1Rpr3olKIy64aYnVJQ
|
||||
RIUZd1Kt9MdOGRdqVHSzAVpssEvMgdxJVjFQJuyJNZKJVmXN/B0pOuT5sLwH8npt
|
||||
iiMiKf3v0TmzpmYbKu7Ex3Kz2B26Czq5aFdVICitB8SF/k6XbKfd6jsTlC04NsEi
|
||||
AiAwWQKCAQEAmEanU0a6M4SeZ2u+t5glHaW0b/BTXpD3PWa14ORNstChmdpmlS6q
|
||||
nRB0hYrgeWXdtBk7u/KuTOLYboemaUTOrQ3RG3KZIAlmZHVq73IrisG+ft6L1HbV
|
||||
TA96CO4+hvywb5vDkobyTLjmz2TiBRFVsDffetRaiE8zZs6yJxB9xFRJInWbT0q+
|
||||
1MB2M2BccajNNHi/S21kBGZI5xrEKwamL6SeOjzVgjM238CILQjn9+6dRRBoA8xi
|
||||
mb/CHSOycAwAktObB/Aa1i1lYJugJ5h6Vh3Rdlc+g0gTawSAgxVPRJ41JFyzSH9+
|
||||
MwhQ66CzwUDIAuoc2sggrequhNaZNEV4qQKCAQAM8WpFVOZiTQS1wH4trLIO/SkP
|
||||
gYZW0n1JGHKihf5E3/KWkOwEIewPrff1wCjFJYDncbPbV7UqyOGC1qLv5tHSLBQ/
|
||||
sr3e4pAcqHh1bJWjq7+VN41LwPsoQ8EZdHsoS4Nw0zDln0VTKk532b6yisXCvaye
|
||||
zpoWnfPNS6JfL6M1zw+6vLZCEyBO+d8rVo9lCeO+FOI1N84dTZwmZD3K7QubMKco
|
||||
QShjtmygjEpmw02yRF/85mh1ki6f5rklCeJGqgTj8CDQr6uMczC80n5ISXn87uYW
|
||||
HAkErZpC4ZEqsq+ZexAZSJElATogEsfx7psS4UoYfvf52/X8/Idl+MEmY5h6
|
||||
-----END RSA PRIVATE KEY-----
|
17
spikes/metrics-service/http2/package.json
Normal file
17
spikes/metrics-service/http2/package.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "http2",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"start": "node src/index.js"
|
||||
},
|
||||
"main": "src/index.js",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"bunyan": "^1.8.4",
|
||||
"hapi": "^15.2.0",
|
||||
"http2": "^3.3.6",
|
||||
"inert": "^4.0.2",
|
||||
"require-dir": "^0.3.1",
|
||||
"string-to-stream": "^1.1.0"
|
||||
}
|
||||
}
|
40
spikes/metrics-service/http2/src/index.js
Normal file
40
spikes/metrics-service/http2/src/index.js
Normal file
@ -0,0 +1,40 @@
|
||||
const http2 = require('http2');
|
||||
const requireDir = require('require-dir');
|
||||
const plugins = require('./plugins');
|
||||
const routes = requireDir('./routes');
|
||||
const Hapi = require('hapi');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const server = new Hapi.Server();
|
||||
|
||||
server.connection({
|
||||
listener: http2.createServer({
|
||||
key: fs.readFileSync(path.join(__dirname, '../key.pem')),
|
||||
cert: fs.readFileSync(path.join(__dirname, '../cert.pem')),
|
||||
log: require('bunyan').createLogger({
|
||||
name: 'server',
|
||||
stream: process.stdout,
|
||||
serializers: require('http2/lib/http').serializers
|
||||
})
|
||||
}),
|
||||
host: 'localhost',
|
||||
port: 8000,
|
||||
tls: true
|
||||
});
|
||||
|
||||
Object.keys(routes).forEach((name) => {
|
||||
routes[name](server);
|
||||
});
|
||||
|
||||
server.register(plugins, (err) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
server.start((err) => {
|
||||
server.connections.forEach((conn) => {
|
||||
console.log(`started at: ${conn.info.uri}`);
|
||||
});
|
||||
});
|
||||
});
|
3
spikes/metrics-service/http2/src/plugins.js
Normal file
3
spikes/metrics-service/http2/src/plugins.js
Normal file
@ -0,0 +1,3 @@
|
||||
module.exports = [
|
||||
require('inert')
|
||||
];
|
11
spikes/metrics-service/http2/src/routes/home.js
Normal file
11
spikes/metrics-service/http2/src/routes/home.js
Normal file
@ -0,0 +1,11 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = (server) => {
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/',
|
||||
handler: (request, reply) => {
|
||||
reply.file(path.join(__dirname, 'index.html'));
|
||||
}
|
||||
});
|
||||
};
|
25
spikes/metrics-service/http2/src/routes/index.html
Normal file
25
spikes/metrics-service/http2/src/routes/index.html
Normal file
@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script>
|
||||
var source = new EventSource(`${document.location.origin}/stats`);
|
||||
|
||||
source.onmessage = function(e) {
|
||||
document.body.innerHTML += "SSE notification: " + e.data + '<br />';
|
||||
|
||||
// fetch resource via XHR... from cache!
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', e.data);
|
||||
xhr.onload = function() {
|
||||
document.body.innerHTML += "Message: " + this.response + '<br />';
|
||||
};
|
||||
|
||||
xhr.send();
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
38
spikes/metrics-service/http2/src/routes/metrics.js
Normal file
38
spikes/metrics-service/http2/src/routes/metrics.js
Normal file
@ -0,0 +1,38 @@
|
||||
const str = require('string-to-stream');
|
||||
|
||||
let messageId = 0;
|
||||
|
||||
module.exports = (server) => {
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/stats',
|
||||
handler: (request, reply) => {
|
||||
request.raw.res.setHeader('Content-Type', 'text/event-stream');
|
||||
|
||||
const intervalId = setInterval(() => {
|
||||
const resourcePath = `/resource/${messageId}`;
|
||||
|
||||
if (!request.raw.res.push) {
|
||||
clearInterval(intervalId);
|
||||
return;
|
||||
}
|
||||
|
||||
const stream = request.raw.res.push(resourcePath, {
|
||||
status: 200,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
str(JSON.stringify({
|
||||
msg: messageId
|
||||
})).pipe(stream);
|
||||
|
||||
request.raw.res.write(`data:${resourcePath}\n\n`);
|
||||
|
||||
messageId += 1;
|
||||
}, 100);
|
||||
}
|
||||
});
|
||||
};
|
18
spikes/metrics-service/http2/src/routes/version.js
Normal file
18
spikes/metrics-service/http2/src/routes/version.js
Normal file
@ -0,0 +1,18 @@
|
||||
const Pkg = require('../../package.json');
|
||||
|
||||
const internals = {
|
||||
response: {
|
||||
version: Pkg.version
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = (server) => {
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/ops/version',
|
||||
config: {
|
||||
description: 'Returns the version of the server',
|
||||
handler: (request, reply) => reply(internals.response)
|
||||
}
|
||||
});
|
||||
};
|
30
spikes/metrics-service/readme.md
Normal file
30
spikes/metrics-service/readme.md
Normal file
@ -0,0 +1,30 @@
|
||||
# metrics-service
|
||||
|
||||
> A service which produces random streams of data (firehose) of interpretable metric information for various subsystems that can or will be pulled out from a container. These are currently defined in [RFD-0037](https://github.com/joyent/rfd/blob/master/rfd/0037/README.md#default-metric-keys).
|
||||
|
||||
This spike's purpose was to find the best pattern to expose such metrics service with mock data.
|
||||
|
||||
## http1
|
||||
|
||||
+ very simple API to push data from the server to the client
|
||||
+ plain HTTP
|
||||
- requires a connection to each container - because it's not bidirectional, we can't subscribe to more containers on-demand
|
||||
|
||||
## http2
|
||||
|
||||
+ very simple API to push data from the server to the client
|
||||
+ multiplexing
|
||||
- push doesn't really help us, because it's only useful for static resources
|
||||
|
||||
## graphql
|
||||
|
||||
+ common interface between all data resources
|
||||
+ filter received data
|
||||
- api not finalised yet
|
||||
- api not documented
|
||||
|
||||
## ws (with [nes](https://github.com/hapijs/nes))
|
||||
|
||||
+ strong integration with [Hapi](https://github.com/hapijs/hapi)
|
||||
+ allow to subscribe and unsubscribe on-demand on a single connection
|
||||
- some networks might require fallback to pooling
|
3
spikes/metrics-service/ws/.gitignore
vendored
Normal file
3
spikes/metrics-service/ws/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
/node_modules
|
||||
/npm-debug.log
|
||||
.idea
|
16
spikes/metrics-service/ws/package.json
Normal file
16
spikes/metrics-service/ws/package.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "ws",
|
||||
"version": "1.0.0",
|
||||
"scripts": {
|
||||
"start": "node src/index.js"
|
||||
},
|
||||
"main": "src/index.js",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"component-emitter": "^1.2.1",
|
||||
"hapi": "^15.2.0",
|
||||
"inert": "^4.0.2",
|
||||
"nes": "^6.3.1",
|
||||
"require-dir": "^0.3.1"
|
||||
}
|
||||
}
|
29
spikes/metrics-service/ws/src/index.js
Normal file
29
spikes/metrics-service/ws/src/index.js
Normal file
@ -0,0 +1,29 @@
|
||||
const requireDir = require('require-dir');
|
||||
const plugins = require('./plugins');
|
||||
const routes = requireDir('./routes');
|
||||
const Hapi = require('hapi');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const server = new Hapi.Server();
|
||||
|
||||
server.connection({
|
||||
host: 'localhost',
|
||||
port: 8000
|
||||
});
|
||||
|
||||
server.register(plugins, (err) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
Object.keys(routes).forEach((name) => {
|
||||
routes[name](server);
|
||||
});
|
||||
|
||||
server.start((err) => {
|
||||
server.connections.forEach((conn) => {
|
||||
console.log(`started at: ${conn.info.uri}`);
|
||||
});
|
||||
});
|
||||
});
|
30
spikes/metrics-service/ws/src/metric.js
Normal file
30
spikes/metrics-service/ws/src/metric.js
Normal file
@ -0,0 +1,30 @@
|
||||
const Emitter = require('component-emitter');
|
||||
|
||||
const cdm = {};
|
||||
|
||||
module.exports = (server) => ({
|
||||
on: (id) => {
|
||||
if (cdm[id]) {
|
||||
cdm[id].sockets +=1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
let messageId = 0;
|
||||
const interval = setInterval(() => {
|
||||
server.publish(`/stats/${id}`, {
|
||||
id: messageId += 1
|
||||
});
|
||||
}, 500);
|
||||
|
||||
cdm[id] = {
|
||||
interval,
|
||||
sockets: 1
|
||||
};
|
||||
},
|
||||
off: (id) => {
|
||||
if (!(cdm[id].sockets -= 1)) {
|
||||
clearInterval(cdm[id].interval);
|
||||
}
|
||||
}
|
||||
});
|
4
spikes/metrics-service/ws/src/plugins.js
Normal file
4
spikes/metrics-service/ws/src/plugins.js
Normal file
@ -0,0 +1,4 @@
|
||||
module.exports = [
|
||||
require('inert'),
|
||||
require('nes')
|
||||
];
|
11
spikes/metrics-service/ws/src/routes/home.js
Normal file
11
spikes/metrics-service/ws/src/routes/home.js
Normal file
@ -0,0 +1,11 @@
|
||||
const path = require('path');
|
||||
|
||||
module.exports = (server) => {
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/',
|
||||
handler: (request, reply) => {
|
||||
reply.file(path.join(__dirname, 'index.html'));
|
||||
}
|
||||
});
|
||||
};
|
33
spikes/metrics-service/ws/src/routes/index.html
Normal file
33
spikes/metrics-service/ws/src/routes/index.html
Normal file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script src="https://unpkg.com/nes@6.3.1"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script>
|
||||
const client = new window.nes.Client('ws://localhost:8000');
|
||||
|
||||
client.connect((err) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
console.log('connected');
|
||||
|
||||
client.subscribe('/stats/5', (update, flag) => {
|
||||
console.log(update, flag);
|
||||
}, (err) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
console.log('subscribed');
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
18
spikes/metrics-service/ws/src/routes/metrics.js
Normal file
18
spikes/metrics-service/ws/src/routes/metrics.js
Normal file
@ -0,0 +1,18 @@
|
||||
const Metric = require('../metric');
|
||||
|
||||
module.exports = (server) => {
|
||||
const metric = Metric(server);
|
||||
|
||||
server.subscription('/stats/{id}', {
|
||||
onSubscribe: (socket, path, params, next) => {
|
||||
console.log('onSubscribe');
|
||||
metric.on(params.id);
|
||||
next();
|
||||
},
|
||||
onUnsubscribe: (socket, path, params, next) => {
|
||||
console.log('onUnsubscribe');
|
||||
metric.off(params.id);
|
||||
next();
|
||||
}
|
||||
});
|
||||
};
|
18
spikes/metrics-service/ws/src/routes/version.js
Normal file
18
spikes/metrics-service/ws/src/routes/version.js
Normal file
@ -0,0 +1,18 @@
|
||||
const Pkg = require('../../package.json');
|
||||
|
||||
const internals = {
|
||||
response: {
|
||||
version: Pkg.version
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = (server) => {
|
||||
server.route({
|
||||
method: 'GET',
|
||||
path: '/ops/version',
|
||||
config: {
|
||||
description: 'Returns the version of the server',
|
||||
handler: (request, reply) => reply(internals.response)
|
||||
}
|
||||
});
|
||||
};
|
Loading…
Reference in New Issue
Block a user