2016-06-01 1 views
0

Создал скрипт, который проверяет статус проверки работоспособности и портов в файле .json, заполненном микросервисами. Итак, для каждого микросервиса из файла .json скрипт выведет статус HTTP и тело bodycheck и другие мелкие детали, и я хочу добавить сюда многопоточность, чтобы сразу вернуть весь вывод. Пожалуйста, смотрите ниже скрипт:Добавить многопоточность/совпадение в скрипте

#!/usr/bin/env ruby 
... get the environment argument part... 

file = File.read('./services.json') 
data_hash = JSON.parse(file) 

threads = [] 
service = data_hash.keys 
service.each do |microservice| 
threads << Thread.new do 
    begin 
    puts "Microservice: #{microservice}" 
    port = data_hash["#{microservice}"]['port'] 
    puts "Port: #{port}" 

    nodes = "knife search 'chef_environment:#{env} AND recipe:#{microservice}' -i" 
    node = %x[ #{nodes} ].split 
    node.each do |n| 
    puts "Node: #{n}" 
    uri = URI("http://#{n}:#{port}/healthcheck?count=10") 
    res = Net::HTTP.get_response(uri) 
    status = Net::HTTP.get(uri) 
    puts res.code 
    puts status 
    puts res.message 
    end 

rescue Net::ReadTimeout 
    puts "ReadTimeout Error" 
    next 
end 
end 
end 
threads.each do |thread| 
    thread.join 
end 

В любом случае сценарий возвращает сначала «Microservice: # {microservice}» и помещает «Port: # {port}», после чего он вернет узлы и только после STATUS. Как я могу вернуть все данные для каждого цикла вместе?

+0

Влад, ознакомьтесь с методом 'map', это очень удобно. Вы можете упростить свой код, выполнив: 'threads = service.map ...'. Кроме того, 'service', вероятно, должен быть назван' services', чтобы указать множественное число. –

ответ

1

Вместо puts запись вывода в переменную (хэш). Если вы хотите, чтобы все потоки завершили работу, прежде чем показывать результат, используйте класс ThreadsWait.

require 'thwait' 
file = File.read('./services.json') 
data_hash = JSON.parse(file) 

h = {} 
threads = [] 
service = data_hash.keys 
service.each do |microservice| 
threads << Thread.new do 
    thread_id = Thread.current.object_id.to_s(36) 
    begin 
    h[thread_id] = "Microservice: #{microservice}" 
    port = data_hash["#{microservice}"]['port'] 
    h[thread_id] << "Port: #{port}" 

    nodes = "knife search 'chef_environment:#{env} AND recipe:#{microservice}' -i" 
    node = %x[ #{nodes} ].split 
    node.each do |n| 
    h[thread_id]<< "Node: #{n}" 
    uri = URI("http://#{n}:#{port}/healthcheck?count=10") 
    res = Net::HTTP.get_response(uri) 
    status = Net::HTTP.get(uri) 
    h[thread_id] << res.code 
    h[thread_id] << status 
    h[thread_id] << res.message 
    end 

rescue Net::ReadTimeout 
    h[thread_id] << "ReadTimeout Error" 
    next 
end 
end 
end 
threads.each do |thread| 
    thread.join 
end 

# wait untill all threads finish their job 
ThreadsWait.all_waits(*threads) 

p h 

[править]

ThreadsWait.all_waits(*threads) избыточен в коде выше и может быть опущен, так как линия treads.each do |thread| thread.join end делает exactely то же самое.

+0

Да, работает, спасибо за идее, в основном он возвращает HASH, как это {"8x694" => "Microservice: microservice1Port: 27580Node: node404 {\" ... –

+1

Присоединение потоков может быть реализовано более сжато, threads.each (&: присоединиться) '. Разве это уже не ждет завершения всех потоков? Что добавляет 'ThreadsWait'? –

+0

Влад, ты прав. Строки должны иметь новые строки в конце (например, мои должны иметь). Кроме того, что-то, что мне показалось удобным, заключается в том, что вместо построения строки для построения хеша с описательными именами ключей. Затем вы можете использовать awesome_print для вывода их очень читабельным способом. –

1

Вместо того, чтобы выводить данные по мере их использования с помощью puts, вы можете собрать все это в строку, а затем puts это один раз в конце. Строки могут взять << оператор (реализованный как метод в Ruby), так что вы можете просто инициализировать строку, добавить к нему, а затем выводит его в конце, как это:

report = '' 
report << 'first thing' 
report << 'second thing' 
puts report 

Вы можете даже сохранить их все вместе и распечатайте их все, если хотите.

+0

Я тоже пробовал это решение и работает, любой идеей, как сломать это, чтобы просмотреть каждый элемент на новой строке? –

+1

Изменить отчет на массив: 'report = []', а затем в конце 'puts report.join (" \ n ")' – maicher