The Result

Let’s delve into how to simulate and manage long running processes in fie.

You probably already know about commanders, which are used by fie in the same way controllers are used by Ruby on Rails. However, since long running processes are handled by the Active Jobs framework which is external to fie’s commanders, fie has another feature called Manipulator which injects your classes with the ability to manipulate the state of your user’s views in the same way as the commander.

By including Manipulator within your classes, you provide them with access to basic fie commander methods which include state for viewing and changing the shared state, execute_js_function to execute a JavaScript function from the backend, and commander_exists? to verify whether the commander/client whose state you wish to manipulate still exists.

Your first step to recreating the example displayed in the GIF above is to define your instance variables (or your overall state) within your controller which should look like this:

As you can see, two instance variables are created and will be used for the following purpose:

@long_job_progress keeps track of the progress of our simulated long running job, which is 0 out of 100 at the time of initialization.

keeps track of the progress of our simulated long running job, which is 0 out of 100 at the time of initialization. @is_long_job_running , verifies whether the long running job is currently running or not. If we do not keep track of whether the job is already running or not, we risk having the same job run multiple times concurrently, especially if the view does not prevent the user from triggering it multiple times for one reason or another.

Once your state is initialized in your controller, the next step is to create your view which will display the progress of your long running job to the user:

The view may display one of two things depending on whether the job is already running or not (which is represented in the @is_long_job_running instance variable).

If the job is already running, the user will see a progress bar equal to the current value of the @long_job_progress instance variable and a maximum value of 100. Therefore as the value of @long_job_progress changes, so will the progress bar. If the job has finished or not yet started, the user will simply see a button that will prompt them to start the long running job. If the user clicks on the button, the commander method start_long_job will be triggered.

As the button is currently triggering a method named start_long_job in our commander and it does not yet exist, we will create it. It should look like this:

To begin with, if the job is currently running, the method simply exits (through an empty return). Otherwise, the value of @long_job_progress is reset to 0 and the long job is set as running through modifying the value of @is_long_job_running to true. The actual job is then set to run asynchronously through its perform_later method. We also pass the identifier of our commander @connection_uuid to the job so that the commander can manipulate the state of our commander/view.

Let’s now create the part we have been waiting for, the actual JOB (in the app/jobs folder):

It is first important to note that we include the Manipulator module through include Fie::Manipulator in order to have access to the methods necessary to modify the state from our job.

Once we include Fie::Manipulator , the next step is to define the perform method of our job which accepts as an argument the identifier connection_uuid of our commander/view. In order for the methods included from Fie::Manipulator to work, we need to define the instance variable @fie_connection_uuid as equal to the connection_uuid of the commander/view whose state we would like to manipulate. After doing so, we can create a lambda literal named is_job_finished which will tell us whether the progress of the job is over 100 or not.

Based on whether the job has finished running or not (meaning the client disconnected or the job completed at a progress of ≥ 100), the job will complete one of two actions.

If the client is still connected (verified through the commander_exists? method) and the job is still running (verified through calling is_job_running ), the value of @long_process_progress is increased by 10, and after a waiting period of 1 second, the job is then run again. The user will see it as their progress bar being more complete. Otherwise, the value of @is_long_job_running is set to false which will notify all other parts of the application that the job has finished running. The user will see this as their progress bar converting into a button again.

You can try this example at https://fie.eranpeer.co/showcase#long-running-job.