终于把Apache2从我的VPS上停掉了
Gentoo, Web, Wordpress February 21st, 2010
折腾了一个上午,终于把我的 VPS 上的 Apache 跑着的相关服务,都切换到 Nginx 上了:
1. Blog 用的是 WordPress,原先是用 mod_php 跑着的,现在则换成了 php-fpm
2. Wiki 用的是 Trac,原先是用的 mod_python,现在用 tracd 直接起来,然后 Nginx 转发
3. Git 前端用的是 Gitweb,因为懒得再启一个 spawn-fcgi 了,所以干脆换成 GitPHP,同样通过 php-fpm 的方式跑着
4. Zotero 的 WebDAV 存储,由于好久都不用,直接停了,有时间再看看有没有什么轻便的替代方案吧
PS1:关于 Gentoo 上的 php-fpm 配置,见 http://bugs.gentoo.org/show_bug.cgi?id=208155 及 http://bugs.gentoo.org/show_bug.cgi?id=301279
PS2:关于 Nginx 跑 WordPress 的 Permalink 设置,可以参考 http://blog.sjinks.pro/wordpress-plugins/nginx-compatibility/
果然还是把复杂问题简单化比较爽啊
Python September 16th, 2009
事情的起因是这样子的,小员在写一个测试工具,主要是管理 Xvfb 和 Selenium Server,启动多个 Server 来并行跑多个测试用例,出错的时候截图生成报告。
然后开发人员的测试代码是这么写的:
1 2 | def setUP(self): self.selenium = selenium(host, port, "*firefox", "http://xxx.yyy.zzz:1234/") |
这里的 host 和 port 在测试用例里是写死的,而在这个测试工具中,由于启动的 Selenium Server 的端口是随机绑定的,所以需要自动的把测试用例里的连接修改成对应的参数。
我俩讨论了下,决定用 decorator 来改掉 selenium 的构造函数,然后有了以下关键部分的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | def change_selenium_params(host, port, browser='', baseURL=''): def inner(func): def wrapper(*kargs, **kwargs): kargs = list(kargs) kargs[1:3] = host, port return func(*kargs, **kwargs) return wrapper return inner @stop_servers def run(self): """ Run testcases """ self.xvfb.start() self.selenium_server = serverctl.SeleniumServer(self.xvfb.display) self.selenium_server.start() for testcase_file in self.testcases_status['waiting']: selenium.selenium._init_ = change_selenium_params('localhost', self.selenium_server.port)(selenium.selenium.__init__) # Make testsuite and run it here ...... self.selenium_server.restart() self.selenium_server.stop() self.xvfb.stop() |
由于 Selenium 关闭 Firefox 有 Bug,所以不得不每跑一个 testsuite 就重启一次 Selenium Server,这时候发现 testsuite 用的还是第一次传过去的端口。结果看起来奇怪,这个问题还和其它混在一起了,而且这玩意比较难跟踪,调试器也不好用,于是乎,我们写了个简化版的原型来分析,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | class Selenium: def __init__(self, port): print 'Port:', port def change_port(port): def inner(func): def wrapper(*kargs, **kwargs): kargs = list(kargs) kargs[1] = port return func(*kargs, **kwargs) return wrapper return inner for i in xrange(3): Selenium.__init__ = change_port(i)(Selenium.__init__) a = Selenium(9) |
这时候的输出是:
1 2 3 | Port: 0 Port: 0 Port: 0 |
然后在 decorator 里加了条输出语句:
1 2 3 4 5 6 7 8 9 | def change_port(port): def inner(func): def wrapper(*kargs, **kwargs): kargs = list(kargs) print 'Change port:', port # Add a debug output. kargs[1] = port return func(*kargs, **kwargs) return wrapper return inner |
这时候的输出是:
1 2 3 4 5 6 7 8 9 | Change port: 0 Port: 0 Change port: 1 Change port: 0 Port: 0 Change port: 2 Change port: 1 Change port: 0 Port: 0 |
这下终于知道问题所在了,可怜的 A.__init__ 函数每次执行都多被套一层 decorator,到了最后就变成了:
1 | change_port(2)(change_port(1)(change_port(0)(A.__init__))) |
嗯,用个临时变量先把初始的 A.__init__ 保存起来就 OK 了,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | class A: def __init__(self, port): print 'Port:', port orig_func = A.__init__ def change_port(port): def inner(func): def wrapper(*kargs, **kwargs): kargs = list(kargs) print 'Change port:', port # Add a debug output. kargs[1] = port return func(*kargs, **kwargs) return wrapper return inner for i in xrange(3): A.__init__ = orig_func A.__init__ = change_port(i)(A.__init__) a = A(9) |
Tags: Python
有时候真的怀疑本应是明年的本命年提前过了,毕竟这一年下来,真的是没什么顺心的事情。被妹子发卡就不说了,毕竟感情的事不是努力就能成的,也只能无可奈何的等伤口慢慢恢复了…
之后过了段时间,由于一些个人原因,辞职宅宿舍了,结果又遇到搞笑的事情。投了家新加坡的创业公司,一开始觉得他们做的东西蛮有意思的,而且还可以异地办公,这样我就可以迁移杭州了。于是和他们作了个 Skype 的面试,说是接下来安排个小项目来试试看。嗯,过了好几天,没动静,发邮件催了下,说是很抱歉,最近比较忙,所以要我再等几天。在这之后就是漫长的等待,IM 上和他们讨论了几次服务器的性能问题,还帮他们弄优化方案的原型,每次聊完总是说让我等那个测试项目。最近更牛掰了,干脆 IM 和 Email 都不回复了… 我都无语了,哥们,你要是不招直说啊,每次都说再等等啥意思呢,要么像现在这样子干脆不回复也成啊。反正啊,是又被忽悠了,想想自个中途还拒了网易的 offer,真是无愧傻多这称号啊…
然后最近看到谷歌宣布 Android 谷歌拼音输入法发布,支持用户词典同步功能,觉得挺不错的。翻了下 Android 的代码仓库,有 PinyinIME 的源代码,于是开始动手移植到 Mac 上,想着如果我 Windows 下也用谷歌拼音的话,两边的词库能同步,挺方便的。结果把原型搞出来后,非常沮丧的发现:
1. 目前的 Android 仓库上的 PinyinIME 源代码里没有网络词库同步的实现…
2. 就算网络词库同步以后加进去了,但是… Android 版本的词库同步和 PC 版本的是独立的,没法共享…
3. Android 版本的词库格式和 PC 版本的不兼容,工程里生成的那 1M 大小的词库实在是太寒碜了,还没法拷 PC 版的来用…
目前的原型继续完善下去感觉也没有必要了,毕竟一开始就是奔着词库同步的优点才动手的,还是老老实实用付费的 QIM 吧…
顺手放个截图缅怀下这个夭折的原型…

也许最近唯一还值得欣慰的就是,笑来兄的《TOEFL核心词汇21天突破》还有坚持每天在背,虽然进度很慢就是了…