我有一個Worker
和Job
的例子,其中每個Job
有一個昂貴的/緩慢的方法。爲什麼delete_at不會刪除提供的索引處的元素?
如果我在我的@job_table
中有10 Jobs
,我希望將它們分批處理5次,每次都在他們自己的過程中。 5個進程(一批)退出之後,我試圖從@job_table
和delete_at
中刪除那些Jobs
。
我觀察東西在我意想不到的實施(見下面的代碼),但:
jobs:
[#<Job:0x007fd2230082a8 @id=0>,
#<Job:0x007fd223008280 @id=1>,
#<Job:0x007fd223008258 @id=2>,
#<Job:0x007fd223008208 @id=3>,
#<Job:0x007fd2230081e0 @id=4>,
#<Job:0x007fd2230081b8 @id=5>,
#<Job:0x007fd223008190 @id=6>,
#<Job:0x007fd223008168 @id=7>,
#<Job:0x007fd223008140 @id=8>,
#<Job:0x007fd223008118 @id=9>]
這是@job_table
運行首批之前。我看到Jobs
0-4已經運行併成功退出(這裏省略輸出)。 所以我打電話remove_batch_1
和期望的工作0-4從@job_table
被刪除,但是這是我觀察,而不是:
jobs:
[#<Job:0x007fd223008280 @id=1>,
#<Job:0x007fd223008208 @id=3>,
#<Job:0x007fd2230081b8 @id=5>,
#<Job:0x007fd223008168 @id=7>,
#<Job:0x007fd223008118 @id=9>]
我登錄的方法i
參數,並將其返回0-4。但它看起來像delete_at
正在刪除其他工作(0,2,4,6,8)。
我還寫了另一種刪除批次remove_batch_0
的方法,它使用slice!
並按預期行事。
BATCH_SIZE = 5 || ENV['BATCH_SIZE']
class Job
def initialize(id)
@id = id
end
def perform
puts "Job #{@id}> Start!"
sleep 1
puts "Job #{@id}> End!"
end
end
class Worker
def initialize
@job_table = []
fill_job_table
work_job_table
end
def fill_job_table
10.times do |i|
@job_table << Job.new(i)
end
end
def work_job_table
until @job_table.empty?
puts "jobs: "
pp @job_table
work_batch
Process.waitall
remove_batch_1
end
end
def work_batch
i = 0
while (i < @job_table.length && i < BATCH_SIZE)
fork { @job_table[i].perform }
i += 1
end
end
def remove_batch_1
i = 0
while (i < @job_table.length && i < BATCH_SIZE)
@job_table.delete_at(i)
i += 1
end
end
def remove_batch_0
@job_table.slice!(0..BATCH_SIZE-1)
end
end
Worker.new
我無法相信我錯過了!謝謝。 – wpp