Я пытаюсь реализовать сканер, который посещает какой-то URL-адрес, собирает из него новые относительные URL-адреса и создает отчет. Я пытаюсь сделать это одновременно, используя волокна и каналы Crystal, например:
urls = [...] # of String
visited_urls = []
pool_size.times do
spawn do
loop do
url = urls.shift?
break if url.nil?
channel.send(url) if some_condition
end
end
end
# TODO: here the problem!
loop do
url = channel.receive?
break if url.nil? || channel.closed?
visited_urls << url
end
puts visited_urls.inspect
Но здесь у меня проблема - бесконечная секунда loop
(она вызывает channel.receive?
до последнего элемента в канале, а затем ждет нового сообщения, которое никогда не приходит). Проблема существует, потому что я никогда не знаю, сколько элементов на самом деле в канале, поэтому я не могу сделать то, что предлагается в Concurency Руководства по языку Crystal.
Так что, может быть, есть хорошие практики работы с каналом, когда мы не знаем, сколько предметов он будет хранить, а нам нужно получить? Спасибо!