Как запустить REST-вызов одновременно или с более низким приоритетом
Я загружаю данные через вызов REST и рендеринг его. После этого я вызываю другой REST API, который занимает около 10 секунд. В это время я не могу сделать еще один вызов REST, пока этот не закончится. У меня вопрос, как я могу это сделать?
Я пытался с потоком, но это не работает, возможно, я делаю что-то не так, или, возможно, потоки не правильный выбор?
Это названный маршрут:
get '/api/dashboard/:dbnum/block/:blnum/inbackground/:inbackground' do
user = get_current_userobject
return assemble_error('LOGIN', 'NOTLOGGEDIN', {}, []).rest_fail if !user
dbnum,blnum = params[:dbnum].to_i, params[:blnum].to_i
return { rows: [] }.rest_success if !user.dashboardinfo || !user.dashboardinfo[dbnum] || !user.dashboardinfo[dbnum]['blocks'] || !(block = user.dashboardinfo[dbnum]['blocks'][blnum]) || !respond_to?("dashboard_type_#{block['type']}", true)
if params[:inbackground] == 'true'
t = Thread.new do
t.priority= -1
ret = method("dashboard_type_#{block['type']}").call(block['filters'], false, true)
ret.rest_success
end
t.join
t.exit
else
ret = method("dashboard_type_#{block['type']}").call(block['filters'], false, false)
ret.rest_success
end
end
Как я могу запустить код в строке 8-22 в "фоне", чтобы другие вызовы имели приоритет?
1 ответ
Команда t.join
ждет окончания потока. Если вы хотите, чтобы ваш поток работал в фоновом режиме, просто запустите и забудьте:
get '/api/dashboard/:dbnum/block/:blnum/inbackground/:inbackground' do
user = get_current_userobject
return assemble_error('LOGIN', 'NOTLOGGEDIN', {}, []).rest_fail if !user
dbnum,blnum = params[:dbnum].to_i, params[:blnum].to_i
return { rows: [] }.rest_success if !user.dashboardinfo || !user.dashboardinfo[dbnum] || !user.dashboardinfo[dbnum]['blocks'] || !(block = user.dashboardinfo[dbnum]['blocks'][blnum]) || !respond_to?("dashboard_type_#{block['type']}", true)
if params[:inbackground] == 'true'
t = Thread.new do
t.priority= -1
ret = method("dashboard_type_#{block['type']}").call(block['filters'], false, true)
ret.rest_success
end
else
ret = method("dashboard_type_#{block['type']}").call(block['filters'], false, false)
ret.rest_success
end
end
Конечно, проблема в том, что вы получаете кучу мертвых потоков, которые накапливаются во время работы вашего сервера. И если вы работаете в REST API (разработанном так, чтобы он не имел состояния), это может быть не так просто, как перебрасывать ваши потоки в массив и периодически очищать их.
В конечном счете, я думаю, вы должны изучить асинхронные обработчики заданий. Я работал с sidekiq и хорошо провел время, но у меня недостаточно опыта, чтобы дать вам искреннюю рекомендацию.