From 58babbcbf4b16ede8b4a2c8b37ea3fc91e892b2d Mon Sep 17 00:00:00 2001 From: eletroswing Date: Wed, 7 Feb 2024 14:09:43 -0300 Subject: [PATCH 1/2] add participant: eu_fountai --- participantes/eu_fountai/README.md | 18 +++ participantes/eu_fountai/docker-compose.yml | 56 +++++++++ participantes/eu_fountai/inti.sql | 126 ++++++++++++++++++++ participantes/eu_fountai/nginx.conf | 22 ++++ 4 files changed, 222 insertions(+) create mode 100644 participantes/eu_fountai/README.md create mode 100644 participantes/eu_fountai/docker-compose.yml create mode 100644 participantes/eu_fountai/inti.sql create mode 100644 participantes/eu_fountai/nginx.conf diff --git a/participantes/eu_fountai/README.md b/participantes/eu_fountai/README.md new file mode 100644 index 000000000..6783e0ce0 --- /dev/null +++ b/participantes/eu_fountai/README.md @@ -0,0 +1,18 @@ +# Rinha de Backend 2024-Q1 - Node bombado + +### EuFountai + +Github: [@eletroswing](https://github.com/eletroswing)
+Repositório: [https://github.com/eletroswing/rinha-backend-2024](https://github.com/eletroswing/rinha-backend-2024) + + +### Stack: Node puro com PG + +#### Database +- Postgres + +#### Lib +- Node +- http +- cluster +- pg diff --git a/participantes/eu_fountai/docker-compose.yml b/participantes/eu_fountai/docker-compose.yml new file mode 100644 index 000000000..f0382a1f6 --- /dev/null +++ b/participantes/eu_fountai/docker-compose.yml @@ -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 \ No newline at end of file diff --git a/participantes/eu_fountai/inti.sql b/participantes/eu_fountai/inti.sql new file mode 100644 index 000000000..57253e663 --- /dev/null +++ b/participantes/eu_fountai/inti.sql @@ -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; +$$; \ No newline at end of file diff --git a/participantes/eu_fountai/nginx.conf b/participantes/eu_fountai/nginx.conf new file mode 100644 index 000000000..1793d90af --- /dev/null +++ b/participantes/eu_fountai/nginx.conf @@ -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; + } + } +} \ No newline at end of file From 0ef2e0fb4dc17356e7317a3af90ef8b0fd04b9d0 Mon Sep 17 00:00:00 2001 From: eletroswing Date: Wed, 7 Feb 2024 14:11:10 -0300 Subject: [PATCH 2/2] fix: readme link --- participantes/eu_fountai/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/participantes/eu_fountai/README.md b/participantes/eu_fountai/README.md index 6783e0ce0..598e41966 100644 --- a/participantes/eu_fountai/README.md +++ b/participantes/eu_fountai/README.md @@ -3,7 +3,7 @@ ### EuFountai Github: [@eletroswing](https://github.com/eletroswing)
-Repositório: [https://github.com/eletroswing/rinha-backend-2024](https://github.com/eletroswing/rinha-backend-2024) +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