![](/img/trans.png)
[英]How do I run a ruby script, that I put in my /lib/tasks/ directory in my Rails app, once?
[英]How do I make a Ruby script run once a second?
我有一个需要每秒运行一次的Ruby脚本。 我使用Ruby脚本来跟踪目录中文件的修改,并希望脚本在“实时”时间内跟踪更新。
基本上,我希望我的脚本能够像在Unix shell上运行“top”一样运行,其中屏幕每隔一秒左右更新一次。 在Ruby中是否存在与Ruby中的setInterval
相同的东西?
有几种方法可以做到这一点。
快速和肮脏的版本:
贝壳(kornish):
while :; do my_ruby_script.rb sleep 1 done
(1)看:
shell$ watch -n 1 my_ruby_script.rb
这将每秒运行您的脚本并保持终端中显示的最新运行的输出。
在红宝石:
while true do_my_stuff sleep 1 end
这些都遭受同样的问题:如果实际的脚本/函数需要时间来运行,它会使循环运行少于每秒。
这是一个ruby函数,只要函数不超过一秒钟,就会确保函数(几乎)每秒都被调用一次:
def secondly_loop
last = Time.now
while true
yield
now = Time.now
_next = [last + 1,now].max
sleep (_next-now)
last = _next
end
end
像这样使用它:
secondly_loop { my_function }
正如另一个答案所述,rb-inotify非常适合这类事情。 如果您不想使用它,那么一个简单的方法是使用线程:
a = Thread.new { loop { some_method; Thread.stop } }
b = Thread.new { loop { sleep 1; break unless a.alive?; a.run } }
要停止查询,使用a.kill
或者确保some_method杀死自己的线程与Thread.kill
当某些条件得到满足。
使用这样的两个线程可确保some_method至少每秒运行一次,无论操作的长度如何,无需任何时间检查自己(当然,在线程调度的粒度内)。
您可能需要考虑使用rb-inotify之类的东西来获取文件更改的通知。 这样你就可以避免“睡觉”并保持“活”的感觉。
Guard Gem文档的“高效文件系统处理”部分提供了一些有用的信息: https : //github.com/guard/guard#efficient-filesystem-handling
或者您可以使用Concurrent Ruby gem中的TimerTask
timer_task = Concurrent::TimerTask.new(execution_interval: 1) do |task|
task.execution_interval.times{ print 'Boom! ' }
print "\n"
task.execution_interval += 1
if task.execution_interval > 5
puts 'Stopping...'
task.shutdown
end
end
timer_task.execute
从同一链接中提取的代码
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.