<commit_before>---
version: 1.0.2
title: Параллелизм в OTP
---

Мы уже рассматривали абстракции языка Elixir для параллельного выполнения, но иногда нужна более широкая функциональность, и тогда мы обращаемся к поведениям OTP.

В этом уроке мы сосредоточимся на GenServer.

{% include toc.html %}

## GenServer

Сервер OTP &mdash; это модуль с GenServer, который имплементирует набор функций обратного вызова (callback). На простейшем уровне GenServer &mdash; это цикл, который обрабатывает один запрос за итерацию, сохраняя обновленное состояние.

Для демонстрации API GenServer мы реализуем базовую очередь для хранения и извлечения значений.

Для создания GenServer нужно запустить его и позаботиться об инициализации. В большинстве случаев мы хотим связать процессы, потому используем `GenServer.start_link/3`. Мы передаем туда запускаемый GenServer модуль, начальные аргументы и набор настроек для самого GenServer. Эти настройки будут переданы в `GenServer.init/1`, который и задает начальное состояние с помощью возвращаемого значения. В этом примере аргументы и будут начальным состоянием:

```elixir
defmodule SimpleQueue do
  use GenServer

  @doc """
  Запуск и линковка нашей очереди. Это вспомогательный метод.
  """
  def start_link(state \\ []) do
    GenServer.start_link(__MODULE__, state, name: __MODULE__)
  end
<commit_msg>[RU] Update `advanced/otp-concurrency` to 1.0.3 (#1562)<commit_after>---
version: 1.0.3
title: Параллелизм в OTP
---

Мы уже рассматривали абстракции языка Elixir для параллельного выполнения, но иногда нужна более широкая функциональность, и тогда мы обращаемся к поведениям OTP.

В этом уроке мы сосредоточимся на GenServer.

{% include toc.html %}

## GenServer

Сервер OTP &mdash; это модуль с GenServer, который имплементирует набор функций обратного вызова (callback). На простейшем уровне GenServer &mdash; это один процесс, обрабатывающий в цикле по одному запросу за итерацию, сохраняя обновленное состояние.

Для демонстрации API GenServer мы реализуем базовую очередь для хранения и извлечения значений.

Для создания GenServer нужно запустить его и позаботиться об инициализации. В большинстве случаев мы хотим связать процессы, потому используем `GenServer.start_link/3`. Мы передаем туда запускаемый GenServer модуль, начальные аргументы и набор настроек для самого GenServer. Эти настройки будут переданы в `GenServer.init/1`, который и задает начальное состояние с помощью возвращаемого значения. В этом примере аргументы и будут начальным состоянием:

```elixir
defmodule SimpleQueue do
  use GenServer

  @doc """
  Запуск и линковка нашей очереди. Это вспомогательный метод.
  """
  def start_link(state \\ []) do
    GenServer.start_link(__MODULE__, state, name: __MODULE__)
  end

{'fraction_non_alphanumeric': 0.059402332361516035, 'fraction_numerical': 0.00619533527696793, 'mean_word_length': 5.006564551422319, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '115822', 'n_tokens_mistral': 1048, 'n_tokens_neox': 1232, 'n_words': 332}