g:subtech:id:hirose31:20090613:1244914640 の続き。
コードスケッチのときとか、ひとつのファイルにmain部とpackage宣言とが混在してるときに、ファイルの下の方のpackage宣言をひろってrename-bufferしちゃうので、最初のn行までにpackage宣言があるときのみその名でrename-bufferするようにしてみた。
(defun plcmp-get-current-package-name-first (&optional limitline) "nil or string" (let ((re (rx-to-string `(and bol (* space) "package" (* space) (group (regexp ,plcmp-perl-package-re)) (* not-newline) ";"))) (bound (if (not limitline) nil (line-end-position limitline))) ) (save-excursion (goto-char (point-min)) (when (re-search-forward re bound t) (match-string-no-properties 1))))) (defun perl-rename-buffer () (interactive) (let ((package-name (plcmp-get-current-package-name-first 16))) (when package-name (rename-buffer package-name t))))
多ノードにすばやくping☆pongする必要があったのでAnyEvent::FastPingを使ってみたんですが、内部的にどういう処理をしてるのか気になってメモったので残しておきたいと思います。
追記。
「epoll(7)やselect(2)で監視している」のepoll(7)だとかselect(2)だとかは AnyEvent が隠蔽してくれるので、epoll(7)だとかselect(2)だとかのAPIの違いは気にする必要がないです。
こんな感じ:
our $THR_RES_W = AnyEvent->io (fh => $THR_RES_FH, poll => 'r', cb => sub { my $sv = _read_res or return; $sv->(); });
に、AnyEventのI/O監視のAPIを使うだけで OK です。
自分の環境 (Linux) では、use AnyEvent だけだと select(2) が使われて、
use AnyEvent; use EV;
するとepoll(7)が使われました。
(港区在住 非同期野郎Pチーム 31)
Emacsでファイルを開くとそのバッファ名はファイル名になります。
ですので、"なんとか/Server.pm" なファイルをいくつか開いていると、anythingなどでのバッファ選択では "Server.pm" がいっぱい出てきてどれがどれだかわかりません。
バッファ名をpackage名にすれば区別がつくようになるんですが、いちいち手でrename-bufferするのはめんどうです。
で、なんかいい方法ないですかねー?ときいたら id:IMAKADO がさくっとファイルを開いたらバッファ名をpackage名にしてくれるのを作ってくれました。
これが使用後。
ハラショー!!
g:subtech:id:hirose31:20090624:1245829941 に続きます……
# zakkuri httpd.conf
LoadModule perl_module modules/mod_perl.so
ErrorLog "/var/log/httpd/default/default.err"
<VirtualHost *>
ServerName curry.example.com
ErrorLog "/var/log/httpd/example.com/curry.err"
PerlOptions +SetupEnv +Parent
<Location />
SetHandler modperl
PerlResponseHandler OrenoHandler
</Location>
</VirtualHost>
な構成で、OrenoHandler 内で
print "OrenoTest: STDOUT\n"; print STDERR "OrenoTest: STDERR\n"; warn "OrenoTest: warn"; my $v1 = "2:" + 3; eval q[my $v2 = "3:" + 4;]; (undef) . "xxx"; my %h1 = qw(foo bar baz); die "OrenoTest: die";
とすると、VirtualHostのErrorLogのcurry.errじゃなくて、server contextのErrorLogのdeault.errに全部出ちゃう。
VirtualHostが複数あると、ログが混ざってどのVirtualHostのか判別しづらくなるのでちゃんとVirtualHostのErrorLogに吐かせてあげたい。
http://perl.apache.org/docs/2.0/api/Apache2/Log.html#Virtual_Hosts
に書いてあるように、httpd.confで
- PerlOptions +SetupEnv +Parent + PerlOptions +SetupEnv +Parent +GlobalRequest
して、OrenoHandler で
use Apache2::Log ();
$SIG{__WARN__} = \&Apache2::ServerRec::warn;
してあげると、curry.errにはこのように吐かれるようになる。
[warn] OrenoTest: warn at ... [warn] Argument "3:" isn't numeric in addition (+) at (eval 8) line 1.\n [warn] Use of uninitialized value in concatenation (.) or string at ... [warn] Odd number of elements in hash assignment at ...
一方で、default.errにはこのように吐かれる。
Argument "2:" isn't numeric in addition (+) at ... Useless use of concatenation (.) or string in void context at ... OrenoTest: STDERR
つまり、
はVirtualHostのErrorLogに出るようになったけど、
は依然としてserver contextのErrorLogに出てしまう。
まぁこれでだいたいいいかなぁとは思うんですが、2点、残糞感がある感じす。
しゅ〜しゅ〜
STDERR と Apache2::ServerRec::warn を tie して、print STDERR を Apache2::ServerRec::warn にしちゃう、というテクを同僚に教えてもらいました。
use Apache2::Log (); $SIG{__WARN__} = \&Apache2::ServerRec::warn; { package Oreno::_tie_stderr; sub TIEHANDLE { bless {}, shift } sub PRINT { shift; Apache2::ServerRec::warn(@_) } tie *STDERR, __PACKAGE__; }
これで print STDERR も VirtualHosts 毎の ErrorLog に出力されるようになったので、残すは
のみです。
Apache2::Status では、条件が揃えば package 毎に喰ってるメモリ量を知ることができます。
StatusTerseSizeMainSummary
With this option On and the B::TerseSize module installed, a "Memory Usage" will be added to the Apache2::Status main menu. This option is disabled by default, as it can be rather cpu intensive to summarize memory usage for the entire server. It is strongly suggested that this option only be used with a development server running in -X mode, as the results will be cached.
mod_perl: Apache2::Status - Embedded interpreter status information
非mod_perl環境、普通のスクリプトとか、Perlで書いたdaemonでも使えるといいなと思ったので、ソースみてコピペってみました。
use B::TerseSize; use Devel::Symdump; my $stab = Devel::Symdump->rnew("main"); my %size; for my $package ("main", $stab->packages) { my($subs, $opcount, $opsize) = B::TerseSize::package_size($package); $size{$package} = $opsize; } for my $package (sort {$size{$b}<=>$size{$a}} keys %size) { printf "%-24s %8d [KB]\n", $package, $size{$package}/1024; }
ENDブロックでくるんでスクリプトが終了するときにサマリを出力するようにしたり、シグナルハンドラで出力するようにするといいんじゃないかと思います。