Operations
Operations are Lato's system for visually managing the execution of background Jobs.
Operations are handled by several components:
- The
Lato::Operation
model initializes all operations and tracks their execution state. - The
Lato::OperationsController
controller manages user access to an ongoing operation. - The
lato_operation
component allows displaying the operation status in the front-end.
Converting a Job into an Operation
The easiest way to convert a Job into an operation is to simply make the Job a subclass of Lato::ApplicationJob
.
Additionally, the perform()
method must accept a single Hash parameter called params
.
# Before def MyJob < ApplicationJob def perform(hello) puts hello end end # After def MyJob < Lato::ApplicationJob def perform(params = {}) puts params['hello'] end end
Generating an Operation
Operations can be generated using the generate
method of the Lato::Operation
model.
Creating an operation requires three parameters: the name of the job to execute, a Hash of parameters to pass, and the ID of the user requesting the operation.
operation = Lato::Operation.generate('ExportProductsJob', { product_ids: [1, 2, 3] }, @session.user_id)
Once generated, the operation must be started using the start
method.
Here is an example controller that starts an operation:
class CustomController < ApplicationController def create_operation_action @operation = Lato::Operation.generate('OperationExampleJob', {}, @session.user_id) respond_to do |format| if @operation.start format.html { redirect_to lato.operation_path(@operation) } format.json { render json: @operation } else format.html { render :index, status: :unprocessable_entity } format.json { render json: @operation.errors, status: :unprocessable_entity } end end end end
Displaying the Outcome of an Operation
Each operation can be viewed at the route lato.operation_path(operation_id)
.
To ensure data security, an operation is only accessible to the user who initiated it.
Each operation can have four states: created
, running
, completed
, failed
.
The operation view, handled via the lato_operation
component, shows the real-time status and output of the operation.
Use the link below to try out an operation:
<%= link_to 'Generate Operation', main_app.custom_create_operation_action_path, data: { turbo_method: :post } %>Generate Operation
Notes
To display the result of an operation directly in-page, you can use lato_action_controller
features.
Example:
<%= link_to 'Generate Operation', main_app.custom_create_operation_action_path, data: { lato_action_target: 'trigger', turbo_method: :post, turbo_frame: 'lato_operation' } %>Generate Operation with Success
Handling Operation Outputs
An operation's output can be handled directly within the Job using a series of helper methods.
These functions can also be called even if the Job is executed without using the Lato::Operation
model.
Set an Output Message
class MyJob < Lato::ApplicationJob def perform(params = {}) save_operation_output_message("Operation succeeded with this message") end end
Set an Output File
class MyJob < Lato::ApplicationJob def perform(params = {}) file_path = Rails.root.join('tmp', 'myfile.csv') save_operation_output_file(file_path) end end
Set an Error
class MyJob < Lato::ApplicationJob def perform(params = {}) raise "This is the operation error message" end end
Update Progress Percentage
class MyJob < Lato::ApplicationJob def perform(params = {}) 10.times do |index| sleep(1) update_operation_percentage((index + 1) * 10) end end end
Set an Input File
<%= form_with url: create_operation_action_path(type: 'file_input'), data: { lato_action_target: 'triggerSubmit', turbo_frame: 'lato_operation', controller: 'lato-form' } do |form| %> ...
class CustomController < ApplicationController def create_operation_action @operation = Lato::Operation.generate('OperationExampleJob', {}, @session.user_id, params[:file]) # ... end end
class MyJob < Lato::ApplicationJob def perform(params = {}) save_operation_output_message("You uploaded the file #{operation_input_file_attachment.filename}") end end