-
Notifications
You must be signed in to change notification settings - Fork 923
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #27 from eletroswing/http
Add participant: EuFountai - node http
- Loading branch information
Showing
4 changed files
with
222 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Rinha de Backend 2024-Q1 - Node bombado | ||
|
||
### EuFountai | ||
|
||
Github: [@eletroswing](https://github.com/eletroswing) <br /> | ||
Repositório: [https://github.com/eletroswing/rinha-de-backend-2024-http](https://github.com/eletroswing/rinha-de-backend-2024-http) | ||
|
||
|
||
### Stack: Node puro com PG | ||
|
||
#### Database | ||
- Postgres | ||
|
||
#### Lib | ||
- Node | ||
- http | ||
- cluster | ||
- pg |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
version: "3.5" | ||
|
||
services: | ||
api1: &api | ||
image: founty/rinha-de-backend-2024:latest | ||
hostname: api1 | ||
environment: | ||
- PORT=3000 | ||
- INSTANCES=4 | ||
- BACKLOG=4096 | ||
- DATABASE_URL=postgresql://admin:123@db:5432/rinha | ||
depends_on: | ||
- db | ||
deploy: | ||
resources: | ||
limits: | ||
cpus: "0.4" | ||
memory: 125MB | ||
|
||
api2: | ||
<<: *api | ||
hostname: api2 | ||
|
||
nginx: | ||
image: nginx | ||
container_name: nginx | ||
volumes: | ||
- ./nginx.conf:/etc/nginx/nginx.conf:ro | ||
ports: | ||
- 9999:9999 | ||
depends_on: | ||
- api1 | ||
- api2 | ||
deploy: | ||
resources: | ||
limits: | ||
cpus: '0.2' | ||
memory: '50MB' | ||
|
||
db: | ||
image: postgres:latest | ||
hostname: db | ||
environment: | ||
- POSTGRES_PASSWORD=123 | ||
- POSTGRES_USER=admin | ||
- POSTGRES_DB=rinha | ||
expose: | ||
- "5432" | ||
volumes: | ||
- ./init.sql:/docker-entrypoint-initdb.d/init.sql | ||
command: postgres -c checkpoint_timeout=600 -c max_wal_size=4096 | ||
deploy: | ||
resources: | ||
limits: | ||
cpus: "0.5" | ||
memory: 250MB |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
CREATE TABLE clientes ( | ||
id SERIAL PRIMARY KEY, | ||
nome VARCHAR(50) NOT NULL, | ||
limite INTEGER NOT NULL | ||
); | ||
|
||
CREATE TABLE transacoes ( | ||
id SERIAL PRIMARY KEY, | ||
cliente_id INTEGER NOT NULL, | ||
valor INTEGER NOT NULL, | ||
tipo CHAR(1) NOT NULL, | ||
descricao VARCHAR(10) NOT NULL, | ||
realizada_em TIMESTAMP NOT NULL DEFAULT NOW(), | ||
CONSTRAINT fk_clientes_transacoes_id | ||
FOREIGN KEY (cliente_id) REFERENCES clientes(id) | ||
); | ||
|
||
CREATE TABLE saldos ( | ||
id SERIAL PRIMARY KEY, | ||
cliente_id INTEGER NOT NULL, | ||
valor INTEGER NOT NULL, | ||
CONSTRAINT fk_clientes_saldos_id | ||
FOREIGN KEY (cliente_id) REFERENCES clientes(id) | ||
); | ||
|
||
-- INDEX | ||
CREATE INDEX idx_clientes_id ON clientes (id); | ||
CREATE INDEX idx_transacoes_cliente_id ON transacoes (cliente_id); | ||
CREATE INDEX idx_saldos_cliente_id ON saldos (cliente_id); | ||
|
||
--- STORE PROCEDURE | ||
CREATE OR REPLACE FUNCTION obter_saldo_limite(cliente_id_param INTEGER) | ||
RETURNS JSON AS $$ | ||
DECLARE | ||
resultado JSON; | ||
BEGIN | ||
SELECT json_build_object('saldo', s.valor, 'limite', c.limite) | ||
INTO resultado | ||
FROM saldos s | ||
JOIN clientes c ON s.cliente_id = c.id | ||
WHERE s.cliente_id = cliente_id_param; | ||
|
||
RETURN resultado; | ||
END; | ||
$$ LANGUAGE plpgsql; | ||
|
||
CREATE OR REPLACE FUNCTION obter_extrato(cliente_id_param INTEGER) | ||
RETURNS JSON AS $$ | ||
DECLARE | ||
extrato JSON; | ||
BEGIN | ||
SELECT json_build_object( | ||
'saldo', json_build_object( | ||
'total', (SELECT valor FROM saldos WHERE cliente_id = cliente_id_param), | ||
'data_extrato', NOW(), | ||
'limite', (SELECT limite FROM clientes WHERE id = cliente_id_param) | ||
), | ||
'ultimas_transacoes', COALESCE(( | ||
SELECT json_agg(json_build_object( | ||
'valor', t.valor, | ||
'tipo', t.tipo, | ||
'descricao', t.descricao, | ||
'realizada_em', t.realizada_em | ||
) ORDER BY t.realizada_em DESC) | ||
FROM transacoes t | ||
WHERE t.cliente_id = cliente_id_param | ||
LIMIT 10 | ||
), '[]'::JSON) | ||
) | ||
INTO extrato; | ||
|
||
RETURN extrato; | ||
END; | ||
$$ LANGUAGE plpgsql; | ||
|
||
CREATE OR REPLACE FUNCTION transacao(cliente_id_param INTEGER, valor_param INTEGER, tipo_param CHAR(1), descricao_param VARCHAR(10)) | ||
RETURNS JSON AS $$ | ||
DECLARE | ||
saldo_atual INTEGER; | ||
limite_atual INTEGER; | ||
novo_saldo INTEGER; | ||
resultado JSON; | ||
BEGIN | ||
SELECT valor INTO saldo_atual FROM saldos WHERE cliente_id = cliente_id_param; | ||
SELECT limite INTO limite_atual FROM clientes WHERE id = cliente_id_param; | ||
|
||
IF (valor_param > (saldo_atual + limite_atual)) THEN | ||
resultado := json_build_object('limite', limite_atual, 'saldo', saldo_atual); | ||
ELSE | ||
INSERT INTO transacoes (cliente_id, valor, tipo, descricao) | ||
VALUES (cliente_id_param, valor_param, tipo_param, descricao_param); | ||
|
||
novo_saldo := saldo_atual - valor_param; | ||
|
||
UPDATE saldos SET valor = novo_saldo WHERE cliente_id = cliente_id_param; | ||
|
||
SELECT json_build_object('limite', limite_atual, 'saldo', novo_saldo) INTO resultado; | ||
END IF; | ||
|
||
RETURN resultado; | ||
END; | ||
$$ LANGUAGE plpgsql; | ||
|
||
CREATE OR REPLACE FUNCTION reset_db() | ||
RETURNS VOID AS $$ | ||
BEGIN | ||
DELETE FROM transacoes; | ||
UPDATE saldos SET valor = 0; | ||
END; | ||
$$ LANGUAGE plpgsql; | ||
|
||
--- SEED | ||
DO $$ | ||
BEGIN | ||
INSERT INTO clientes (nome, limite) | ||
VALUES | ||
('user 1', 1000 * 100), | ||
('user 2', 800 * 100), | ||
('user 3', 10000 * 100), | ||
('user 4', 100000 * 100), | ||
('user 5', 5000 * 100); | ||
|
||
INSERT INTO saldos (cliente_id, valor) | ||
SELECT id, 0 FROM clientes; | ||
END; | ||
$$; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
worker_processes auto; | ||
|
||
events { | ||
worker_connections 512; | ||
} | ||
|
||
http { | ||
access_log off; | ||
|
||
upstream api { | ||
server api1:3000; | ||
server api2:3000; | ||
} | ||
|
||
server { | ||
listen 9999; | ||
|
||
location / { | ||
proxy_pass http://api; | ||
} | ||
} | ||
} |