Tuesday, September 12, 2006

noticpan.org update 060912

毛坯房在 perlchina 广告了一下,应者寥寥。也是,过分粗糙了,各方各面都是。同时,如期开始了装修工程。到现在为止,第一期简装已经完毕,还是很丑?多多包涵,多多包涵。期间自己在使用中发现了几个 BUG,都一一予以修正。还有部分功能缺失,如注销、忘记/更改密码等,也会于近日慢慢补上。
出乎意料的是,我自己订阅了 10+ 个模块,竟然两个多星期来没有受到一个更新通知,搞笑了,受打击了。但是不能气馁,要相信这个服务肯定是有用的,嗯嗯。
天色不早了,该休息了,各位晚安。

Wednesday, September 06, 2006

noticpan.org online

从想法到实施,花了三个周末,昨晚 noticpan.org 上线了。
最基础的邮件提醒功能已经可用,其他一切都处于史前文明水平,留待日后慢慢开化。
不容易啊,在虚拟主机上搭建 Catalyst 的应用程序。Catalyst 本身已经做得很好了,还有详细的教程说明如何在虚拟主机搭建站点。
革命尚未成功,同志还需努力!

Wednesday, August 30, 2006

DreamHost promo codes

正在筹划个站点,于是满地图找空间,最后决定买 Dreamhost 的虚拟主机。
最初是在 Catalyst 的 wiki 上看到它的广告的,那么想当然地以为它是支持 Catalyst 的,买了之后发现不是这样的,这是后话。
L1: Crazy Domain Insane (20GB disk, 1TB bw, $9.95/month)

咋一看,价格和内容都还不错;再一瞅,跟咱电信一样,包年免初装费,按月付费的话要额外追加一项
$49.95 set up fee

那一年就一年吧,$119.4,也还好吧。那么,最后掏钱之前 Google 一下,这 Dreamhost 到底怎么样,好不好,恕我孤陋寡闻,一搜就搜出了 promo codes 这个东西,大把大把的。使用促销代码注册,最多可以获得$97的优惠,然后$22.4就出手了。
回到上面的话题,原来 Catalyst 需要自己安装的,好就好在 Dreamhost 提供了 ssh/telnet 权限,可以在自己的目录下自行安装。当前正在摸索中……
既然 promo codes 利人又利己,那么我也来弄个玩玩
Code: NOTICPAN
PlanCostThis Code's Discount
L1 Monthly$59.90$50.00
L1 Yearly$119.40$97.00
L1 Two years$190.80$97.00
L2 Monthly$69.90$60.00
L2 Yearly$239.40$97.00
L2 Two years$382.80$97.00
L3 Monthly$89.90$80.00
L3 Yearly$479.40$97.00
L3 Two years$766.80$97.00
L4 Monthly$129.90$97.00
L4 Yearly$959.40$97.00
L4 Two years$1534.80$97.00
While L3 is at L2's price, L2's discount will be used for L3.

Thursday, August 24, 2006

Pound前端下Catalyst的https重定向问题

如果你使用Pound作为前端,那么不可避免地,必须使用Pound作为你的https wrapper,因为Pound和后端只用http通讯。然后说那个Catalyst的重定向,常规情况下,你可以使用这样的代码来做重定向
$c->res->redirect('/foo');

对于大多数现代浏览器,这个响应返回的头部是可以被正常解析的,所以如果你是从一个https入口进的话,这个重定向会正确地被浏览器解析成
https://example.com/foo

但是,根据RFC某某某号的描述,重定向的目标路径应该是全路径,这样的话就有问题了,首先,你必须借助uri_for这个函数来产生你的全路径
$c->res->redirect( $c->uri_for('/foo') )

然后,问题就来了,由于Catalyst只接受到了http的请求,它并不知道外面的世界是上海还是广州,于是,得到了
http://example.com/foo

诚然,也许你要的只是某个区域永远安全,那么简单的解决方法就是这样
my $uri = 'https://' . $c->req->header('host') . '/foo';
$c->res->redirect( $uri );

显然,我们要得更多,又要马儿好,又要马儿不吃草。所以呢,在很多站点的入口都能看到一个醒目的“安全登录”的标签。让你自己选,要安全就给你安全,不要?呵呵,我乐得省下这些开销。这样的话,情况就要复杂一些了,首先,为了让Catalyst知道你的来路,Pound必须履行告知的义务,比如这样

ListenHTTPS
AddHeader "secure: 1"
End

接着,就可以根据这个头部来分情况选择重定向的协议(schema)了,我比较倾向于自己写个插件
package Catalyst::Plugin::Secure;

use strict;
use warnings;

sub uri_for {
my ( $c, $path, @args ) = @_;

my $uri = $c->NEXT::uri_for($path, @args);
if ( $c->req->header('secure') ) {
my $str = $uri->as_string;
$str =~ s/^http/https/;
$uri = new URI( $str )->canonical;
}

return $uri;
}

1;

好,圆满了,多谢观赏!

Wednesday, August 16, 2006

正则表达式的写法和效率一例

#!/usr/bin/perl
use strict;
use warnings;
use Benchmark qw(:all);

my $b = cmpthese( -1,
{
pa => qq("It's a fine day today." =~ /a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z/g),
pb => qq("It's a fine day today." =~ /[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]/g ),
pc => qq("It's a fine day today." =~ /[a-zA-Z]/g ),
}
);

上面的这个例子我一直跑不出个相对稳定的结果,只能随便拿个结果来说明一下:
        Rate   pa   pb   pc
pa 848885/s -- -61% -65%
pb 2204237/s 160% -- -9%
pc 2427045/s 186% 10% --

可以看到,从“或(|)”模式到“类([])”模式,正则匹配的效率可以得到大幅度的提高,如果在“类”中能利用“范围(-)”符的话,还可以有小幅度提升。粗糙地结论就是,正则愈短,效率愈高。

因而在处理特定字符集的情况下,可以将其浓缩成一个精简的字符类描述的话,在执行效率上应该是很有帮助的。

Monday, August 14, 2006

MySQL可靠吗?

由于工作的原因,一直用着MySQL,一来是免费,二来简单易用。
但是随着应用的扩展,对于功能和稳定性的要求也越来越高。最近遇到了一件事情,让我觉得很是不爽,MySQL究竟可不可靠?

事情是这样的,安装完MySQL之后,在简单配置了my.cnf和启动测试之后,就清掉了binlog打算投入使用了。由于经验不足,没有删除ib_logfileX,又因为在第一次启动后修改了配置文件,已创建的ib_logfileX的文件大小和配置文件中的innodb_log_file_size不一致,导致了接下来的问题。
启动MySQL,OK。导入预先准备好的SQL脚本,OK。然后,发现了原来显式声明了Engine=InnoDB的表全部创建成了MyISAM模式。
SHOW ENGINES;后看到InnoDB的状态为DISABLE,很是莫名……最后在hostname.err里面看到,因为innodb_log_file_size的问题,导致了:
1)InnoDB被自动禁用了
2)创建InnoDB模式的表的时候,自动转成了MyISAM

我觉得不满的是,InnoDB被禁用只是在日志里这么一笔带过,终端上没有任何警告信息。据说*nix程序的普识原则是没有输出就是没有错误,难道MySQL认为这只是个小问题,并不会影响用户使用?!之后的自动转换模式就是个衍生问题了,虽然有WARNING,不过在批处理模式下显然是没有任何帮助的了。

问题虽然很好解决,删除innodb-log,重启MySQL,ALTER TABLE,就可以了。但是如果问题发现的晚,或者系统不能轻易下线,那损失就不好估算了。

Saturday, June 24, 2006

Config::General

前面在Catalyst的ML中就配置文件采用哪个模块处理讨论得不亦乐乎,感觉很多人对YMAL都颇有微辞,比如不能使用Tab之类的,最后达成的比较一致的意见是使用Config::General。第一次听说这模块。
正好给朋友写了个脚本,尝试了一下。格式定义和Apache的配置文件格式很相似,就是同一层次的Hash引用和Array引用在配置文件中看起来是不同层的,稍稍有些不爽。例:
<hash>
 foo = bar
</hash>
array = 1
array = 2

好处就是通俗易懂,适用性比较广,毕竟更多人对Apache的配置文件格式比较熟悉。不过如果只是我个人使用,还是会选择YAML的,简洁明了,我喜欢。
---
hash:
 foo: bar
array:
 - 1
 - 2

Sunday, May 07, 2006

Catalyst项目组裂变

核心开发者sri宣布离开Catalyst项目组,另起炉灶Mojo。在我印象里,sri是最活跃的核心之一,感觉上想法也比较多。不知道这次人事变动会给Catalyst带来怎样的变化,拭目以待。

Thursday, April 20, 2006

DBIx::Class和DBI

今天在更新安装DBIx::Class 0.06001的时候,make test在测试关于cache的地方失败了。
究其原因,是因为测试cache是依赖于DBI的Trace Output的。而DBI 1.40在TraceLevel 1下,输出的内容有些问题,并且在DBI 1.43中得到了修正:
- Changes in DBI 1.43 (svn rev 377), 2nd July 2004
* Changed TraceLevel 1 to not show recursive/nested calls.

奇怪的是,在比较DBI 1.40的TraceLevel 1和TraceLevel 2的输出文件后,发现在TraceLevel 1下,输出的是recursive/nested calls的最后一句,不过这一点并没有在Changes中被提到。但是在逐版本安装测试1.42和1.43后,我确认这个问题是在1.43中修正了的。
已经把问题提交到了Dbix-class ML了,估计应该会在下一版本修正。

Saturday, April 01, 2006

如何正确设置svn仓库权限

在多用户环境下,如果你使用的是Berkeley DB作为后端,那么你多半遇到过这样的错误:
Berkeley DB error while opening environment for filesystem ...
DB_RUNRECOVERY: Fatal error, run database recovery

为了解决这个问题还是费了我不少功夫,所以这里小小地归纳一下。
首先每一个用户都需要有BDB文件的读写权限,所以通常情况下我们会创建一个用户组G,然后把所有用户都加入到G中,并且会把整个仓库的组设为G。但是,因为用户在操作BDB的时候会创建新文件,而这时使用的umask一般是022,即组用户没有写权限。此后,当其他用户试图操作该文件的时候就会发生上面的错误。
在svn的How-to文档中建议尽量避免多用户访问仓库,但是如果使用的是file:///或者svn+ssh://的话就完全没办法绕开了。于是《Version Control with Subversion》一书的第6章第5节中另外提供了一个解决方案:
$ cat /usr/local/bin/svn

#!/bin/sh

umask 002
/usr/local/subversion/bin/svn "$@"

即手动包装一下svn,在执行命令之前将umask改为002,问题就这样解决了。
svn作为新一代的版本控制系统,对于这样一个显然客观存在的问题竟然没有一个较好的解决方案,实在是令我吃惊不小。