【问题标题】:Porting a command line app to Sinatra/Ruby on Rails app将命令行应用程序移植到 Sinatra/Ruby on Rails 应用程序
【发布时间】:2015-01-13 20:13:32
【问题描述】:

我有一个运行几分钟的 Ruby 命令行应用程序。在执行过程中,在应用程序的每个阶段完成后,我会在命令行输出中打印几条消息。

这只是为了让用户知道应用程序正在运行的阶段,并让应用程序提供更多信息。

现在,我想将应用程序移植到 Sinatra 应用程序。我已经准备好了整个框架。我正在使用 jQuery AJAX 将输出结果打印回用户。

问题是,它只在整个应用程序运行后才呈现输出,因此,它是非响应式的(与命令行应用程序相比)。在某些情况下,整个应用程序甚至可能需要 2-3 分钟才能运行,然后将结果打印到网页上。

这相当于做一个 POST 并且我没有从这里的 jQuery AJAX 调用中获得任何东西。 有没有办法,我可以将打印到 STDOUT 的相同消息发送回网页上的用户。

这可能是一个非常简单的问题,但我是新手,过去没有做过类似的事情。

如果您需要更多信息,请告诉我。

【问题讨论】:

  • 您将“响应式”一词与“信息性”混淆了。输出信息不会使程序响应更快,它会使程序更冗长并帮助用户知道它在做什么。如果有的话,输出会使它的响应性降低一点。
  • 哦,对不起。是的,你是对的。不知道我为什么写响应式。我已经更新了这个问题。谢谢。
  • 这个任务不适合 SO,你只需要将一些 gem 从 rails 替换为 sinatra,包括 activepack,并调试应用程序。

标签: jquery ruby-on-rails ruby ajax sinatra


【解决方案1】:

我对一个运行我的规范并在浏览器中显示当前构建状态的 sinatra 应用程序做了类似的事情。

总结了三件事:

  1. 一个可以存储当前状态的全局对象(在我的例子中是一个包含 Build 列表的 BuildQueue)
  2. 使用Thread.new 开始构建
  3. 使用IO.popen 的构建运行命令,因此我可以逐行处理(将其放入构建日志数组中)

然后,我的 javascript 间隔函数向应用程序发送构建 ID 的 ajax 请求,并返回日志数组(因此,不断增加直到构建结束)。

这是一个抽象的例子:

require 'sinatra'
require 'json'

Thread.abort_on_exception = true

Logs = []

post '/build' do
  Logs.clear
  Thread.new do
    my_cmd = IO.popen( "my_long_running_binary 2>&1" )
    Logs.push( line ) while ( line = my_cmd.gets )
    my_cmd.close
  end

  200
end

get '/build.json' do
  JSON.dump Logs
end

【讨论】:

    【解决方案2】:

    前段时间我遇到了类似的问题,我采取了一种“更聪明”的方式来解决它。我所做的是,我添加了一个 JavaScript sn-p,它会在 ruby​​ 程序在后台运行时继续在网页上加载新文本。 JavaScript 代码将在该过程完成时停止运行。这样,您的应用程序将变得“响应式”并为您节省大量时间。

    上述步骤的分步方法应该如下(据我所知):

    1. 在您的 ruby​​ 代码中添加一个标志,当您的处理完成时该标志应翻转为 true(取决于您的代码的具体内容)。

    2. 添加一点 javascript 代码。像这样的:

      $(document).ready(function() {
      
         $('#demo1').click(function() { 
      
        $.blockUI({ message: $('#loginForm') }); 
      
        setTimeout($.unblockUI, 2000); 
         });  
      });
      
      1. 为了显示更改文本的动画,我添加了来自以下repository的代码

    【讨论】:

    • 您能否分享一下您的 sn-p 或简要概述您是如何做到的?
    • @JatinGanhotra 不幸的是我现在没有代码。我在一家公司实习的时候做了这件事,不得不把它留在那里。但我肯定会给你整个概述
    【解决方案3】:

    您所说的是执行状态。有几种方法可以解决它,使用服务器发送事件 (SSE)、使用 websockets 或只是轮询更改。

    最简单的解决方案是轮询更改。有另一个 Ajax 方法,每隔一段时间向网站发送一个请求,服务器将返回响应与长时间运行进程的当前状态。

    在你的长期运行过程中你需要的是里程碑,你更新状态并且它可以被其他人访问,即某种数据库(Redis,Memcached,SQL-ish),或者通过线程但是这不能很好地扩展。

    【讨论】:

      猜你喜欢
      • 2011-12-09
      • 1970-01-01
      • 1970-01-01
      • 2011-05-15
      • 2017-12-09
      • 1970-01-01
      • 1970-01-01
      • 2011-08-07
      • 1970-01-01
      相关资源
      最近更新 更多