blog mail me! feed

Archive for Tech

实现Github的代码仓库权限控制.

Github这个social coding的代码托管网站风骚得总有让人push, 攒蓝条的冲动.
以上是题外话.

最近回头去, 把以前断断续续没写完的Project gitar(web端的多用户仓库管理界面)继续拾起来开发,
也遇到了些问题: 比如, 如何实现github那样的, 对用户的公共仓库进行权限控制,
今天仔细翻了翻sshd和git的文档, 终于找到了一个解决方法.

[1] 修改sshd_config, 将PermitUserEnvironment设置为yes, 以保证能够在authorized_keys文件中, 对环境变量进行设置.

[2] 对于每个用户提交的RSA公钥, 在其

ssh-rsa AA….== foo@bar

的前面, 加上

environment=”GITAR_USER=username”

这样用户通过了公钥认证后, 当前的session的环境变量中, 即保存了用户的gitar用户名.

[3] 使用git hooks, 匹配环境变量 $GIT_DIR 路径中所包含的用户名信息, 和$GITAR_USER 中的当前用户名,
用户名不匹配时, 即通过产生不为0的exit code, 终止远端的push操作.

[4] 当然Github中还可以添加collaborators, 也可以对特定仓库添加public keys, 可以通过扩充用户session的环境变量来实现目的.
或者, 也可以使用shell脚本调用一个python脚本, 将 $GITAR_USER 的值与数据库中的collaborators进行比对.

一个wpmu的hack, 用nginx代替php处理静态文件.

wpmu使用php处理静态文件的模式一直让我很不舒服,
结果今天研究了N久如何绕开php来做静态文件的处理.

先选取了自己以为最简单的实现方法, 用squid做反向代理.
装上了squid 3.1, 发现网上的config教程都是2.6的, 完全不适用,
研究了manual后, 配好了反向代理,
接着, 尴尬的事情就发生了, 因为是本地做反向代理,
无疑通过nginx来进行proxy_pass的结果就是死循环…

nginx –[proxy_pass]–> squid –[http request]–> nginx –[proxy_pass]–> squid…

太糟糕了, 要解决这个问题只有通过实现两个virtual server, 并且重写host来实现反向代理.
庞大的工程. 遂放弃.

后来转向nginx的X-SendFile功能,
原理是捕捉到特定的X-Accel-Redirect头后,
通过实现一个内部的location, 来完成一个重定向.

不过事情没有这么简单, 现有栋力博客的重写规则是:
rewrite ^.*/files/(.*) /wp-content/blogs.php?file=$1;

而静态路径里也含有 /files/ , 所以会被同时重写, 最后返回一个500 Internal Error,
并且这个error是没法通过FireBug或者日志来trace的.
研究了下nginx的判断逻辑, 加了一条URL判断后终于搞定.

详细的步骤如下:
Read the rest of this entry »

服务器升级.

目前去年5月几经折腾买入的二手Hitachi服务器工作一切良好,
就是36G的硬盘有点小.
索性周二在淘宝上订了块二手Maxtor 174g 10000r SCSI硬盘, 310, 
周四早上去机房, 把硬盘插好, 顺利的自检通过.

本想跑个badblocks检查下坏道, 无奈忘了加-s 参数也忘了用& 让它在后台跑,
10分钟后putty就被润新脆弱的网速折磨挂了, 坏道检测也就中止了-___-.

接着把原来的FAT32分区全部删掉(哦, 数据删光了, 某b还念念不忘有没有点秘密的玩意儿)
整个盘重新做成了Linux LVM,
打算着格式化为reiserfs, 这样配合LVM可以在线的扩充逻辑卷容量,
嗯… 很悲惨的发现内核里没reiserfs -____-#

又转而试图作成ext4, 结果用mount -t ext4 也mount不上, 郁闷(有牛人解释下咩?).
最后还是做成ext3; 把htdocs全部迁移; nginx配置修改好,
就基本完成平滑迁移了.

话说等考完G了重做一次Debian, 把reiserfs扔内核里去.

新年的第二个程序.

第一个程序是一个实验性的词频的数据可视化的Flash.
改天弄完了发上来.

现在要说的是正在忙活的项目, 酵母的蛋白质编码基因预测.
今天下午断断续续的忙活得差不多了, 基本搞定了整个程序,
尽管数次觉得程序还有很多可以改进的地方, 让其更简洁, 更可读.

速度还没优化, 不过其实我是想看看Cross-Validation的结果如何,
有点失望, 最后尝试了各种参数组合(氨基酸的参数还没做, 因为构建一个CODON –> AA的表都得费些功夫),
准确率只能跑到大概97%左右, 离想象的99%有着巨大的鸿沟.
不甘心又用Z-Curve跑了一次, 33参数的Z-Curve就能跑到99.1%左右的准确率了,
看来的确是参数的问题.

双密码子是在是太慢了, 且不说这4000多个参数多么庞大,
估计用libsvm来跑一次 6 Fold Cross-Validation就足够等以小时算的时间单位了,
未来如果要用到Markov Model可能还得把libsvm的代码直接放到程序里来,
外部调用读数据文件的时间和效率都够呛.

其实也没做多少工作, 无非都是体力活, 科研的实质皮毛都没摸到, 倒感觉有点像打杂性质.
所以还好了, 不算太失落. 也不应该失落的.
只是实在是门外汉, 一点门路都摸不到, 
晚些时候再稍微想想看看, 先优化效率,
再试试有没有其他方法.

上次看到的一篇讲短序列预测的文章很好,
里面提到了傅立叶变换用作一个参数, 也准备试试.
看来还得找找FFT的相关资料来看看了,
现在一说起FFT, 脑袋里除了那张似有似无的蝶形图,
什么都没了.

真核生物果然高级些…

嗯, 假期的项目是研究酵母这种低等真核生物的蛋白质编码基因预测.
上次入门做的是霍乱弧菌.

话说霍乱弧菌全身上下一个长了大小两个染色体, 而酵母竟然有16个染色体,
加上线粒体染色体, 一共17个…

还没有看具体的sequence和annotation文件,
得开始着手了.

有限状态的有序世界.

我时常觉得<数字逻辑>这门课最大的收获不是那些该死的门, 以及一堆74XX,
而是以一种状态和时序的眼光去分解事件, 乃至世界[狭义的]的有限状态和演进关系. 

今天看到篇文章, 用正则表达式判断一个二进制数是否能被3整除, 很有启发.
当然可以把这样一个有限状态机, 看做一种时序的逻辑(事实上本来也是一种时序逻辑),
状态随着输入演进, 并且仅由状态决定输出[Moore机].

为了实现逻辑上的并发, 事实上许多电路的实现都是”暴力”的,
唯有在有限状态下的所有可能均进行了逻辑上的连接处理, 才能实现不考虑因为多级电路产生时延情况下, “瞬时的并行处理”.
这篇文章里的通过有限状态机实现的正则表达式也是如此,
毕竟正则表达式不包含一个可以分支选择的结构, back reference也只是一个简单的前向匹配而已.
因此我们通过状态机的有限状态转换图, 列出了可能的所有会最终到达状态0, 并且输出1的匹配序列.
(当然这里的”所有”, 是指可以通过wildcard和repetation完成简化描述的序列)
最后用正则表达式完成匹配.(当然这里说到的序列枚举的”暴力”操作, 已经和组合逻辑的单纯”暴力组合”有了实质性区别了)

二进制序列模型保证了要成为一个符合条件的有效数字(0自然不考虑了),
第一位必然是1, (否则就必然是0了).
也就是状态机的初始状态非随机, 使得我们在构造最后序列的时候有了很多约束条件可用. 

所以, 在这个一定生产环境下, 约束必然有界的有限状态世界中,
还可以有哪些更有趣的实例呢?

有关豆瓣批处理.

前两天发现自己的豆瓣累积了一堆”正在听”的音乐, 其实老早已经听过了,
继而无数次的点击把这些专辑全部改了状态.

索性萌生出想法做个批处理来折腾这类非人类工作,
鉴于做一个客户端实施不合我心意(去折腾构造C#的类, 总是让我觉得不自在, 囧),
还是打算做一个web端的实现, 不过豆瓣的API的限制(40 reqs/min)使得我还得考虑高并发下的队列问题, 缓存问题,
在公交车上想了一路也没个好方法.

回家了打开豆瓣看了看js, 因为我记得豆瓣的”收藏”页面是通过ajax装入的,
在douban的js里有这么个函数, Douban.init_collect_btn,
请求了一个返回json的的web service,  (URL: /j/subject/[SID]/interest).
这样就很愉悦了, 用一个php/python请求这个web service, 就可以得到对应需要的信息(当然其实大抵我只需要tag信息, 其他的各种按钮表单都直接封装为了HTML, 没有多大必要去处理),
然后在前台构造一个像模像样又足够简单的表单即可完工.

当然整个过程中还需要考虑SESSION_ID的维持与提交,
以及模拟登录表单的提交, 读取用户数据(这里倒是考虑偷懒用API来做).

P.S.

  1. 现在很多网站的架构上都实现了很好的web service, 是简化开发的好方法.
  2. 实际上, 如果连读取各类列表的API的并发也不想考虑的话, 也不嫌额外的麻烦, 直接处理HTML也行(自己尝试了半天, 想在/j/这个web service下把用户的各种兴趣列表的url找到, 没试出来,囧)

最轻量的模板实现, Here Document

今天去Google了下Smarty, 发现对其批评甚多.
比如认为其太不轻量, 有100k+的核心库, 而其编译生成的缓存又过于臃肿.
很多人拿Smarty和PHPLIB对比, 后者是一个只有一个类的10+k的模板引擎, 不过貌似在PHP4时代就停止开发了.

后来看到人说phpwind是用的heredoc实现的模板,
就去搜了下heredoc, 其实在php manual里也有:

print <<<END
This uses the "here document" syntax to output
multiple lines with $variable interpolation. Note
that the here document terminator must appear on a
line with just a semicolon no extra whitespace!
END;

这里的END是结束符, 当然你可以用其他的来代替, 比如phpwind使用的是EOT.
以上代码就实现了代码与变量的准分离, 而且没有用到破坏布局和显示效果的引号.

无疑这样的方式来实现”模板”比使用Smarty更轻量,
也比在HTML里嵌入大量的<? echo $variable ?>更直观简洁.

更多的一些细节可以看这里: http://www.tsingfeng.com/show-667-1.html

瓢泼序章.

最近的几次, 每每我一回华阳,
总会天色骤变, 应验了数次, 屡试不爽.

今天在摇晃的504上摇晃到了目的地,
竟然就在车拐弯进站的时候, 开始飘雨了.

(于是这让我哀伤的想起每次出门, 大抵到达一处, 便见得一出天色渐渐阴沉下来, 最后不免瓢泼作雨)

当然这天气实在是闷热的太难受, 哪怕是倾盆如柱, 加上狂风几个时辰我也不会说半个不字.

车上还在想 类Rapidshare应用的问题, 回到家顺便搜了搜nginx防盗链的东西,
就找到了这个好东西: NginxHttpAccessKeyModule, 对于某文件, 必须根据请求的用户IP生成特定的signature才能正常下载.

files 目录下有一 foo.zip, 则必须请求 http://domain/files/foo.zip?key=09093abeac094 才能正常下载文件, 而key值由salt和用户的remote_addr的hash值决定(SHA1或MD5).

P.S. 据说这玩意儿现在也可以防迅雷的盗链了,
由此看来, 用nginx来做 类rapidshare 的文件服务器也不是不可以的.

Project Babel还有这么雷的设计…

不经意看了看apache目录下的.htaccess文件, 居然有16k, 大概接近300条RewriteRule,
感觉是完全没有利用好正则.

nexus的重写规则被写在了最后, 可怜的nexus, 为了处理URL重写, 已经执行了300次正则匹配了,
其实很多的规则都可以合并和简化, 感觉现在这样, 靠缓存优化出来的性能, 被重写就吞噬了不少.

P.S.  Babel也是用echo控制的所有html的输出而不是用模板引擎或者类似ipb那样的模板.
想了下, 不用Smarty, 用稍微优化下的分离view, 用echo来控制变量输出还是不错.

Next entries »