2017-01-05 3 views
-1

У меня есть ряд задач, которые необходимо выполнить последовательно. После реорганизации логики задачи из методов в отдельные классы, я вижу, что их производительность перестает быть последовательной (т. Е. Вторая и третья задачи начинаются до завершения первого). Что здесь происходит и как я могу обеспечить последовательную производительность?Ruby - как обеспечить последовательное выполнение

Исходный код выглядел так:

class MyClass 
    def do_stuff 
    do_first_thing 
    do_second_thing 
    do_third_thing 
    end # each waits for its predecessor to finish before starting 

    def do_first_thing 
    # takes a minute to complete 
    end 

    def do_second_thing 
    # takes a minute to complete 
    end 

    def do_third_thing 
    # takes a minute to complete 
    end 
end 

переработан код выглядит следующим образом:

class MyClass 
    def do_stuff 
    FirstThing.new.do_it 
    SecondThing.new.do_it 
    ThirdThing.new.do_it 
    end # for some reason, each doesn't wait for its predecessor to finish before starting 
end 

class FirstThing 
    def do_it 
    # takes a minute to complete 
    end 
end 

class SecondThing 
    def do_it 
    # takes a minute to complete 
    end 
end 

class ThirdThing 
    def do_it 
    # takes a minute to complete 
    end 
end 

EDIT: нет резьбы или параллельной обработки не происходит или по желанию.

EDIT: Я использовал следующий код, чтобы попытаться воспроизвести мою проблему, и, похоже, она работает, поэтому, возможно, проблема лежит где-то в другом месте. Я опубликую прогресс и результаты здесь.

# 
# OLD VERSION 
# 

class OldJob 
    def work_it 
    move_it 
    shake_it 
    bake_it 
    end 

    def move_it 
    puts "MOVING IT..." 
    sleep 5 
    end 

    def shake_it 
    puts "SHAKING IT..." 
    sleep 5 
    end 

    def bake_it 
    puts "BAKING IT..." 
    sleep 5 
    end 
end 

OldJob.new.work_it 

puts "-----------" 

# 
# NEW VERSION 
# 

class MoveJob 
    def do_it 
    puts "MOVING IT..." 
    sleep 5 
    end 
end 

class ShakeJob 
    def do_it 
    puts "SHAKING IT..." 
    sleep 5 
    end 
end 

class BakeJob 
    def do_it 
    puts "BAKING IT..." 
    sleep 5 
    end 
end 

class NewJob 
    def work_it 
    MoveJob.new.do_it 
    ShakeJob.new.do_it 
    BakeJob.new.do_it 
    end 
end 

NewJob.new.work_it 

результаты, как и ожидалось в:

ruby --->> ruby ~/Desktop/my_job.rb 
MOVING IT... 
SHAKING IT... 
BAKING IT... 
----------- 
MOVING IT... 
SHAKING IT... 
BAKING IT... 

FINAL EDIT:

Так что получается в спешке рефакторинга, рефакторинга на несколько подобных классов, я неверно названы некоторые из имен классов, которые что их исполнение не произошло. Следовательно, зависимые классы не имели доступа к результатам предыдущего процесса, потому что они не имели места. Интересно отметить, что я не видел ошибок, связанных с неоднозначностью имени класса, что и было основной причиной.

Моя проблема решена. Не стесняйтесь удалять?/Закрыть этот вопрос.

+0

Возможно, вы захотите предоставить больше информации о том, что именно происходит в ваших методах, b/c звучит так, будто вы выполняете асинхронную обработку в своих методах, а это значит, что вам придется переработать некоторые вещи, чтобы их получить оценивая по порядку. – GDP2

+0

Просьба уточнить вашу конкретную проблему. Как это написано в настоящее время, трудно точно сказать, что происходит не так. – akuhn

+1

Я согласен с @ GPD2 здесь. Код, который вы публикуете, будет работать последовательно. –

ответ

1

Я понимаю, что ваши задачи выполняются в отдельных потоках, потому что иначе они будут последовательными.

Предполагая, что они работают в отдельных потоках, вы можете сделать это последовательно с помощью обратных вызовов. Они более распространены в Javascript, но, безусловно, выполняются и в Ruby.

Пример определения задач принимать обратные вызовы

class FirstThing 
    def do_it(&callback) 
    Thread.new do 
     # do stuff 
     callback.call 
    end 
    end 
end 

Затем запустите первую задачу, ссылаясь на вторую задачу обратного вызова:

FirstThing.new.run do 
    SecondThing.new.run 
end 

Обратите внимание, что ваш метод MyClass#do_stuff будет немедленно вернуться, не дождитесь завершения обратных вызовов. Без какого-либо блокирующего цикла невозможно сделать синхронный асинхронный код.

+1

Это 'do_it',' run' или 'do_stuff'? :) –