При многопоточности Ruby (с j ruby). Как я могу передать постоянный вывод в файл, который будет виден сразу, а не в конце потока? - PullRequest
0 голосов
/ 15 апреля 2020

Im Пишу простое терминальное приложение j ruby, чтобы помочь понять многопоточность. Это в основном приложение лифта, поэтому каждый лифт будет работать в своем собственном потоке ... Пользователь вводит желаемый уровень, который затем формулирует задание и добавляет его в очередь. Моя текущая загвоздка в том, что я пытаюсь добавить детали в конце каждого задания в очереди в текстовый файл. У каждого лифта есть один из этих файлов, и он будет использоваться для извлечения данных из дальней части пути и позволит пользователю видеть, кто находится в башне. Atm поток не будет печатать выходные данные в файл, независимо от того, как я его структурирую, пока поток не завершится. Есть ли способ настроить какой-то поток из потока, чтобы он обновлял файл в режиме реального времени ... даже если мне придется закрывать и открывать файл снова для каждой записи?

Глядя в основном на функция do_work


require 'timers'

class Lift 

attr_reader :lift_num, :time_until_free, :job_que

  def initialize(lift_num, store)
    @lift_num = lift_num
    @current_floor = "Ground"
    @destination = nil
    @job_que = []
    @time_until_free = nil
    @state = {
      :active => false
    }
    self.add_to_store(store)
  end

  def state_updater(key)
    @state[key] = !@state[key]
  end

  def state?(key)
    !!@state[key]
  end

  def add_to_store(store)
    store.store_lift(self)
  end

  def job_quer(job)
    if state?(:active) == false
      @job_que << job
      state_updater(:active)
      return do_work()
    end
    @job_que << job 
  end

  def do_work
    Thread.new{
      timers = Timers::Group.new
      File.open("Lift#{@lift_num}_movements.txt", 'w') do |file|
        while state?(:active) == true && @job_que.length > 0
          job = @job_que[0]
          job_timer = timers.after(job.fetch(:travel_time)) { file << "Dropping #{job.fetch(:traveller)} at level #{job.fetch(:floor)}" }
          timers.wait
          @job_que.reject! {|job| job == @job_que[0]}
        end
      end
    }
  end
end```
open to suggestions
...