Git Product home page Git Product logo

respond_from_active_job's Introduction

Respond from ActiveJob

Using ActiveJob, ActionCable and StimulusJS

Check out the sample

Motivation

Often you want to offload long running tasks to an asynchronous job but you also need to update the UI as soon as possible, without having the user refresh the whole page.

Rails supports spinning off tasks out of the box with ActiveJob, and also makes it easy to broadcast updates to the client with ActionCable. The core goal of this example is to demonstrate the use of those two together.

For completeness, we'll also use Stimulus to keep the front-end organized, and add some basic tests using rspec.

Overview

This application is a single view that shows all the "process runs", that simulate long running tasks. You can click on "Start 10 processes" and 10 processes will be spun up, and their status will be updated in the UI as the jobs progress.

The long running "process runs" are achieved with a call to sleep with a random interval, this is just for illustration purposes. In production, you would get this delay from an actual task. You can see how these simulated delays work in the ProcessRun model.

The gist

The job (ProcessRunJob) broadcasts the status changes using ActionCable:

Check out the sample.

# app/jobs/process_run_job.rb

class ProcessRunJob < ApplicationJob
  # ...

  def perform
    # ...

    ProcessRunsChannel.broadcast_to process_run, status: process_run.status
  end
end

And the UI is updated, in this case using Stimulus. To prevent ordering issues, the UI checks the status using the process_runs/show endpoint, though this might be overkill. You can probably get away just using the payload in the broadcast:

// app/javascript/controllers/process_run_row_controller.js
// ...

export default class extends Controller {
  // ...

  connectToChannel() {
    consumer.subscriptions.create({
      channel: 'ProcessRunsChannel',
      id: this.recordId
    }, {
      connected: () => {},
      disconnected: () => {},
      received: ({ status }) => { this.statusColTarget.innerText = status }
    });
  }
}

Also noteworthy

The ProcessRunsChannel is very standard per the ActionCable guides, but it includes the safeguard of transmitting the current status upon each subscription, in case the status changes while the first response is in flight (sounds unlikely, but I have seen it in production):

class ProcessRunsChannel < ApplicationCable::Channel
  # ...

  def subscribed
    return if subscription_rejected?

    stream_for process_run
    transmit finished: process_run.finished
  end

  #...
end

As mentioned before, this example is reasonably tested, don't forget to check out the spec directory, and write some tests for your production code!

Contributing

Feel free to open a PR, Issue, or contact me, to suggest improvements or discuss any problems, errors or opinions.

respond_from_active_job's People

Contributors

perezperret avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.