Skip to content

Commit

Permalink
wip: failed-76% >800ms-17% >1200ms-6%
Browse files Browse the repository at this point in the history
  • Loading branch information
lukas8219 committed Aug 15, 2023
1 parent b374c30 commit 7e0d606
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 24 deletions.
4 changes: 3 additions & 1 deletion Dockerfile
Expand Up @@ -3,4 +3,6 @@ FROM node:18.12.1-alpine
COPY . .
RUN npm ci

CMD ["node", "index.js"]
RUN npm install pm2 -g

CMD ["pm2-runtime", "--instances", "4", "index.js"]
10 changes: 5 additions & 5 deletions database.js
Expand Up @@ -49,7 +49,7 @@ module.exports.db = async function createConnection() {

module.exports.insertPerson = async function ({ apelido, nome, nascimento, stack }) {
const stackRaw = (stack || []);
const stackValue = stackRaw.length ? `ARRAY[${stackRaw.filter(Boolean).map((s) => `'${stack}'`)}]` : null;
const stackValue = stackRaw.length ? `ARRAY[${stackRaw.map((s) => `'${s}'`).join(',')}]` : null;
const query = `
INSERT INTO
pessoas(
Expand Down Expand Up @@ -94,9 +94,9 @@ module.exports.findByTerm = async function findByTerm(term) {
FROM
pessoas
WHERE
to_tsvector('english', apelido) @@ to_tsquery('${term}:*')
OR to_tsvector('english', nome) @@ to_tsquery('${term}:*')
OR to_tsvector(array_to_string(stack, ' ')) @@ to_tsquery('${term}:*')
to_tsvector('english', apelido) @@ plainto_tsquery('"${term}":*')
OR to_tsvector('english', nome) @@ plainto_tsquery('"${term}":*')
OR to_tsvector(array_to_string(stack, ' ')) @@ plainto_tsquery('"${term}":*')
LIMIT 50;`
return pool.query(query);
}
Expand Down Expand Up @@ -127,7 +127,7 @@ process.env.BATCH === 'true' ? (() => {
});
};
if (queue) {
logger.info(`${moduleKey} has been queued: for args ${key}`);
logger.debug(`${moduleKey} has been queued: for args ${key}`);
return queue.push(cb);
}
batchItems[moduleKey].set(key, new Array([cb]));
Expand Down
16 changes: 10 additions & 6 deletions docker-compose.yaml
Expand Up @@ -11,37 +11,41 @@ services:
deploy:
resources:
limits:
cpus: '0.75'
cpus: '0.50'
memory: '0.5GB'
app1:
image: lukas8219/rinha-be-2023-q3:latest
environment:
DB_URL: "postgres://postgres:12345678@postgres:5432/postgres"
BATCH: "true"
CLUSTER: "false"
CLUSTER: "true"
PINO_LOG_LEVEL: "error"
REQ_TIMEOUT: "10000"
ports:
- "8080"
depends_on:
- postgres
deploy:
resources:
limits:
cpus: '0.25'
cpus: '0.45'
memory: '0.5GB'
app2:
image: lukas8219/rinha-be-2023-q3:latest
environment:
DB_URL: "postgres://postgres:12345678@postgres:5432/postgres"
BATCH: "true"
CLUSTER: "false"
CLUSTER: "true"
REQ_TIMEOUT: "10000"
PINO_LOG_LEVEL: "error"
ports:
- "8080"
depends_on:
- postgres
deploy:
resources:
limits:
cpus: '0.25'
cpus: '0.45'
memory: '0.5GB'
nginx: # Load Balancer
image: nginx:latest
Expand All @@ -55,5 +59,5 @@ services:
deploy:
resources:
limits:
cpus: '0.25'
cpus: '0.1'
memory: '0.5GB'
19 changes: 16 additions & 3 deletions index.js
Expand Up @@ -8,16 +8,18 @@ const os = require('os');
const cluster = require('cluster');
const process = require('process');

const TIMEOUT = Number(process.env.REQ_TIMEOUT) || 5000;
process.env.UV_THREADPOOL_SIZE = os.cpus().length

const app = express();

app.use(bodyParser.json())


app.post('/pessoas', validateBody, async (req, res, next) => {
try {
await insertPerson(req.body);
return res.json(req.body);
return res.status(201).json(req.body);
} catch(err) {
return next({ status: 422, err });
}
Expand Down Expand Up @@ -66,11 +68,22 @@ if(cluster.isPrimary && process.env.CLUSTER === 'true'){
}

cluster.on('exit', (worker, code, signal) => {
console.log(`index.js: worker ${worker.process.pid} died: code ${code} signal ${signal}`);
logger.info(`index.js: worker ${worker.process.pid} died: code ${code} signal ${signal}`);
});
} else {
app.listen(8080, () => {
const serverApp = app.listen(8080, () => {
logger.info(`index.js:${process.pid}:Listening on 8080`);
});


if(process.env.USE_TIMEOUT === 'true'){
serverApp.setTimeout(TIMEOUT)
logger.info(`Starting with timeout as ${TIMEOUT}ms`)

serverApp.on('timeout', (socket) => {
logger.warn(`Timing out connection`);
socket.end();
})
}
}

7 changes: 6 additions & 1 deletion logger.js
@@ -1,3 +1,8 @@
const pino = require('pino');

module.exports.logger = pino();
module.exports.logger = pino({
disabled: !!process.env.NOLOG,
minLength: 4096, // Buffer before writing
sync: false, // Asynchronous logging,
level: process.env.PINO_LOG_LEVEL || 'debug',
});
24 changes: 19 additions & 5 deletions middleware.js
@@ -1,6 +1,6 @@
const { logger } = require("./logger");
const _ = require('lodash');
const { promisify } = require('util');
const { logger } = require('./logger');
const moment = require('moment');

module.exports.validateBody = async function validate(req, res, next){
const { apelido, nome, nascimento, stack } = req.body;
Expand Down Expand Up @@ -46,26 +46,40 @@ module.exports.validateBody = async function validate(req, res, next){
})
}

if(nascimento.length && !moment(nascimento, 'YYYY-MM-DD').isValid()){
res.status(422);
return res.json({
error: 'nascimento invalido'
})
}

if(!_.isUndefined(stack) && !Array.isArray(stack)){
res.status(422);
return res.json({
error: 'stack precisa ser uma array'
})
}

if(stack && stack.length && stack.some((s) => s === undefined || s === null || s === "" || !_.isString(s))){
if(stack&& stack.length && stack.some((s) => s === undefined || s === null || s === "" || !_.isString(s))){
res.status(422);
return res.json({
error: 'stack com item invalido'
})
}

if(stack && stack.length && stack.some((s) => s.length > 32)){
res.status(422);
return res.json({
error: 'stack com item maior que 32 caracteres'
})
}

return await next();
}

module.exports.errorHandler = function clientErrorHandler (err, req, res, next) {
logger.error(`Something failed`, err);
logger.error(err);``
//logger.error(`Something failed`, err);
//logger.error(err);``
res
.status(err.status || 500)
.send({ error: err.err || 'Something failed' })
Expand Down
8 changes: 7 additions & 1 deletion nginx.conf
@@ -1,13 +1,19 @@
worker_rlimit_nofile 40960;

events {
# configure como quiser
worker_connections 20480;
}

http {

upstream api {
server app1:8080;
server app2:8080;
}

server {
listen 9999;
access_log on;
location / {
proxy_pass http://api;
}
Expand Down

0 comments on commit 7e0d606

Please sign in to comment.