Ruby에서 예외를 복구하는 동안 Concurrent::Promise 사용

14425 단어
Concurrent::Promises(Concurrent Ruby gem 의 일부)에서 예외를 구하는 방법에 대한 명확한 예를 찾을 수 없었기 때문에 설명서를 읽었으며 여기에 두 가지 예가 있습니다. 하나는 성공 사례를 문서화하고 다른 하나는 오류가 있습니다.

다음은 동시 루비를 실행하고 예외를 복구하는 간단한 방법입니다.

성공 사례




require 'bundler/inline'

gemfile do
  ruby "3.0.1"
  source 'https://rubygems.org'
  gem "concurrent-ruby"
end

require "concurrent"
require "pp"

# Just a simple class that needs to execute something
class Load
  def initialize(id)
    @id = id
  end

  def work
    sleep(1)
    "Executing #{@id}"
  end
end

class ParallelExecution
  def call

    # Using here Concurrent::Array to be thread safe
    exceptions = Concurrent::Array.new
    promises = []
    10.times do |t|
      promises << Concurrent::Promises.future { Load.new(t).work }.rescue { exceptions.push(_1) }
    end

    # Calling .value on each job to wait for its execution
    values = Concurrent::Promises.zip(*promises).value

    # Raising exceptions if any of the jobs were returning an exception
    raise exceptions.first if exceptions.length > 0

    pp values
  end
end


ParallelExecution.new.call


다음과 같이 인쇄됩니다.

["Executing 0",
 "Executing 1",
 "Executing 2",
 "Executing 3",
 "Executing 4",
 "Executing 5",
 "Executing 6",
 "Executing 7",
 "Executing 8",
 "Executing 9"]


실패 예




require 'bundler/inline'

gemfile do
  ruby "3.0.1"
  source 'https://rubygems.org'
  gem "concurrent-ruby"
end

require "concurrent"
require "pp"

# Just a simple class that needs to execute something
class Load
  def initialize(id)
    @id = id
  end

  def work
    raise MyException.new
  end
end

class MyException < Exception ; end

class ParallelExecution
  def call

    # Using here Concurrent::Array to be thread safe
    exceptions = Concurrent::Array.new
    promises = []
    10.times do |t|
      promises << Concurrent::Promises.future { Load.new(t).work }.rescue { exceptions.push(_1) }
    end

    # Calling .value on each job to wait for its execution
    values = Concurrent::Promises.zip(*promises).value

    # Raising exceptions if any of the jobs were returning an exception
    raise exceptions.first if exceptions.length > 0

    pp values
  end
end


ParallelExecution.new.call


이 코드는 MyException 예외를 발생시킵니다.

코드 예제에서 확인하려면



모든 예외를 얻을 수 있고 예를 들어 유형에 따라 다양한 작업을 수행할 수 있습니다.

require 'bundler/inline'

gemfile do
  ruby "3.0.1"
  source 'https://rubygems.org'
  gem "concurrent-ruby"
end

require "concurrent"
require "pp"

# Just a simple class that needs to execute something
class Load
  def initialize(id)
    @id = id
  end

  def work
    exception = [MyException, SecondException].sample
    raise exception.send(:new)
  end
end

class MyException < Exception ; end
class SecondException < Exception ; end

class ParallelExecution
  def call

    # Using here Concurrent::Array to be thread safe
    exceptions = Concurrent::Array.new
    promises = []
    10.times do |t|
      promises << Concurrent::Promises.future { Load.new(t).work }.rescue { exceptions.push(_1) }
    end

    # Calling .value on each job to wait for its execution
    values = Concurrent::Promises.zip(*promises).value

    # Raising exceptions if any of the jobs were returning an exception
    if exceptions.length > 0
      count_my_exception = exceptions.count { _1.instance_of?(MyException) }
      count_second_exception = exceptions.count { _1.instance_of?(SecondException) }

      puts "MyException generated #{count_my_exception}"
      puts "SecondException generated #{count_second_exception}"
    end
  end
end


ParallelExecution.new.call

좋은 웹페이지 즐겨찾기