diff --git a/.ruby-version b/.ruby-version index bea438e..8cf6caf 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.3.1 +3.4.1 \ No newline at end of file diff --git a/async_client.rb b/async_client.rb new file mode 100644 index 0000000..71c5071 --- /dev/null +++ b/async_client.rb @@ -0,0 +1,80 @@ +require 'openssl' +require 'faraday' +require 'async' +require 'async/semaphore' +require 'async/barrier' + +OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE + +# Есть три типа эндпоинтов API +# Тип A: +# - работает 1 секунду +# - одновременно можно запускать не более трёх +# Тип B: +# - работает 2 секунды +# - одновременно можно запускать не более двух +# Тип C: +# - работает 1 секунду +# - одновременно можно запускать не более одного +# +def a(value) + puts "https://localhost:9292/a?value=#{value}" + Faraday.get("https://localhost:9292/a?value=#{value}").body +end + +def b(value) + puts "https://localhost:9292/b?value=#{value}" + Faraday.get("https://localhost:9292/b?value=#{value}").body +end + +def c(value) + puts "https://localhost:9292/c?value=#{value}" + Faraday.get("https://localhost:9292/c?value=#{value}").body +end + +def collect_sorted(arr) + arr.sort.join('-') +end + +start = Time.now + + +A_SEMAPHORE = Async::Semaphore.new(3) +B_SEMAPHORE = Async::Semaphore.new(2) +C_SEMAPHORE = Async::Semaphore.new(1) +barriers = Hash.new { |hh, kk| hh[kk] = Async::Barrier.new } + +@a = Hash.new { |h, k| h[k] = [] } +@b = {} +@c = {} + +Async do + {1 => [11, 12, 13], 2 => [21, 22, 23], 3 => [31, 32, 33]}.each do |index, a_indexes| + a_indexes.each do |a_index| + A_SEMAPHORE.async(parent: barriers[:a][index]) { @a[index] << a(a_index) } + end + + B_SEMAPHORE.async(parent: barriers[:b][index]) { @b[index] = b(index) } + end + + [1, 2, 3].each do |index| + C_SEMAPHORE.async do + barriers[:a][index].wait + barriers[:b][index].wait + + ab_value = "#{collect_sorted(@a[index])}-#{@b[index]}" + + puts "AB#{index} = #{ab_value}" + + @c[index] = c(ab_value) + + puts "C#{index} = #{@c[index]}" + end + end +end + +result = a(collect_sorted(@c.values)) + + +puts "FINISHED in #{Time.now - start}s." +puts "RESULT = #{result}" # 0bbe9ecf251ef4131dd43e1600742cfb \ No newline at end of file diff --git a/case-study.md b/case-study.md new file mode 100644 index 0000000..3b05a56 --- /dev/null +++ b/case-study.md @@ -0,0 +1,24 @@ +# Как выполняются рачеты +Схема в примере для подсчета `cN` + - кидаются 3 запроса `a` последовательно (не зависит от других переменных) + - запрос `b` (не зависит от других переменных) + - высчитывается `ab` объединение (зависит от переменных `a` и `b` ) + - сохраняется `c` ( зависит только от `a`) + + + Итоговый результат сумма `cN` + + +## Что можно сделать? + 1) вынести в асинхронное вычисление `a` и `b`, они не зависят не от чего кроме кол-ва запрсоов одновременных + 2) после создаём асинхронную логику, которая ждёт выполенние вычислений по index, тем самым дожидаемся что для ab[i](c[i]) собраны все `a` и `b` и запускаем вычисление + 3) потом синхронно высчитываем результат + + +## Результат +1) При использовании гема asynс добились рузельтата в 6 сек +``` +FINISHED in 6.088452s. +RESULT = 0bbe9ecf251ef4131dd43e1600742cfb +``` + +2) Ractor ... \ No newline at end of file diff --git a/correct.log b/correct.log new file mode 100644 index 0000000..03e89b0 --- /dev/null +++ b/correct.log @@ -0,0 +1,27 @@ +https://localhost:9292/a?value=11 +https://localhost:9292/a?value=12 +https://localhost:9292/a?value=13 +https://localhost:9292/b?value=1 +AB1 = 6512bd43d9caa6e02c990b0a82652dca-c20ad4d76fe97759aa27a0c99bff6710-c51ce410c124a10e0db5e4b97fc2af39-6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b +FINISHED AB1 5.034885s. +https://localhost:9292/c?value=6512bd43d9caa6e02c990b0a82652dca-c20ad4d76fe97759aa27a0c99bff6710-c51ce410c124a10e0db5e4b97fc2af39-6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b +C1 = ee54918569d9620a4947a184c097ab1a90b33db6b8a009e01cbbe7238f800ecf846068a36ac7ae289a0796face8b471dcfd7e7d55f9081bccd8f2f50c1d4f888 +FINISHED C1 6.041672s. +https://localhost:9292/a?value=21 +https://localhost:9292/a?value=22 +https://localhost:9292/a?value=23 +https://localhost:9292/b?value=2 +AB2 = 37693cfc748049e45d87b8c7d8b9aacd-3c59dc048e8850243be8079a5c74d079-b6d767d2f8ed5d21a44b0e5886680cb9-d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35 +FINISHED AB2 11.06694s. +https://localhost:9292/c?value=37693cfc748049e45d87b8c7d8b9aacd-3c59dc048e8850243be8079a5c74d079-b6d767d2f8ed5d21a44b0e5886680cb9-d4735e3a265e16eee03f59718b9b5d03019c07d8b6c51f90da3a666eec13ab35 +C2 = 4bc5a33ec7c74626144b5277e887501074b07819ecd9cc506b08e765be1f26a3d7c9fbb59bde46379ca7f0ebf2ef066f38c0a4652d4017a635fc8bdddc070557 +https://localhost:9292/a?value=31 +https://localhost:9292/a?value=32 +https://localhost:9292/a?value=33 +https://localhost:9292/b?value=3 +AB3 = 182be0c5cdcd5072bb1864cdee4d3d6e-6364d3f0f495b6ab9dcf8d3b5c6e0b01-c16a5320fa475530d9583c34fd356ef5-4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce +https://localhost:9292/c?value=182be0c5cdcd5072bb1864cdee4d3d6e-6364d3f0f495b6ab9dcf8d3b5c6e0b01-c16a5320fa475530d9583c34fd356ef5-4e07408562bedb8b60ce05c1decfe3ad16b72230967de01f640b7e4729b49fce +C3 = 35bf8dfb6c327259fd05a56a6d47ecfc21965b0f4ff8926b164c32e31cc91d825da1a73bc145cdec04dfbb0862fb14b687f15a8233be15092c4c85da4b7bf94a +https://localhost:9292/a?value=35bf8dfb6c327259fd05a56a6d47ecfc21965b0f4ff8926b164c32e31cc91d825da1a73bc145cdec04dfbb0862fb14b687f15a8233be15092c4c85da4b7bf94a-4bc5a33ec7c74626144b5277e887501074b07819ecd9cc506b08e765be1f26a3d7c9fbb59bde46379ca7f0ebf2ef066f38c0a4652d4017a635fc8bdddc070557-ee54918569d9620a4947a184c097ab1a90b33db6b8a009e01cbbe7238f800ecf846068a36ac7ae289a0796face8b471dcfd7e7d55f9081bccd8f2f50c1d4f888 +FINISHED in 19.115005s. +RESULT = 0bbe9ecf251ef4131dd43e1600742cfb \ No newline at end of file