What is the best way to run a background process in Rails 5?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
I have a web application where I need to perform a process that takes a while to complete (Usually 1 minute).
I'll try to explain it briefly: In my app I have an algorithm that assigns foreign keys to a set of objects based on a bunch of parameters (mainly dates). When a user presses the designated button inside my application a controller method is executed. Inside that method I make a call to a method in the model where all the logic is handled and the keys are being assigned. As mentioned before, the whole process takes about a minute to complete.
So my question is: What is the best way to run this process in the background in Rails 5? I obviously don't want to force my users to wait an entire minute before they can navigate around the application and I also don't want the application to time out while the browser is waiting for a response from the server. So what's the best way to handle this? Do I need a framework that can make the request asynchronously? If so, which one? (I would prefer if it doesn't require too many dependencies and if I can keep using ActiveRecord).
I haven't really worked too much with ActionCable or AJAX, but if they can get the job done in any way, then I would be thrilled to know how.
Ideally I should be able to send a notification to the user, within the app, once the process is done
view.html.erb:
# Button the user presses to execute the algorithm
<%= link_to 'execute algorithm', algorithm_path(@variable), :method => :put %>
my_controller.rb:
def button_method
Object.execute_algorithm(@variable)
redirect_to :back
end
Object.rb:
def self.execute_algorithm(variable)
# Logic
end
ruby-on-rails ruby-on-rails-5 background-process
add a comment |
I have a web application where I need to perform a process that takes a while to complete (Usually 1 minute).
I'll try to explain it briefly: In my app I have an algorithm that assigns foreign keys to a set of objects based on a bunch of parameters (mainly dates). When a user presses the designated button inside my application a controller method is executed. Inside that method I make a call to a method in the model where all the logic is handled and the keys are being assigned. As mentioned before, the whole process takes about a minute to complete.
So my question is: What is the best way to run this process in the background in Rails 5? I obviously don't want to force my users to wait an entire minute before they can navigate around the application and I also don't want the application to time out while the browser is waiting for a response from the server. So what's the best way to handle this? Do I need a framework that can make the request asynchronously? If so, which one? (I would prefer if it doesn't require too many dependencies and if I can keep using ActiveRecord).
I haven't really worked too much with ActionCable or AJAX, but if they can get the job done in any way, then I would be thrilled to know how.
Ideally I should be able to send a notification to the user, within the app, once the process is done
view.html.erb:
# Button the user presses to execute the algorithm
<%= link_to 'execute algorithm', algorithm_path(@variable), :method => :put %>
my_controller.rb:
def button_method
Object.execute_algorithm(@variable)
redirect_to :back
end
Object.rb:
def self.execute_algorithm(variable)
# Logic
end
ruby-on-rails ruby-on-rails-5 background-process
ActiveJob should be able to handle this. Though I'm curious what's the purpose of the custom foreign key process, and why does it take a minute?
– Schwern
Nov 23 '18 at 16:24
add a comment |
I have a web application where I need to perform a process that takes a while to complete (Usually 1 minute).
I'll try to explain it briefly: In my app I have an algorithm that assigns foreign keys to a set of objects based on a bunch of parameters (mainly dates). When a user presses the designated button inside my application a controller method is executed. Inside that method I make a call to a method in the model where all the logic is handled and the keys are being assigned. As mentioned before, the whole process takes about a minute to complete.
So my question is: What is the best way to run this process in the background in Rails 5? I obviously don't want to force my users to wait an entire minute before they can navigate around the application and I also don't want the application to time out while the browser is waiting for a response from the server. So what's the best way to handle this? Do I need a framework that can make the request asynchronously? If so, which one? (I would prefer if it doesn't require too many dependencies and if I can keep using ActiveRecord).
I haven't really worked too much with ActionCable or AJAX, but if they can get the job done in any way, then I would be thrilled to know how.
Ideally I should be able to send a notification to the user, within the app, once the process is done
view.html.erb:
# Button the user presses to execute the algorithm
<%= link_to 'execute algorithm', algorithm_path(@variable), :method => :put %>
my_controller.rb:
def button_method
Object.execute_algorithm(@variable)
redirect_to :back
end
Object.rb:
def self.execute_algorithm(variable)
# Logic
end
ruby-on-rails ruby-on-rails-5 background-process
I have a web application where I need to perform a process that takes a while to complete (Usually 1 minute).
I'll try to explain it briefly: In my app I have an algorithm that assigns foreign keys to a set of objects based on a bunch of parameters (mainly dates). When a user presses the designated button inside my application a controller method is executed. Inside that method I make a call to a method in the model where all the logic is handled and the keys are being assigned. As mentioned before, the whole process takes about a minute to complete.
So my question is: What is the best way to run this process in the background in Rails 5? I obviously don't want to force my users to wait an entire minute before they can navigate around the application and I also don't want the application to time out while the browser is waiting for a response from the server. So what's the best way to handle this? Do I need a framework that can make the request asynchronously? If so, which one? (I would prefer if it doesn't require too many dependencies and if I can keep using ActiveRecord).
I haven't really worked too much with ActionCable or AJAX, but if they can get the job done in any way, then I would be thrilled to know how.
Ideally I should be able to send a notification to the user, within the app, once the process is done
view.html.erb:
# Button the user presses to execute the algorithm
<%= link_to 'execute algorithm', algorithm_path(@variable), :method => :put %>
my_controller.rb:
def button_method
Object.execute_algorithm(@variable)
redirect_to :back
end
Object.rb:
def self.execute_algorithm(variable)
# Logic
end
ruby-on-rails ruby-on-rails-5 background-process
ruby-on-rails ruby-on-rails-5 background-process
asked Nov 23 '18 at 16:13
Tobias KristensenTobias Kristensen
445
445
ActiveJob should be able to handle this. Though I'm curious what's the purpose of the custom foreign key process, and why does it take a minute?
– Schwern
Nov 23 '18 at 16:24
add a comment |
ActiveJob should be able to handle this. Though I'm curious what's the purpose of the custom foreign key process, and why does it take a minute?
– Schwern
Nov 23 '18 at 16:24
ActiveJob should be able to handle this. Though I'm curious what's the purpose of the custom foreign key process, and why does it take a minute?
– Schwern
Nov 23 '18 at 16:24
ActiveJob should be able to handle this. Though I'm curious what's the purpose of the custom foreign key process, and why does it take a minute?
– Schwern
Nov 23 '18 at 16:24
add a comment |
2 Answers
2
active
oldest
votes
Rails uses ActiveJob, which allow you to queue up an expensive tasks and run them in the background. They are quite simple to use.
Fist, you can use rails generator to create one:
rails generate job slow_algorithm
...which will create a job under app/jobs/slow_algorithm_job.rb
. There, you can implement your algorithm logic.
Queue up the job is just as easy, simply do it in your controller:
SlowAlgorithmJob.perform_later
Last thing you need to cover is setting up queuing backend that will actually run the jobs. Rails supports couple of them. Probably the simplest one to set up is delayed_job, but if you're looking for something more scalable, I'd recommend looking into Sidekiq.
EDIT: How to notify user that the job is done?
In order to do this, you clearly have to somehow track the progress of the task. One possible direction is to create a record, let's call it a Task
, which represents one invocation of your algorithm.
When user triggers the action that should queue up the job, Task record is created with status pending
, then before_perform
and after_perform
job hooks can be used to move the Task
status to running
and then to completed
.
after_perform
hook can be used to notify the customer. How the app is going to do it, is up to you. For example, Dropbox uses similar system when downloading large amount of files. They queue up the job, the zips ups the files and then send the email with download link once the job is finished.
Another approach would be using in-app notification system.
Lastly, to have the notification pop-up without requiring user to refresh the page, you'd have to use ActiveCable
and push the notification back to user, again, using after_perform
hook.
1
I've updated the answer with a suggestion how to achieve that. Cheers.
– Mladen Ilić
Nov 23 '18 at 17:41
add a comment |
I will suggest sidekiq as a better solution for background tasks
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53449925%2fwhat-is-the-best-way-to-run-a-background-process-in-rails-5%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Rails uses ActiveJob, which allow you to queue up an expensive tasks and run them in the background. They are quite simple to use.
Fist, you can use rails generator to create one:
rails generate job slow_algorithm
...which will create a job under app/jobs/slow_algorithm_job.rb
. There, you can implement your algorithm logic.
Queue up the job is just as easy, simply do it in your controller:
SlowAlgorithmJob.perform_later
Last thing you need to cover is setting up queuing backend that will actually run the jobs. Rails supports couple of them. Probably the simplest one to set up is delayed_job, but if you're looking for something more scalable, I'd recommend looking into Sidekiq.
EDIT: How to notify user that the job is done?
In order to do this, you clearly have to somehow track the progress of the task. One possible direction is to create a record, let's call it a Task
, which represents one invocation of your algorithm.
When user triggers the action that should queue up the job, Task record is created with status pending
, then before_perform
and after_perform
job hooks can be used to move the Task
status to running
and then to completed
.
after_perform
hook can be used to notify the customer. How the app is going to do it, is up to you. For example, Dropbox uses similar system when downloading large amount of files. They queue up the job, the zips ups the files and then send the email with download link once the job is finished.
Another approach would be using in-app notification system.
Lastly, to have the notification pop-up without requiring user to refresh the page, you'd have to use ActiveCable
and push the notification back to user, again, using after_perform
hook.
1
I've updated the answer with a suggestion how to achieve that. Cheers.
– Mladen Ilić
Nov 23 '18 at 17:41
add a comment |
Rails uses ActiveJob, which allow you to queue up an expensive tasks and run them in the background. They are quite simple to use.
Fist, you can use rails generator to create one:
rails generate job slow_algorithm
...which will create a job under app/jobs/slow_algorithm_job.rb
. There, you can implement your algorithm logic.
Queue up the job is just as easy, simply do it in your controller:
SlowAlgorithmJob.perform_later
Last thing you need to cover is setting up queuing backend that will actually run the jobs. Rails supports couple of them. Probably the simplest one to set up is delayed_job, but if you're looking for something more scalable, I'd recommend looking into Sidekiq.
EDIT: How to notify user that the job is done?
In order to do this, you clearly have to somehow track the progress of the task. One possible direction is to create a record, let's call it a Task
, which represents one invocation of your algorithm.
When user triggers the action that should queue up the job, Task record is created with status pending
, then before_perform
and after_perform
job hooks can be used to move the Task
status to running
and then to completed
.
after_perform
hook can be used to notify the customer. How the app is going to do it, is up to you. For example, Dropbox uses similar system when downloading large amount of files. They queue up the job, the zips ups the files and then send the email with download link once the job is finished.
Another approach would be using in-app notification system.
Lastly, to have the notification pop-up without requiring user to refresh the page, you'd have to use ActiveCable
and push the notification back to user, again, using after_perform
hook.
1
I've updated the answer with a suggestion how to achieve that. Cheers.
– Mladen Ilić
Nov 23 '18 at 17:41
add a comment |
Rails uses ActiveJob, which allow you to queue up an expensive tasks and run them in the background. They are quite simple to use.
Fist, you can use rails generator to create one:
rails generate job slow_algorithm
...which will create a job under app/jobs/slow_algorithm_job.rb
. There, you can implement your algorithm logic.
Queue up the job is just as easy, simply do it in your controller:
SlowAlgorithmJob.perform_later
Last thing you need to cover is setting up queuing backend that will actually run the jobs. Rails supports couple of them. Probably the simplest one to set up is delayed_job, but if you're looking for something more scalable, I'd recommend looking into Sidekiq.
EDIT: How to notify user that the job is done?
In order to do this, you clearly have to somehow track the progress of the task. One possible direction is to create a record, let's call it a Task
, which represents one invocation of your algorithm.
When user triggers the action that should queue up the job, Task record is created with status pending
, then before_perform
and after_perform
job hooks can be used to move the Task
status to running
and then to completed
.
after_perform
hook can be used to notify the customer. How the app is going to do it, is up to you. For example, Dropbox uses similar system when downloading large amount of files. They queue up the job, the zips ups the files and then send the email with download link once the job is finished.
Another approach would be using in-app notification system.
Lastly, to have the notification pop-up without requiring user to refresh the page, you'd have to use ActiveCable
and push the notification back to user, again, using after_perform
hook.
Rails uses ActiveJob, which allow you to queue up an expensive tasks and run them in the background. They are quite simple to use.
Fist, you can use rails generator to create one:
rails generate job slow_algorithm
...which will create a job under app/jobs/slow_algorithm_job.rb
. There, you can implement your algorithm logic.
Queue up the job is just as easy, simply do it in your controller:
SlowAlgorithmJob.perform_later
Last thing you need to cover is setting up queuing backend that will actually run the jobs. Rails supports couple of them. Probably the simplest one to set up is delayed_job, but if you're looking for something more scalable, I'd recommend looking into Sidekiq.
EDIT: How to notify user that the job is done?
In order to do this, you clearly have to somehow track the progress of the task. One possible direction is to create a record, let's call it a Task
, which represents one invocation of your algorithm.
When user triggers the action that should queue up the job, Task record is created with status pending
, then before_perform
and after_perform
job hooks can be used to move the Task
status to running
and then to completed
.
after_perform
hook can be used to notify the customer. How the app is going to do it, is up to you. For example, Dropbox uses similar system when downloading large amount of files. They queue up the job, the zips ups the files and then send the email with download link once the job is finished.
Another approach would be using in-app notification system.
Lastly, to have the notification pop-up without requiring user to refresh the page, you'd have to use ActiveCable
and push the notification back to user, again, using after_perform
hook.
edited Nov 23 '18 at 17:40
answered Nov 23 '18 at 17:25
Mladen IlićMladen Ilić
1,26011420
1,26011420
1
I've updated the answer with a suggestion how to achieve that. Cheers.
– Mladen Ilić
Nov 23 '18 at 17:41
add a comment |
1
I've updated the answer with a suggestion how to achieve that. Cheers.
– Mladen Ilić
Nov 23 '18 at 17:41
1
1
I've updated the answer with a suggestion how to achieve that. Cheers.
– Mladen Ilić
Nov 23 '18 at 17:41
I've updated the answer with a suggestion how to achieve that. Cheers.
– Mladen Ilić
Nov 23 '18 at 17:41
add a comment |
I will suggest sidekiq as a better solution for background tasks
add a comment |
I will suggest sidekiq as a better solution for background tasks
add a comment |
I will suggest sidekiq as a better solution for background tasks
I will suggest sidekiq as a better solution for background tasks
answered Nov 24 '18 at 4:53
rayray
3,3731829
3,3731829
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53449925%2fwhat-is-the-best-way-to-run-a-background-process-in-rails-5%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
ActiveJob should be able to handle this. Though I'm curious what's the purpose of the custom foreign key process, and why does it take a minute?
– Schwern
Nov 23 '18 at 16:24