回调消息打印未按照重试逻辑按预期工作

问题描述 投票:0回答:1

我正在尝试制作一个执行以下操作的程序:

  1. 处理项目列表。
  2. 每个项目都由专用函数处理。
  3. 每个函数调用都包装在 with_retries 块函数中。
  4. 显示消息应该使用回调来显示。

我已经成功实现了回调、错误处理和重试逻辑,但是我的实现中有一些问题,因为将回调与重试逻辑结合起来会破坏错误处理。

这个节目:

def print_attempt_number(proc_id:, &callback)
    random = [true, false].sample
    if random
        message = "Attempt for ID: #{proc_id}"
        callback.call(proc_id, message) if callback
        # puts "PUTS: #{message}"
    else
        raise StandardError, "This is my error message"
    end
end

def handle_error(proc_id:, retries:, max_retries:, &callback)
    retries += 1
    retry_msg = "Retry #{retries} / #{max_retries}"
    # puts "PUTS: #{retry_msg}"
    callback.call(proc_id, retry_msg)
    return retries
end

def with_retries(max_retries:, proc_id:, &callback)
    retries = 0
    begin
        yield
    rescue StandardError => e
        retries = handle_error(proc_id: proc_id, retries: retries, max_retries: max_retries, &callback)
        sleep 1.0
        retry if retries < max_retries
    end
end

def process_item(proc_id:, &callback)
    init_msg = "Starting with #{proc_id}"
    callback.call(proc_id, init_msg)
    with_retries(max_retries: 3, proc_id:) do
        print_attempt_number(proc_id: proc_id, &callback)
    end
end



callback = Proc.new do |proc_id, message|
    puts "CALLBACK: #{proc_id}\t#{message}"
end

for id in 1..5 do
    process_item(proc_id: id, &callback)
    sleep 1.0
end

产生这个结果:

CALLBACK: 1     Starting with 1
CALLBACK: 1     Attempt for ID: 1
CALLBACK: 2     Starting with 2
CALLBACK: 2     Attempt for ID: 2
callback_test.rb:8:in `print_attempt_number': This is my error message (StandardError)
        from callback_test.rb:38:in `block in process_item'
        from callback_test.rb:16:in `handle_error'
        from callback_test.rb:25:in `rescue in with_retries'
        from callback_test.rb:22:in `with_retries'
        from callback_test.rb:37:in `process_item'
        from callback_test.rb:49:in `block in <main>'
        from callback_test.rb:48:in `each'
        from callback_test.rb:48:in `<main>'
callback_test.rb:8:in `print_attempt_number': This is my error message (StandardError)
        from callback_test.rb:38:in `block in process_item'
        from callback_test.rb:23:in `with_retries'
        from callback_test.rb:37:in `process_item'
        from callback_test.rb:49:in `block in <main>'
        from callback_test.rb:48:in `each'
        from callback_test.rb:48:in `<main>'

但是,从

callback
直接切换到
puts
会产生预期的结果:

def print_attempt_number(proc_id:, &callback)
    random = [true, false].sample
    if random
        message = "Attempt for ID: #{proc_id}"
        # callback.call(proc_id, message) if callback
        puts "PUTS: #{message}"
    else
        raise StandardError, "This is my error message"
    end
end

def handle_error(proc_id:, retries:, max_retries:, &callback)
    retries += 1
    retry_msg = "Retry #{retries} / #{max_retries}"
    puts "PUTS: #{retry_msg}"
    # callback.call(proc_id, retry_msg)
    return retries
end

def with_retries(max_retries:, proc_id:, &callback)
    retries = 0
    begin
        yield
    rescue StandardError => e
        retries = handle_error(proc_id: proc_id, retries: retries, max_retries: max_retries, &callback)
        sleep 1.0
        retry if retries < max_retries
    end
end


def process_item(proc_id:, &callback)
    init_msg = "Starting with #{proc_id}"
    callback.call(proc_id, init_msg)
    with_retries(max_retries: 3, proc_id:) do
        print_attempt_number(proc_id: proc_id, &callback)
    end
end



callback = Proc.new do |proc_id, message|
    puts "CALLBACK: #{proc_id}\t#{message}"
end

for id in 1..5 do
    process_item(proc_id: id, &callback)
    sleep 1.0
end

产生:

CALLBACK: 1     Starting with 1
PUTS: Attempt for ID: 1
CALLBACK: 2     Starting with 2
PUTS: Retry 1 / 3
PUTS: Attempt for ID: 2
CALLBACK: 3     Starting with 3
PUTS: Retry 1 / 3
PUTS: Attempt for ID: 3
CALLBACK: 4     Starting with 4
PUTS: Retry 1 / 3
PUTS: Retry 2 / 3
PUTS: Retry 3 / 3
CALLBACK: 5     Starting with 5
PUTS: Attempt for ID: 5

我不明白为什么会发生这种情况;如何使用打印消息的回调来实现所需的打印?

ruby callback retry-logic
1个回答
0
投票

显然,不将其作为块传递(没有

&
)解决了我的用例:

def print_attempt_number(proc_id, callback)
    random = [true, false].sample
    if random
        message = "Attempt for ID: #{proc_id}"
        callback.call(proc_id, message)  # Use callback without block syntax
    else
        raise StandardError, "This is my error message"
    end
end

def handle_error(proc_id, retries, max_retries, callback)
    retries += 1
    retry_msg = "Retry #{retries} / #{max_retries}"
    callback.call(proc_id, retry_msg)  # Use callback without block syntax
    retries
end

def with_retries(max_retries, proc_id, callback)
    retries = 0
    begin
        yield  # Execute the block provided to with_retries
    rescue StandardError => e
        retries = handle_error(proc_id, retries, max_retries, callback)
        sleep 1.0
        retry if retries < max_retries
    end
end

def process_item(proc_id, callback)
    init_msg = "Starting with #{proc_id}"
    callback.call(proc_id, init_msg)  # Call the callback with init message
    with_retries(3, proc_id, callback) do
        print_attempt_number(proc_id, callback)  # Pass callback without using & syntax
    end
end

callback = Proc.new do |proc_id, message|
    puts "CALLBACK: #{proc_id}\t#{message}"
end

for id in 1..5 do
    process_item(id, callback)
    sleep 1.0
end
© www.soinside.com 2019 - 2024. All rights reserved.