我有一个 Upstart 任务,它根据 Starting multiple upstart instances automatically 启动一个服务的多个实例和 Restarting Upstart instance processes .它正在工作并且它启动了所有实例但是在它成功启动它们之后它只是挂起。如果我 Ctrl-C 退出,然后使用 service status 或查看 ps 检查实例,它们都已成功启动,所以我不挂起时不知道它在做什么。
这是我的脚本:
description "all-my-workers"
start on runlevel [2345]
task
console log
env NUM_INSTANCES=1
env STARTING_PORT=42002
pre-start script
for i in `seq 1 $NUM_INSTANCES`;
do
start my-worker N=$i PORT=$(($STARTING_PORT + $i))
done
end script
当我执行 service start all-my-workers 时,我得到了这个:
vagrant@vagrant-service:/etc/init$ sudo service all-my-workers start
然后它就卡在那里,不再提示我。正如我所说,我可以 Ctrl-C 退出并查看正在运行的工作人员:
vagrant@vagrant-service:/etc/init$ sudo service all-my-workers status
all-my-workers start/running
vagrant@vagrant-service:/etc/init$ sudo service my-worker status N=1
my-worker (1) start/running, process 21938
在 ps 中:
worker 21938 0.0 0.1 4392 612 ? Ss 21:46 0:00 /bin/sh -e /proc/self/fd/9
worker 21941 0.2 7.3 174076 27616 ? Sl 21:46 0:00 python /var/lib/my-system/script/start_worker.py
我认为问题不在 my-worker.conf 中,但以防万一:
description "my-worker"
stop on stopping all-my-workers
setuid worker
setgid worker
respawn
instance $N
console log
env SCRIPT_PATH="/var/lib/my-system/script/"
script
export PROVIDER=vagrant
export REGION=all
export ENVIRONMENT=cert
. /var/lib/my-system/.virtualenvs/my-system/bin/activate
python $SCRIPT_PATH/start_worker.py
END
end script
非常感谢!
最佳答案
我假设 my-worker 是一个长期存在的进程,并且您希望有任何简单的方法来启动和拆除 my- 的多个并行实例 worker .
如果是这种情况,您可能不希望all-my-workers 成为任务。您需要以下内容:
description "all-my-workers"
start on runlevel [2345]
console log
env NUM_INSTANCES=1
env STARTING_PORT=42002
pre-start script
for i in `seq 1 $NUM_INSTANCES`;
do
start my-worker N=$i PORT=$(($STARTING_PORT + $i))
done
end script
pre-stop script
for i in `seq 1 $NUM_INSTANCES`;
do
stop my-worker N=$i PORT=$(($STARTING_PORT + $i)) || true
done
end script
然后你可以运行start all-my-workers来启动所有的my-worker实例,然后运行stop all-my-workers 来阻止他们。实际上,all-my-workers 成为管理启动和停止其子作业的父作业。
您引用了两个 SO 答案,展示了父作业管理子作业的想法。他们显示:
脚本节的任务pre-start节您的父作业是一个带有pre-start 节的任务,这就是您遇到这种奇怪行为的原因。
来自 this Ask Ubuntu answer其中引用了this deprecated documentation , 有两个非常重要的语句(已强调):
All job files must have either an exec or script stanza. This specifies what will be run for the job.
Additional shell code can be given to be run before or after the binary or script specified with exec or script. These are not expected to start the process, in fact, they can't. They are intended for preparing the environment and cleaning up afterwards.
总而言之,Upstart 会忽略(即不监视)由 pre-start 节生成的任何后台进程。相反,您必须使用exec 或script 生成Upstart 将监控的进程。
如果省略 exec/script 节会怎样? Upstart 将坐下来等待一个进程被产生。因此,您不妨编写一个 while-true 循环:
script
while true; do
true
done
end script
唯一的区别是 while-true 循环是活锁,而空节会导致死锁。
了解以上,the Upstart documentation for tasks最终引导我们了解正在发生的事情:
Without the 'task' keyword, the events that cause the job to start will be unblocked as soon as the job is started. This means the job has emitted a starting(7) event, run its pre-start, begun its script/exec, and post-start, and emitted its started(7) event.
With task, the events that lead to this job starting will be blocked until the job has completely transitioned back to stopped. This means that the job has run up to the previously mentioned started(7) event, and has also completed its post-stop, and emitted its stopped(7) event.
(如果您阅读关于 starting and stopping jobs 的文档,关于事件和状态的一些细节会更有意义)。
简单来说:
exec/script 节预计会无限期阻塞,因为它正在启动一个长期存在的进程。因此,Upstart 在完成 pre-start 节后停止阻塞。task,exec/script 节预计会阻塞一段“有限”时间,因为它正在启动一个短暂的过程。因此,Ubstart 会一直阻塞,直到exec/script 节完成之后。但是如果没有 exec/script 节会怎样? Upstart 坐在那里无限期地等待某个东西的发布,但这永远不会发生。
job 的情况下,这很好,因为 Upstart 在等待进程产生时不会阻塞,调用 stop 显然足以让它停止等待。任务 的情况下,Upstart 将永远坐着挂起——或者直到您打断它。但是,因为它还没有找到派生的进程,所以它在技术上仍在运行。这就是为什么您可以在中断后查询状态并查看 all-my-workers start/running 的原因。如果出于某种原因,你真的想让你的父工作变成一个任务,你实际上需要两个任务:一个启动my-worker实例和一个阻止他们。您还需要从 my-worker 中删除 stop on stopping all-my-workers 节。
启动所有我的 worker :
description "starts all-my-workers"
start on runlevel [2345]
task
console log
env NUM_INSTANCES=1
env STARTING_PORT=42002
script
for i in `seq 1 $NUM_INSTANCES`;
do
start my-worker N=$i PORT=$(($STARTING_PORT + $i))
done
end script
停止所有我的 worker :
description "stops all-my-workers"
start on runlevel [!2345]
task
console log
env NUM_INSTANCES=1
env STARTING_PORT=42002
script
for i in `seq 1 $NUM_INSTANCES`;
do
stop my-worker N=$i PORT=$(($STARTING_PORT + $i)) || true
done
end script
关于linux - Upstart 任务在成功完成后挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28119333/
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我写了一个非常简单的rake任务来尝试找到这个问题的根源。namespace:foodotaskbar::environmentdoputs'RUNNING'endend当在控制台中执行rakefoo:bar时,输出为:RUNNINGRUNNING当我执行任何rake任务时会发生这种情况。有没有人遇到过这样的事情?编辑上面的rake任务就是写在那个.rake文件中的所有内容。这是当前正在使用的Rakefile。requireFile.expand_path('../config/application',__FILE__)OurApp::Application.load_tasks这里
在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.
我以前没有使用过cron,所以我不能确定我这样做是对的。我想要自动化的任务似乎没有运行。我在终端中执行了这些步骤:sudogeminstall每当切换到应用程序目录无论何时。(这创建了文件schedule.rb)我将此代码添加到schedule.rb:every10.minutesdorunner"User.vote",environment=>"development"endevery:hourdorunner"Digest.rss",:environment=>"development"end我将此代码添加到deploy.rb:after"deploy:symlink","depl
如何在Rake任务中运行Capybara功能?例如:访问('http://google.com')谢谢! 最佳答案 在任务中尝试这样的事情:require'capybara'require'capybara/dsl'Capybara.current_driver=:seleniumBrowser=Class.new{includeCapybara::DSL}page=Browser.new.pagepage.visit("http://www.google.com")puts(page.html)
一边学习thisRailscast我从Rack中看到了以下源代码:defself.middleware@middleware||=beginm=Hash.new{|h,k|h[k]=[]}m["deployment"].concat[[Rack::ContentLength],[Rack::Chunked],logging_middleware]m["development"].concatm["deployment"]+[[Rack::ShowExceptions],[Rack::Lint]]mendend我的问题是关于第三行。什么是传递block{|h,k|h[k]=[]}到Has
我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n
根据thispostbyStephenHagemann,我正在尝试为我的一个rake任务编写Rspec测试.lib/tasks/retry.rake:namespace:retrydotask:message,[:message_id]=>[:environment]do|t,args|TextMessage.new.resend!(args[:message_id])endendspec/tasks/retry_spec.rb:require'rails_helper'require'rake'describe'retrynamespaceraketask'dodescribe're