我在 php 中有一个 cronjob,它计算一些业务规则(例如:净转速、总转速、估计转速等......使用标准偏差和其他数学算法)
这个 cronjob 使用 exec 调用多个 cron 调用 3 个 php 脚本
对于每个调用,我都会在后台启动一个进程并告诉系统作业 x 已启动。例如:
这是我的逻辑
start
main cron start - message
cron sub 1 start - message
run cron sub 1
cron sub 1 end - message
wait until cron sub 1 stop
process stuff
cron sub 2 start - message
run background cron sub 2 // this will automaticaly send a message when this jobs end
cron sub 3 start - message
run background cron sub 3 // this will automaticaly send a message when this jobs end
main cron end - message
end
我需要解决的是这个
如果有人手动运行作业并取消它 (ctrl+c) 或 cron 中发生了一些不好的事情( fatal error 或无法连接到数据库) 或其他任何东西(比如内存不足)
我想停止 cronjob 并告诉它发生了什么以及它停止的时间,这样我就可以从原来的地方开始。
这可能吗?谢谢
最佳答案
这是您必须尝试/调试的简单代码:
<?php
ignore_user_abort(false);
function shutdown() {
echo "shutdown function\n";
}
register_shutdown_function('shutdown');
class shutdown {
function __construct() {
echo "shutdown::construct\n";
}
function __destruct() {
echo "shutdown::destruct\n";
}
}
$s = new shutdown();
declare(ticks = 1);
function sig_handler($signo) {
switch ($signo) {
case SIGTERM:
echo "SIG: handle shutdown tasks\n";
break;
case SIGHUP:
echo "SIG: handle restart tasks\n";
break;
case SIGUSR1:
echo "SIG: Caught SIGUSR1\n";
break;
case SIGINT:
echo "SIG: Caught CTRL+C\n";
break;
default:
echo "SIG: handle all other signals\n";
break;
}
return;
}
echo "Installing signal handler...\n";
pcntl_signal(SIGTERM, "sig_handler");
pcntl_signal(SIGHUP, "sig_handler");
pcntl_signal(SIGUSR1, "sig_handler");
pcntl_signal(SIGINT, "sig_handler");
echo "Generating signal SIGTERM to self...\n";
# killing the script using bad memory allocation
/*
ini_set('memory_limit', '1K');
$data = '';
for($i = 0; $i < 1000; $i++) {
$data .= str_repeat($i . time(), time());
}
*/
# simulating CTRL+C
// for($i = 0; $i < 100000000; $i++) { } // don't forget to press CTRL+C
echo "Done\n";
如果 cronjob 正常运行你会得到:
shutdown::construct
Installing signal handler...
Generating signal SIGTERM to self...
Done
shutdown function
shutdown::destruct
如果遇到 fatal error :
shutdown::construct
Installing signal handler...
Generating signal SIGTERM to self...
PHP Fatal error: Possible integer overflow in memory allocation (11 * 1321404273 + 1) in /var/www/domain.com/php.php on line 51
shutdown function
如果你终止进程:
kill <processid>
shutdown::construct
Installing signal handler...
Generating signal SIGTERM to self...
SIG: handle shutdown tasks
Done
shutdown function
shutdown::destruct
您可以使用 posix_kill(posix_getpid(), <signal you like>);在每种情况下也是如此。
了解更多:
http://php.net/manual/en/function.pcntl-signal.php
http://en.wikipedia.org/wiki/Signal_%28computing%29
http://users.actcom.co.il/~choo/lupg/tutorials/signals/signals-programming.html
关于php 定时任务中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8136983/
我试图在一个项目中使用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
在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl
我写了一个非常简单的rake任务来尝试找到这个问题的根源。namespace:foodotaskbar::environmentdoputs'RUNNING'endend当在控制台中执行rakefoo:bar时,输出为:RUNNINGRUNNING当我执行任何rake任务时会发生这种情况。有没有人遇到过这样的事情?编辑上面的rake任务就是写在那个.rake文件中的所有内容。这是当前正在使用的Rakefile。requireFile.expand_path('../config/application',__FILE__)OurApp::Application.load_tasks这里
require'mechanize'agent=Mechanize.newlogin=agent.get('http://www.schoolnet.ch/DE/HomeDE.htm')agent.clicklogin.link_withtext:/Login/然后我得到Mechanize::UnsupportedSchemeError。 最佳答案 Mechanize不支持javascript但您可以将搜索字段添加到表单并为其分配搜索词并使用mechanize提交表单form=page.forms.firstform.add_fie
在几个项目中,我希望有一个类似rakeserver的rake任务,它将通过任何需要的方式开始为该应用程序提供服务。这是一个示例:task:serverdo%x{bundleexecrackup-p1234}end这行得通,但是当我准备停止它时,按Ctrl+c并没有正常关闭;它中断了Rake任务本身,它说rakeaborted!并给出堆栈跟踪。在某些情况下,我必须执行Ctrl+c两次。我可能可以用Signal.trap写一些东西来更优雅地中断它。有没有更简单的方法? 最佳答案 trap('SIGINT'){puts"Yourmessa
我有可变数量的表格和可变数量的行,我想让它们一个接一个地显示,但如果表格不适合当前页面,请将其放在下一页,然后继续。我已将表格放入事务中,以便我可以回滚然后打印它(如果高度适合当前页面),但我如何获得表格高度?我现在有这段代码pdf.transactiondopdf.table@data,:font_size=>12,:border_style=>:grid,:horizontal_padding=>10,:vertical_padding=>3,:border_width=>2,:position=>:left,:row_colors=>["FFFFFF","DDDDDD"]pdf.
我以前没有使用过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)
我正在根据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