Operations
Operations are Lato's system for visually managing the execution of background Jobs.
Operations are handled by several components:
- The
Lato::Operationmodel initializes all operations and tracks their execution state. - The
Lato::OperationsControllercontroller manages user access to an ongoing operation. - The
lato_operationcomponent 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