> ## Documentation Index
> Fetch the complete documentation index at: https://docs.airys.chat/llms.txt
> Use this file to discover all available pages before exploring further.

# Otimizando Configurações

> Guia de otimização de desempenho para implantações auto-hospedadas do AirysChat

Este documento ajuda você a ajustar vários valores de configuração disponíveis no AirysChat para extrair o desempenho máximo da sua Instalação do AirysChat.

## Puma

O AirysChat usa o [Puma](https://puma.io/) como seu servidor web. Então, vamos começar com uma breve introdução aos workers e threads do Puma.

O Puma é um servidor web popular para aplicativos Ruby on Rails e usa múltiplos workers e threads para lidar com solicitações de entrada. Cada Worker executa sua própria instância da aplicação, e cada thread dentro de um worker pode lidar com uma única solicitação de cada vez.

Agora, vamos passar para como você pode configurar os workers e threads do Puma usando variáveis de ambiente.

### Workers

Cada worker do Puma é um processo separado que executa uma instância do aplicativo Ruby. Cada Worker tem seu próprio event loop que pode lidar com solicitações de entrada simultaneamente usando múltiplas threads.

Quando o servidor Puma recebe uma solicitação, ela é atribuída a um processo worker de forma round-robin. Depois que um worker recebe uma solicitação, ele atribui a solicitação a uma thread disponível dentro do seu processo. Cada thread então lida com a solicitação, incluindo quaisquer consultas de banco de dados necessárias, cálculos e outras tarefas de processamento. O uso de múltiplos processos worker permite que o Puma lide com múltiplas solicitações simultaneamente, sem bloquear outras solicitações ou causar um gargalo.

#### Configurando o número de workers

A variável de ambiente `WEB_CONCURRENCY` pode ser usada para configurar o número de workers no Puma. É importante considerar o número de núcleos de CPU disponíveis e buscar uma proporção de workers para núcleos que permita que o servidor funcione com capacidade máxima, sem causar problemas de desempenho. É recomendado ter um número de workers que corresponda ou seja ligeiramente inferior ao número de núcleos de CPU disponíveis para evitar a concorrência por tempo de CPU, o que pode levar a problemas de desempenho.

```
WEB_CONCURRENCY=2
```

<Note>
  A configuração padrão no AirysChat para `WEB_CONCURRENCY` é `0`. Ou seja, ele executa um Worker. Isso é para garantir que a aplicação funcione em máquinas com uma configuração inferior. Se você executar o AirysChat em máquinas com especificações mais altas, ajuste esta configuração adequadamente.
</Note>

### Threads

Cada thread do Puma é um contexto de execução leve que pode lidar com uma única solicitação de cada vez. Quando um processo worker recebe uma solicitação, ela é atribuída a uma thread disponível dentro daquele processo. Cada thread então lida com a solicitação, incluindo quaisquer consultas de banco de dados necessárias, cálculos e outras tarefas de processamento.

O uso de múltiplas threads pode aumentar a concorrência e o desempenho, mas é essencial equilibrar o número de threads com os recursos de CPU disponíveis para evitar a concorrência por tempo de CPU. O número de threads pode ser configurado usando as seguintes variáveis de ambiente.

```
# Only required to configure if absolutely necessary
# Defaults to Max threads value by default
# RAILS_MIN_THREADS=5
RAILS_MAX_THREADS=5
```

<Note>
  A configuração padrão no AirysChat para valores de `RAILS_MAX_THREADS` é `5`. Você pode ajustá-lo com base em suas necessidades. O valor de `RAILS_MIN_THREADS` tem como padrão o de `RAILS_MAX_THREADS`, a menos que um valor específico seja fornecido.
</Note>

### Ajuste fino (Fine-tuning)

TLDR: Você pode configurar `WEB_CONCURRENCY` para o número de núcleos de CPU e, em seguida, ajustar o número de `RAILS_MAX_THREADS` com base nos recursos de `memória` e `CPU` disponíveis. Ao executar o sidekiq e o servidor rails em uma única máquina, considere a configuração do sidekiq ao determinar esses números.

Referências:

* [https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server](https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server)
* [https://www.speedshop.co/2017/10/12/appserver.html](https://www.speedshop.co/2017/10/12/appserver.html)
* [https://github.com/ankane/the-ultimate-guide-to-ruby-timeouts#puma](https://github.com/ankane/the-ultimate-guide-to-ruby-timeouts#puma)

## Sidekiq

O Sidekiq é uma popular biblioteca de processamento de jobs para aplicativos Ruby on Rails. O AirysChat o usa como uma maneira simples e eficiente de executar jobs em segundo plano de forma assíncrona no aplicativo Rails.

O Sidekiq usa o Redis para gerenciar uma fila de jobs, permitindo que você execute múltiplos workers em paralelo, cada um processando jobs da fila. Isso facilita a distribuição de cargas de trabalho e o manuseio de grandes volumes de jobs sem sobrecarregar a thread principal do seu aplicativo Rails.

Você pode configurar o número de workers do sidekiq usando as seguintes variáveis de ambiente.

```
# the default value in AirysChat is 10 
SIDEKIQ_CONCURRENCY=10
```

<Note>
  Se você estiver executando o sidekiq em pods dedicados, você pode fazer um ajuste fino (fine-tune) do número `SIDEKIQ_CONCURRENCY` para extrair o desempenho máximo dos recursos de CPU disponíveis.
</Note>

## Conexões de Banco de Dados

Quando um aplicativo Ruby on Rails é lançado, ele cria um pool de conexões de banco de dados que são armazenadas na memória. Essas conexões são estabelecidas com o servidor de banco de dados no início do aplicativo e são mantidas abertas por toda a vida do aplicativo. Quando uma solicitação que requer acesso ao banco de dados é feita ao aplicativo, o servidor de aplicativo recuperará uma conexão do pool e a usará para processar a solicitação. Assim que a solicitação for concluída, a conexão é devolvida ao pool para ser usada em solicitações futuras.

O tamanho do pool de banco de dados no AirysChat é configurado automaticamente com base nos valores de `RAILS_MAX_THREADS` e `SIDEKIQ_CONCURRENCY`

```
https://github.com/airyschat/airyschat/blob/4d719a8fe33bed72ec57812e174dab1874315340/config/database.yml#L7
```

Ref:

* [https://stackoverflow.com/questions/40412611/in-puma-how-do-i-calculate-db-connections](https://stackoverflow.com/questions/40412611/in-puma-how-do-i-calculate-db-connections)

<Note>
  Se você tiver um servidor de banco de dados com recursos mais altos disponíveis, você pode aproveitá-lo aumentando o número de pods rails e sidekiq de forma que mais limite de conexão esteja sendo usado.
</Note>

### Perguntas Frequentes (FAQ)

## Obtendo erros `ActiveRecord::ConnectionTimeoutError`.

Existe um bug potencial com a implementação do `rack-timeout` do AirysChat, em instalações específicas, que resulta em conexões não sendo liberadas corretamente. Por enquanto, você pode definir a seguinte variável de ambiente para desabilitar o `rack-timeout` se você estiver enfrentando isso.

```
RACK_TIMEOUT_SERVICE_TIMEOUT=0
```
