Skip to content

valitydev/progressor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

40 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Progressor - БистСма ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ процСссов

ОписаниС

Progressor - это Π²Ρ‹ΡΠΎΠΊΠΎΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ систСма ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π΄ΠΎΠ»Π³ΠΎΠΆΠΈΠ²ΡƒΡ‰ΠΈΡ… процСссов Π½Π° языкС Erlang/OTP. БистСма ΠΏΡ€Π΅Π΄Π½Π°Π·Π½Π°Ρ‡Π΅Π½Π° для управлСния ΠΆΠΈΠ·Π½Π΅Π½Π½Ρ‹ΠΌ Ρ†ΠΈΠΊΠ»ΠΎΠΌ процСссов, ΠΈΡ… состояниСм ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ΠΌ Π·Π°Π΄Π°Ρ‡ Π² распрСдСлСнной срСдС с гарантиями консистСнтности ΠΈ отказоустойчивости.

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ возмоТности

  • Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ процСссами: Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅, Π²Ρ‹Π·ΠΎΠ², восстановлСниС ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ процСссов
  • ΠŸΠ»Π°Π½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π·Π°Π΄Π°Ρ‡: Гибкая систСма планирования с ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ Ρ‚Π°ΠΉΠΌΠ΅Ρ€ΠΎΠ² ΠΈ ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ выполнСния
  • ΠžΡ‚ΠΊΠ°Π·ΠΎΡƒΡΡ‚ΠΎΠΉΡ‡ΠΈΠ²ΠΎΡΡ‚ΡŒ: АвтоматичСскоС восстановлСниС послС сбоСв с настраиваСмой ΠΏΠΎΠ»ΠΈΡ‚ΠΈΠΊΠΎΠΉ ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΎΠ²
  • ΠœΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΡƒΠ΅ΠΌΠΎΡΡ‚ΡŒ: ΠŸΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΏΡƒΠ»ΠΎΠ² Π²ΠΎΡ€ΠΊΠ΅Ρ€ΠΎΠ² ΠΈ Π³ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚Π°Π»ΡŒΠ½ΠΎΠ³ΠΎ ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ
  • ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅: Π’Ρ‹ΡΠΎΠΊΠΎΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ состояния процСссов Π½Π° основС логичСской Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ PostgreSQL
  • ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³: ВстроСнныС ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Prometheus для наблюдСния Π·Π° систСмой
  • Π˜Π΄Π΅ΠΌΠΏΠΎΡ‚Π΅Π½Ρ‚Π½ΠΎΡΡ‚ΡŒ: Π—Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ дублирования ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ Ρ‡Π΅Ρ€Π΅Π· ΠΊΠ»ΡŽΡ‡ΠΈ идСмпотСнтности

АрхитСктура систСмы

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Client API    β”‚    β”‚                Progressor                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚                                          β”‚
         β”‚              β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
         β”‚              β”‚  β”‚ API Handlerβ”‚  β”‚     Scheduler       β”‚ β”‚
         β–Ό              β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚                                          β”‚
β”‚   Thrift API    │◄────  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚  β”‚  Storage   β”‚  β”‚    Worker Pool      β”‚ β”‚
                       β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
                       β”‚                                          β”‚
                       β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
                       β”‚  β”‚   Cache    β”‚  β”‚     Processor       β”‚ β”‚
                       β”‚  β”‚   (ETS)    β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
                       β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β”‚
                       β”‚                                          β”‚
                       β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
                       β”‚  β”‚ PostgreSQL β”‚  β”‚      Scanner        β”‚ β”‚
                       β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
                       β”‚                                          β”‚
                       β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                          β”‚
                       β”‚  β”‚  Notifier  β”‚                          β”‚
                       β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                          β”‚
                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                          β”‚
                                          β–Ό
                                   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                                   β”‚    Kafka     β”‚
                                   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹

1. ΠŸΡ€ΠΎΡ†Π΅ΡΡΡ‹ (Processes)

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ сущности систСмы, ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‰ΠΈΠ΅ бизнСс-процСссы:

  • process_id - ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ процСсса
  • status - состояниС процСсса (running ΠΈΠ»ΠΈ error)
  • detail - Π΄Π΅Ρ‚Π°Π»ΡŒΠ½Π°Ρ информация ΠΎ состоянии
  • aux_state - Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ состояниС процСсса
  • metadata - ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ процСсса
  • history - история событий процСсса

2. Π—Π°Π΄Π°Ρ‡ΠΈ (Tasks)

Π•Π΄ΠΈΠ½ΠΈΡ†Ρ‹ Ρ€Π°Π±ΠΎΡ‚Ρ‹, выполняСмыС Π½Π°Π΄ процСссами:

  • init - инициализация Π½ΠΎΠ²ΠΎΠ³ΠΎ процСсса
  • call - внСшний Π²Ρ‹Π·ΠΎΠ² ΠΊ процСссу
  • repair - восстановлСниС процСсса послС ошибки
  • timeout - ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚Π°
  • notify - ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΎ событии
  • remove - ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ процСсса

3. Бобытия (Events)

Π˜ΡΡ‚ΠΎΡ€ΠΈΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ процСссов:

  • event_id - порядковый Π½ΠΎΠΌΠ΅Ρ€ события
  • timestamp - врСмя события
  • payload - Π΄Π°Π½Π½Ρ‹Π΅ события
  • metadata - ΠΌΠ΅Ρ‚Π°Π΄Π°Π½Π½Ρ‹Π΅ события

4. Π’ΠΎΡ€ΠΊΠ΅Ρ€Ρ‹ (Workers)

Π˜ΡΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΠΈ Π·Π°Π΄Π°Ρ‡, Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰ΠΈΠ΅ Π² ΠΏΡƒΠ»Π°Ρ…:

  • ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π·Π°Π΄Π°Ρ‡ ΠΈΠ· ΠΎΡ‡Π΅Ρ€Π΅Π΄Π΅ΠΉ
  • ВзаимодСйствиС с процСссорами
  • Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΆΠΈΠ·Π½Π΅Π½Π½Ρ‹ΠΌ Ρ†ΠΈΠΊΠ»ΠΎΠΌ Π·Π°Π΄Π°Ρ‡

5. Π‘ΠΊΠ°Π½Π΅Ρ€Ρ‹ (Scanners)

ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Ρ‹ поиска Π·Π°Π΄Π°Ρ‡ для выполнСния:

  • Поиск Π·Π°ΠΏΠ»Π°Π½ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Π·Π°Π΄Π°Ρ‡
  • Π‘Π±ΠΎΡ€ "Π·ΠΎΠΌΠ±ΠΈ" Π·Π°Π΄Π°Ρ‡
  • Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ очСрСдями выполнСния

API

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ процСсса

progressor:init(#{
    ns => 'default/default',
    id => <<"process_123">>,
    args => <<"init_args">>,
    context => <<"context_data">>,
    idempotency_key => <<"unique_key">>
}).

Π’Ρ‹Π·ΠΎΠ² процСсса

progressor:call(#{
    ns => 'default/default',
    id => <<"process_123">>,
    args => <<"call_args">>,
    context => <<"context_data">>,
    idempotency_key => <<"call_key">>
}).

ВосстановлСниС процСсса

progressor:repair(#{
    ns => 'default/default',
    id => <<"process_123">>,
    args => <<"repair_args">>,
    context => <<"context_data">>
}).

ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ состояния процСсса

progressor:get(#{
    ns => 'default/default',
    id => <<"process_123">>,
    range => #{
        offset => 0,
        limit => 100,
        direction => forward
    }
}).

Π”ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ процСсса

progressor:put(#{
    ns => 'default/default',
    id => <<"process_123">>,
    args => #{
        process => #{
            process_id => <<"process_123">>,
            status => <<"running">>,
            aux_state => <<"state_data">>
        },
        action => #{set_timer => 1640995200}
    }
}).

ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹

{progressor, [
    {defaults, #{
        storage => #{
            client => prg_pg_backend,
            options => #{
                pool => default_pool,
                scan_pool => default_scan_pool,
                front_pool => default_front_pool,
                cache => db_ref
            }
        },
        retry_policy => #{
            initial_timeout => 3,        % сСкунды
            backoff_coefficient => 1.2,
            max_timeout => 180,          % сСкунды
            max_attempts => 2,
            non_retryable_errors => [
                some_reason,
                <<"Error message">>
            ]
        },
        task_scan_timeout => 10,         % сСкунды
        worker_pool_size => 200,
        process_step_timeout => 30       % сСкунды
    }},

    {namespaces, #{
        'default/default' => #{
            processor => #{
                client => custom_processor,
                options => #{}
            },
            notifier => #{
                client => default_kafka_client,
                options => #{
                    topic => <<"events_topic">>,
                    lifecycle_topic => <<"lifecycle_topic">>
                }
            }
        }
    }}
]}

ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊ PostgreSQL

{epg_connector, [
    {databases, #{
        progressor_db => #{
            host => "postgres",
            port => 5432,
            database => "progressor_db",
            username => "progressor",
            password => "progressor"
        }
    }},
    {pools, #{
        default_pool => #{
            database => progressor_db,
            size => 100
        },
        default_scan_pool => #{
            database => progressor_db,
            size => 1
        },
        default_front_pool => #{
            database => progressor_db,
            size => 10
        }
    }}
]}

Настройка взаимодСйствия с Kafka

{brod, [
    {clients, [
        {default_kafka_client, [
            {endpoints, [{"kafka1", 9092}, {"kafka2", 9092}]},
            {auto_start_producers, true},
            {default_producer_config, []}
        ]}
    ]}
]}

РСализация процСссора

ΠŸΡ€ΠΎΡ†Π΅ΡΡΠΎΡ€ опрСдСляСт бизнСс-Π»ΠΎΠ³ΠΈΠΊΡƒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ процСссов:

-module(my_processor).
-export([process/3]).

process({TaskType, Args, Process}, Options, Context) ->
    #{
        process_id := ProcessId,
        status := Status,
        aux_state := AuxState,
        history := History
    } = Process,

    % БизнСс-Π»ΠΎΠ³ΠΈΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ
    NewEvent = #{
        event_id => length(History) + 1,
        timestamp => erlang:system_time(second),
        metadata => #{<<"format_version">> => 1},
        payload => create_payload(TaskType, Args)
    },

    % Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ
    Result = #{
        events => [NewEvent],
        aux_state => update_aux_state(AuxState, TaskType),
        metadata => #{<<"last_update">> => erlang:system_time(second)},
        response => {ok, <<"success">>}
    },

    % ΠžΠΏΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎ ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Ρ‚Π°ΠΉΠΌΠ΅Ρ€
    case should_set_timer(Process, TaskType) of
        true ->
            TimerTime = erlang:system_time(second) + 60,
            {ok, Result#{action => #{set_timer => TimerTime}}};
        false ->
            {ok, Result}
    end.

Π‘Ρ†Π΅Π½Π°Ρ€ΠΈΠΈ использования

1. ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ процСсс с Ρ‚Π°ΠΉΠΌΠ΅Ρ€ΠΎΠΌ

% Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ процСсса
{ok, ok} = progressor:init(#{
    ns => 'default/default',
    id => <<"timer_process">>,
    args => <<"init">>
}),

% ΠŸΡ€ΠΎΡ†Π΅ΡΡΠΎΡ€ устанавливаСт Ρ‚Π°ΠΉΠΌΠ΅Ρ€ Π½Π° 60 сСкунд
% Π§Π΅Ρ€Π΅Π· 60 сСкунд автоматичСски выполнится timeout Π·Π°Π΄Π°Ρ‡Π°

% ΠŸΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΠ΅ состояния
{ok, Process} = progressor:get(#{
    ns => 'default/default',
    id => <<"timer_process">>
}).

2. Π’Π½Π΅ΡˆΠ½ΠΈΠΉ Π²Ρ‹Π·ΠΎΠ² ΠΊ процСссу

% Π’Ρ‹Π·ΠΎΠ² процСсса с внСшними Π΄Π°Π½Π½Ρ‹ΠΌΠΈ
{ok, Response} = progressor:call(#{
    ns => 'default/default',
    id => <<"active_process">>,
    args => <<"external_data">>,
    idempotency_key => <<"call_123">>
}).

3. ВосстановлСниС послС ошибки

% ВосстановлСниС процСсса Π² состоянии error
{ok, ok} = progressor:repair(#{
    ns => 'default/default',
    id => <<"failed_process">>,
    args => <<"repair_data">>
}).

ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ ΠΈ ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ

БистСма прСдоставляСт ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Prometheus:

Π”Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ (гистограммы)

  • progressor_calls_scanning_duration_ms - ВрСмя сканирования Π²Ρ‹Π·ΠΎΠ²ΠΎΠ²
  • progressor_timers_scanning_duration_ms - ВрСмя сканирования Ρ‚Π°ΠΉΠΌΠ΅Ρ€ΠΎΠ²
  • progressor_zombie_collection_duration_ms - ВрСмя сборки Π·ΠΎΠΌΠ±ΠΈ-Π·Π°Π΄Π°Ρ‡
  • progressor_request_preparing_duration_ms - ВрСмя ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΊΠΈ запросов
  • progressor_task_processing_duration_ms - ВрСмя ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π·Π°Π΄Π°Ρ‡
  • progressor_task_completion_duration_ms - ВрСмя Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ Π·Π°Π΄Π°Ρ‡
  • progressor_process_removing_duration_ms - ВрСмя удалСния процСссов
  • progressor_notification_duration_ms - ВрСмя ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ

ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° Π·Π΄ΠΎΡ€ΠΎΠ²ΡŒΡ

% ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° состояния namespace
{Status, Details} = progressor:health_check(['default/default']).
% Status: passing | critical

Π Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Π½ΠΈΠ΅

Docker

# Π‘Π±ΠΎΡ€ΠΊΠ° ΠΎΠ±Ρ€Π°Π·Π°
docker build -f Dockerfile.dev -t progressor:dev .

# Запуск с docker-compose
docker-compose up -d

Makefile ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹

# ΠšΠΎΠΌΠΏΠΈΠ»ΡΡ†ΠΈΡ
make compile

# ВСсты
make test

# Π€ΠΎΡ€ΠΌΠ°Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠ΄Π°
make fmt

# БтатичСский Π°Π½Π°Π»ΠΈΠ·
make dialyzer

ΠŸΠΎΠ»ΠΈΡ‚ΠΈΠΊΠ° ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΎΠ²

БистСма ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Π³ΠΈΠ±ΠΊΡƒΡŽ настройку ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΎΠ² ΠΏΡ€ΠΈ ΠΎΡˆΠΈΠ±ΠΊΠ°Ρ…:

retry_policy => #{
    initial_timeout => 5,           % ΠΠ°Ρ‡Π°Π»ΡŒΠ½Π°Ρ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° (сСк)
    backoff_coefficient => 2.0,     % ΠšΠΎΡΡ„Ρ„ΠΈΡ†ΠΈΠ΅Π½Ρ‚ увСличСния Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ
    max_timeout => 300,             % Максимальная Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° (сСк)
    max_attempts => 5,              % МаксимальноС количСство ΠΏΠΎΠΏΡ‹Ρ‚ΠΎΠΊ
    non_retryable_errors => [       % Ошибки Π±Π΅Π· ΠΏΠΎΠ²Ρ‚ΠΎΡ€ΠΎΠ²
        validation_failed,
        <<"Invalid input">>
    ]
}

Π‘Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡ‚ΡŒ ΠΈ Π»ΡƒΡ‡ΡˆΠΈΠ΅ ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠΈ

Π˜Π΄Π΅ΠΌΠΏΠΎΡ‚Π΅Π½Ρ‚Π½ΠΎΡΡ‚ΡŒ

  • ВсСгда ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΊΠ»ΡŽΡ‡ΠΈ идСмпотСнтности для ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½Ρ‹Ρ… ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ
  • ΠšΠ»ΡŽΡ‡ΠΈ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… namespace

ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³

  • НастройтС Π°Π»Π΅Ρ€Ρ‚Ρ‹ Π½Π° ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ
  • ΠžΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°ΠΉΡ‚Π΅ количСство Π·ΠΎΠΌΠ±ΠΈ-Π·Π°Π΄Π°Ρ‡
  • ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΡŒΡ‚Π΅ состояниС ΠΏΡƒΠ»ΠΎΠ² ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ ΠΊ Π‘Π”

ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ

  • НастройтС Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ ΠΏΡƒΠ»ΠΎΠ² Π²ΠΎΡ€ΠΊΠ΅Ρ€ΠΎΠ² ΠΏΠΎΠ΄ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΡƒ
  • ΠžΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΡƒΠΉΡ‚Π΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Ρ‹ ΠΏΡƒΠ»ΠΎΠ² ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ ΠΊ PostgreSQL
  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ ΠΏΠ°Ρ€Ρ‚ΠΈΡ†ΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Ρ‚Π°Π±Π»ΠΈΡ† для Π±ΠΎΠ»ΡŒΡˆΠΈΡ… объСмов Π΄Π°Π½Π½Ρ‹Ρ…

ΠžΡ‚ΠΊΠ°Π·ΠΎΡƒΡΡ‚ΠΎΠΉΡ‡ΠΈΠ²ΠΎΡΡ‚ΡŒ

  • НастройтС Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΡŽ PostgreSQL
  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ кластСр Kafka для ΡƒΠ²Π΅Π΄ΠΎΠΌΠ»Π΅Π½ΠΈΠΉ
  • РСгулярно создавайтС Ρ€Π΅Π·Π΅Ρ€Π²Π½Ρ‹Π΅ ΠΊΠΎΠΏΠΈΠΈ Π΄Π°Π½Π½Ρ‹Ρ…

ΠšΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° основС логичСской Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ PostgreSQL

Progressor ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ состояния процСссов с использованиСм логичСской Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ PostgreSQL. Кэш Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Π½ Π½Π° Π±Π°Π·Π΅ ETS Ρ‚Π°Π±Π»ΠΈΡ†.

ΠŸΡ€ΠΈΠ½Ρ†ΠΈΠΏ Ρ€Π°Π±ΠΎΡ‚Ρ‹ кэша

  1. ЛогичСская рСпликация: Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ встроСнная логичСская рСпликация PostgreSQL для отслСТивания ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ Π² Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ… процСссов ΠΈ событий
  2. WAL Reader: ΠšΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚ epg_wal_reader Ρ‡ΠΈΡ‚Π°Π΅Ρ‚ Write-Ahead Log (WAL) ΠΈ ΠΏΠ΅Ρ€Π΅Π΄Π°Π΅Ρ‚ измСнСния Π² кэш
  3. ETS Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅: Π”Π°Π½Π½Ρ‹Π΅ ΠΊΡΡˆΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π² быстрых ETS Ρ‚Π°Π±Π»ΠΈΡ†Π°Ρ… Π² памяти Erlang
  4. АвтоматичСская очистка: НСактивныС процСссы автоматичСски ΡƒΠ΄Π°Π»ΡΡŽΡ‚ΡΡ ΠΈΠ· кэша ΠΏΠΎ Ρ‚Π°ΠΉΠΌΠ°ΡƒΡ‚Ρƒ

Настройка ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ

ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ namespace с кэшСм

{namespaces, #{
    'cached/namespace' => #{
        storage => #{
            client => prg_pg_backend,
            options => #{
                pool => default_pool,
                cache => progressor_db  % Бсылка Π½Π° Π±Π°Π·Ρƒ Π΄Π°Π½Π½Ρ‹Ρ…
            }
        },
        processor => #{
            client => my_processor,
            options => #{}
        }
    }
}}

Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ кэша

{post_init_hooks, [
    {prg_pg_cache, start, [
        #{
            progressor_db => {
                ['cached/namespace'],    % Бписок ΠΊΡΡˆΠΈΡ€ΡƒΠ΅ΠΌΡ‹Ρ… namespace
                "progressor"            % Имя прилоТСния для replication slot
            }
        }
    ]}
]}

Настройки кэша

% Π’Π°ΠΉΠΌΠ°ΡƒΡ‚ ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ ΠΊ Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 5000 мс)
{cache_reconnect_timeout, 5000},

% Π’Π°ΠΉΠΌΠ°ΡƒΡ‚ очистки Π½Π΅Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… процСссов (ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 300000 мс = 5 ΠΌΠΈΠ½)
{cache_cleanup_timeout, 300000}

ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²Π° ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ

  • Высокая ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ: ΠžΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ чтСния Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ ΠΈΠ· памяти Π±Π΅Π· обращСния ΠΊ Π‘Π”
  • АвтоматичСская синхронизация: ИзмСнСния Π² Π‘Π” ΠΎΡ‚Ρ€Π°ΠΆΠ°ΡŽΡ‚ΡΡ Π² кэшС с Π½Π΅Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ (Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ)
  • ΠžΡ‚ΠΊΠ°Π·ΠΎΡƒΡΡ‚ΠΎΠΉΡ‡ΠΈΠ²ΠΎΡΡ‚ΡŒ: ΠŸΡ€ΠΈ ΠΏΠΎΡ‚Π΅Ρ€Π΅ соСдинСния с Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠ΅ΠΉ кэш автоматичСски ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ (ΠΏΡ€ΠΈ ΠΏΠΎΡ‚Π΅Ρ€Π΅ соСдинСния кэш очищаСтся Π΄ΠΎ восстановлСния соСдинСния)
  • Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ ΠΏΠ°ΠΌΡΡ‚ΡŒΡŽ: НСактивныС процСссы автоматичСски ΡƒΠ΄Π°Π»ΡΡŽΡ‚ΡΡ ΠΈΠ· кэша

ВрСбования ΠΊ PostgreSQL

Для Ρ€Π°Π±ΠΎΡ‚Ρ‹ ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ:

  1. ЛогичСская рСпликация Π²ΠΊΠ»ΡŽΡ‡Π΅Π½Π°:

    -- Π’ postgresql.conf
    wal_level = logical
    max_replication_slots = 10
    max_wal_senders = 10
  2. ΠŸΡ€Π°Π²Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ:

    -- ΠŸΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΠΌΠ΅Ρ‚ΡŒ ΠΏΡ€Π°Π²Π° Π½Π° созданиС replication slot
    ALTER ROLE progressor_user REPLICATION;
  3. Publication создаСтся автоматичСски для Ρ‚Π°Π±Π»ΠΈΡ† процСссов ΠΈ событий ΠΊΡΡˆΠΈΡ€ΡƒΠ΅ΠΌΡ‹Ρ… namespace

ΠœΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ кэша

NOT IMPLEMENTED (TODO cache_hit_counter)

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Progressor прСдоставляСт Π½Π°Π΄Π΅ΠΆΠ½ΡƒΡŽ ΠΏΠ»Π°Ρ‚Ρ„ΠΎΡ€ΠΌΡƒ для управлСния Π΄ΠΎΠ»Π³ΠΎΠΆΠΈΠ²ΡƒΡ‰ΠΈΠΌΠΈ процСссами с гарантиями консистСнтности, отказоустойчивости ΠΈ ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΡƒΠ΅ΠΌΠΎΡΡ‚ΠΈ. ВстроСнноС ΠΊΡΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° основС логичСской Ρ€Π΅ΠΏΠ»ΠΈΠΊΠ°Ρ†ΠΈΠΈ PostgreSQL обСспСчиваСт Π²Ρ‹ΡΠΎΠΊΡƒΡŽ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΉ чтСния ΠΏΡ€ΠΈ сохранСнии Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ Π΄Π°Π½Π½Ρ‹Ρ…. БистСма ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ слоТных бизнСс-процСссов, Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‰ΠΈΡ… Π½Π°Π΄Π΅ΠΆΠ½ΠΎΠ³ΠΎ управлСния состояниСм ΠΈ планирования Π·Π°Π΄Π°Ρ‡.

About

No description, website, or topics provided.

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •