我目前正在开发一个Ruby on Rails应用程序,在某些时刻必须使用第三方API导入(至少对我而言)中等大小的数据集。它必须平均进行6000次API调用。相继。它持续约20分钟。
现在我已经做了一个rails任务,可以按照我的意愿完成任务(调用,写入db等)。但是现在我希望这个任务/代码能够从网络上的按钮调用 ALSO 。我知道让控制器调用任务不是一个好方法,这就是我要问的原因。
我希望从控制器和任务中调用导入代码,因为稍后我希望能够从cronjob调用此任务,即使它可能有关于控制器上任务进度的回调,即知道还有多少次调用。
答案 0 :(得分:1)
我知道让控制器调用任务不是一个好方法
按钮触发这样的后台任务没有错,但当然你需要小心这样做。例如,也许:
有许多库可用于实现进度条,或者您甚至可以编写自定义实现。例如,请参阅this blog post - 通过投票工作当前的进度:
// app/views/exports/export_users.js.haml
:plain
var interval;
$('.export .well').show();
interval = setInterval(function(){
$.ajax({
url: '/progress-job/' + #{@job.id},
success: function(job){
var stage, progress;
// If there are errors
if (job.last_error != null) {
$('.progress-status').addClass('text-danger').text(job.progress_stage);
$('.progress-bar').addClass('progress-bar-danger');
$('.progress').removeClass('active');
clearInterval(interval);
}
progress = job.progress_current / job.progress_max * 100;
// In job stage
if (progress.toString() !== 'NaN'){
$('.progress-status').text(job.progress_current + '/' + job.progress_max);
$('.progress-bar').css('width', progress + '%').text(progress + '%');
}
},
error: function(){
// Job is no loger in database which means it finished successfuly
$('.progress').removeClass('active');
$('.progress-bar').css('width', '100%').text('100%');
$('.progress-status').text('Successfully exported!');
$('.export-link').show();
clearInterval(interval);
}
})
},100);
您可以考虑的变体方法是使用 websocket 来查看进度,而不是轮询。
答案 1 :(得分:0)
将大部分代码从任务移动到模型中的模块或方法。您可以从任务中调用此代码(就像您现在这样做),也可以从按下视图上的按钮时通过控制器启动的后台作业调用此代码。
答案 2 :(得分:0)
将特定任务转换为后台作业,即(活动作业,sideqik),这样您的系统就可以在执行任务时继续工作。为每个任务创建类,并在后台作业或cronjobs中调用这些类。 一个适合这里的设计模式是“命令”模式,我给你一个你可以谷歌的东西列表:)。