Search code examples
ruby-on-railsrubyremote-accesspsexec

remotely launching a ruby script via a webpage


I have 3 machines (more in reality but 3 for the purposes of this question) on a network, 2 workstations and a server. The server hosts a Rails app which is visited by users on Workstation A, which allows them to view and analyze data from the server's database.. I've also got a Ruby script on Workstation B that generates data and stores to a database on the server. I want the Rails app to have a function to launch that Ruby script on Workstation B when a user on A clicks a certain button on a page of the Rails app, so that 1. as much of my system is contained in the app as possible and 2. I can avoid having to connect through a remote desktop or even worse, physically going to Workstation B.

I really have no idea how to approach this on even a basic level; I've used PSExec in the past to remotely launch processes, but I don't know if that tool would be viable for this application. If it is I can not image how to use it for that purpose. Can somebody point me in the right direction?


Solution

  • There are a bunch of different ways to launch a subprocess from ruby-- system, exec, backticks, open3. They're all slightly different depending on how you want to interact with it exactly-- this answer to a similar question contains a handy flowchart. I'm not sure which works best on which version of Windows with which version of Ruby; you should search with each one of these options and your versions to find out.

    Within a controller action in your rails app, you can call one of these to execute your ruby script, ex:

    require 'open3'
    
    class WhateverController < ActionController
      def start
        Open3.popen3('ruby your_script.rb') {|stdin, stdout, stderr, wait_thr|
          # do whatever you need to with the output streams here
        }
        render nothing: true # So that the request returns to the user who pushed the button
      end
    end
    

    I'd recommend making this a POST request, making sure you have authorization on it, possibly keeping track of the last time anyone ran this if it takes a long time to run and you don't want people pushing the button a lot, etc.