dbus-python, in case you don't know

上周用dbus-python写exaile插件,实现mpris2.0,非常痛苦,因为几乎没有完整的文档,只有一个tutorials帮助你入门。总结一下我这次quick and dirty的开发所掌握的资料,当然,因为没有太多时间,所以也没有对dbus做更深入的了解,仅仅是in case you don’t know。

DBus Interface Properties

对mpris 2.0中定义的properties用dbus-python应该如何实现呢,似乎没有@dbus.service.properties这种decorator啊。这里的文档对Properties进行了简单的说明,对于python程序,只能这样实现了:

    @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='ss', out_signature='v')
    def Get(self, interface, prop):
        ...
    @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='ssv')
    def Set(self, interface, prop, value):
        ...
    @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature='s', out_signature='a{sv}')
    def GetAll(self, interface):
        ...

程序里通过prop判断property名字,返回结果。没办法,就是这样。

指定返回数据的dbus类型

对于dbus接口返回的variant类型,dbus-python会guess_signature。可是这部分的功能有的时候并不如我们想象,比如返回一个dict类型,其中的value有字符串有list有int,而out_signature是v。这种情况在Property Get的时候非常常见,如果不能手动指定类型,guess_signature得到的结果,value是统一类型,即,int会报错,如果没有int类型,会将所有字符串转成list(dbus的array)

这种情况需要手动指定返回的类型,用dbus.types模块下的类型对python显示包装,对dict类型,需要用dbus.types.Dictionary()包装,并且在构造函数里传入signature=’sv‘及相应的variant_level即可显示告知类型。同样,对list对象,需要用dbus.types.Array()包装。

这样即可绕过guest_signature,如果用dbus-monitor查看,就可以看到类型为variant string了。

Awesome autostart

Problem

让Awesome环境像Openbox一样在启动时,在根上下文中执行一个autostart脚本(启动程序、声明环境变量)。

Solution

Ubuntu中GDM启动后会执行 /etc/gdm/Xsession 这个脚本,如果是custom会话(启动参数custom),会执行用户目录下的.xsession脚本,否则会执行 /etc/X11/Xsession.d/ 目录下的所有脚本。

为了支持autostart脚本,可以在 /etc/X11/Xsession.d/ 里创建一个新的脚本 55awesome-autostart

BASESTARTUP=$(basename "$STARTUP" | cut -d\  -f1)
if [ "$BASESTARTUP" = x-session-manager ]; then
    BASESTARTUP=$(basename $(readlink /etc/alternatives/x-session-manager))
fi
if [ "$BASESTARTUP" = "awesome" ]; then
    AWESOME_AUTOSTART=$HOME/.config/awesome/autostart.sh
    if [ -e "$AWESOME_AUTOSTART" ]; then
        . "$AWESOME_AUTOSTART"
    fi
fi

这个脚本会判断启动的session是否是awesome,如果是,并且autostart.sh存在的话,source这个文件。autostart.sh按照xdg的约定,放在配置文件目录 $HOME/.config/awesome/ 里。

这样,在用户目录下的配置文件里,就可执行一些自启动程序,或者声明环境变量,典型的应用就是指定awesome会话专用的gtkrc:

AWESOME_CONFIG_PATH=$HOME/.config/awesome
export GTK2_RC_FILES=$AWESOME_CONFIG_PATH/gtkrc

xcompmgr -cCfF -t-5 -l-5 -r4.2 -o.55 -D6 &
awsetbg -u feh -f .config/awesome/ubuntu.jpg

Bash Color Support for Bti

Bti is well known as a command line twitter/identica/statusnet client, by Greg Kroah-Hartman.

I have been using this tool in CLI environment for a long time, found it difficult for human to parse output by eyes. So I forked it and added this bash color support, to provide some highlight on tweets.
bti-bash-color

To enable color support, add an option –auto-color to bti command, or append auto-color=yes to your configuration file($HOME/.bti)

I have sent pull request to Greg, hope the patch can be merged into master. Before approved, you can check out my fork and compile it yourself. (If liboauth not found, find it here.)

The 4k Story

从 Redis 2.0 开始,Redis的作者就不断地被问道,你为什么要自己造一个VM轮子呢。尽管作者在FAQ里说明了,但是仍然有很多不同意见。

反向代理Varnish的开发人员,Poul-Henning Kamp 写了一篇文章,What’s wrong with 1975 programming ?,锋芒毕露,矛头直指竞争对手Squid,顺便也打击一大片牵连到了Redis的作者Antirez。他说:

I have spent many years working on the FreeBSD kernel, and only rarely did I venture into userland programming, but when I had occation to do so, I invariably found that people programmed like it was still 1975.

Kamp兄有来到user-space之后一夜回到解放前的感觉,又好像摇晃着饮料瓶子对着Antirez说:你Out啦!也许是因为作者就是个内核开发者,所以Varnish对操作系统的Virtual Memory机制充分信任,把Squid对内存的手动管理称为wasted work。”So Welcome to Varnish, a 2006 architecture program. ”

还有用户也提出

Redis doesn’t use OS swap. According to Salvatore Sanfilippo, the creator of Redis, it was because the page size of 4KB was too big. I personally don’t think that helps but it’d be better if Redis preallocated specified amount of buffer pool and bring related objects to the same page to increase locality of reference, instead of letting the heap manager blindly fragment objects. In my opinion, the page size of 32 bytes is too small, considering that the hardware architectures and the compilers are optimized for the conventional page size. In that scale, even the latency of reading something from RAM could be dominant (RAM is too slow for CPU, therefore it’s got L1/L2 cache), and RAM has the pipelined burst mode to pre-fetche memory contents at a few clock cycles, before they are actually requested.

5号,Antirez在博客上写了回击 What’s wrong with 2006 programming?,他认为:

  • OS Swap在一些情况下会导致客户端阻塞
  • 4K大小的Page可能包含很多key,其中总有一些被访问到,导致操作系统无法swap这些page
  • 使用自己实现的Paging为程序提供了极大的自由度,包括作者提到的2.2将会引入的数据压缩、新的数据结构以及自定义的过期算法

前段时间,Foursquare用MongoDB时,因为Sharding方法一些疏漏把大量的数据集中到了一台机器上,导致一台EC2实例内存耗尽无法工作。Mongodb的内部机制就是mmap,我的同事做过相关的测试,当内存耗尽时,读写操作都使用磁盘,这时mongodb的性能是完全无法使用的。事后10gen的开发人员Horowitz总结出现问题的原因总结出现问题的原因时,其中很重要的一点是

Document size is less than 4k. Such documents, when moved, may be too small to free up pages and, thus, memory.

看了这个原因,Redis的作者Twitter上大喜:”Real world instance of my 4k page + small objects concerns”

Lua script for Geany to view manpage of functions

Requirement

When editing when Geany, you need some document of system library functions at hand. So you want to browse manpage at any time.

Solution

Just two lines:

sel=geany.selection()
geany.launch('rxvt-unicode', '-e', 'man', sel)

http://gist.github.com/591279

Install

Make sure you have geany-plugin-lua installed:
sudo apt-get install geany-plugin-lua

Create a lua source file named ‘ShowMan.lua’ in ~/.config/geany/plugins/geanylua/ . If the direcotry does not exist, you should create it first.

Copy two lines of lua code into this file, save and close.

Create a file named hotkeys.cfg in ~/.config/geany/plugins/geanylua/, add following content:
ShowMan.lua

Restart geany, then open Preferences->Keybindings, Lua Script-> ShowMan, bind a key, for example, Alt+m

Usage

Select the function name, and press Alt+m (or from menu Tools->Lua Scripts->ShowMan), then you see the terminal and the manpage.

geany-lua-manpage

The post is brought to you by lekhonee v0.7