2011年9月28日 星期三

[Linux] Fork & exec

Fork 會把除了process id 之外, 整個program 都複製一份給child process (先不管copy on write), 在child process 執行exec之後, 原本program的資料就會lost, 全部取代成新的program, 但是fd不會自動close, 除非你有設定close-on-exec, 不然要不你需要手動close, 或是用來當作跟parent process溝通的管道.

p.s 當child process在處理NFS之類的fd, 要關掉fd, 有時會需要很長得時間才關得掉 (NFS server unreachable or 你改了ethernet address), 似乎這時候process會在D (uninterruptable) 這個state 停留非常久的時間...簡單來說, 在處理NFS這種網路的fd, 需要注意以免被watchdog

Reference
http://en.wikipedia.org/wiki/Fork-exec 
http://stackoverflow.com/questions/1643304/how-to-set-close-on-exec-by-default 

2011年9月27日 星期二

[XML] The difference between value-of and copy-of

差別:

  • xsl:value-of returns all the TEXT within the selected tag(s).
  • xsl:copy-of returns all the ELEMENTS (both tags and text) of the selected tag(s).

一言以蔽之, value-of 只會回傳你選擇node裡面的text, 但是copy-of 卻是會把整個node structure都回傳回來.

例子:

<Name>
 <Family>Smith</Family>
 <Given>John</Given>
</Name>

XSLT:
<xsl:value-of select="Name"/> 

<!-- 輸出element Name下面的所有text -->

Output:
Smith
John

 

XSLT:

<xsl:value-of select="Name"/> 

輸出Name底下的所有element (包含tag)

Output:

<Name>

 <Family>Smith</Family>

 <Given>John</Given>

</Name>

 

XSLT:
<xsl:value-of select="Name/node()"/> 

輸出Name底下子節點的所有element (包含tag), 不包含自己

Output:

 <Family>Smith</Family>

 <Given>John</Given>

 

XSLT:

<xsl:value-of select="Name/text()"/> 
 輸出Name底下的text, 但是這邊沒有, 所以沒有輸出

Output:

Reference:
http://dev.ektron.com/blogs.aspx?id=10472

2011年9月26日 星期一

[C++] Constructor call other constructor


#include

class Foo
{
public:
Foo() { Foo(1); };
Foo(int a) { m = a; std::cout <<"Foo " << a << std::endl; }

private:
int m;
};

int main()
{
Foo a, b(2);
return 0;
}

It is ok to call other constructor on method body, but calling other constructor on Initialize list is not allowed!
The following example is not allowed.


#include

class Foo
{
public:
// this will cause compile error!!
Foo() : this(1) { };
Foo(int a) { m = a; std::cout <<"Foo " << a << std::endl; }

private:
int m;
};

int main()
{
Foo a, b(2);
return 0;
}

Reference:
http://stackoverflow.com/questions/308276/c-call-constructor-from-constructor

2011年9月16日 星期五

[RabbitMQ] cluster setting

在Ubuntu機器上面安裝很方便, 先安裝完erlang,另外要在裝erlang-nox, 接著直接把抓下來的rabbitmq-server deb安裝就行


$ sudo apt-get install erlang
$ sudo apt-get install erlang-nox
$ dpkg -i rabbitmq-server_2.6.1-1_all.deb
$

另外rabbitmq有提供使用plugin, 如果你是用deb安裝, 那你只需要把所有plugin (.ez)放到 /usr/lib/rabbitmq/lib/rabbitmqserver-2.6.1/plugins下就行了.
我是安裝rabbitmq-management plugin, 在cluster裡面, 只需要有一台安裝完整management plugin, 其他台都指需要裝management
agent就行~


$ ls /usr/lib/rabbitmq/lib/rabbitmq_server-2.6.1/plugins/
amqp_client-2.6.1.ez
rabbitmq_mochiweb-2.6.1.ez
mochiweb-1.3-rmq2.6.1-git9a53dbd.ez
README
rabbitmq_management-2.6.1.ez
webmachine-1.7.0-rmq2.6.1-hg0c4b60a.ez
rabbitmq_management_agent-2.6.1.ez

在erlang的世界裡面, 需要設定同樣的cookie,不同的node彼此之間才可以溝通, 所以假設我們有lab1, lab2, lab3三台機器, 只要把lab1 上面的/var/lib/rabbitmq/.erlang.cookie copy到其他兩台機器上面, 就可以溝通了, 之後就可以透過rabbitmqctl來建立cluster, 有幾點要特別注意

  • 更換.erlang.cookie完之後, 要記得rm -rf /var/lib/rabbitmq/mnesia
  • 要記得更改/etc/hosts裡面關於cluster ip host mapping, 這樣erlang才可以查到domain name的ip
  • 之後要自動設定, 可以寫檔案在/etc/rabbitmq 下面

$ rm -rf /var/lib/rabbitmq/mnesia
$ rabbitmqctl cluster_status
...
$ rabbitmqctl stop_app
...
$ rabbitmqctl reset
...
$ rabbitmqctl cluster rabbit@lab001 # add lab002 as mem mode
...
$ rabbitmqctl cluster rabbit@lab001 rabbit@lab003 # add lab003 as disk mode
...
$ rabbitmqctl cluster_status
...
$ cat /etc/rabbitmq/rabbitmq-env.conf
RABBITMQ_CONFIG_FILE=/etc/rabbitmq/rabbitmq.conf
$ cat /etc/rabbitmq/rabbitmq.conf
[ {rabbit, [ {cluster_nodes, ['rabbit@lab001', 'rabbit@lab003']} ]} ].
$

另外提到一點, erlang的shell可以拿來幫助debug, 當你選定某組cookie來跑rabbitmq server, 假設跑在lab001, 可以利用erlang shell確認連線有沒有錯誤,
假如回傳的是pang, 那代表連線有問題~ 另外也要確定epmd 這個erlang內建的daemon有沒有跑起來~


lab002 $ erl -sname ooo -setcookie
Erlang R13B03 (erts-5.7.4) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.4 (abort with ^G)
(oo@lab002)1> net_adm:ping('rabbit@lab001').
pong
(oo@lab002)2>

$ epmd -names
epmd: up and running on port 4369 with data:
name rabbit at port 58909

Reference
http://www.rabbitmq.com/clustering.html

[Network] TCP hole punching under NAT

NAT (network address translation) box, 目前可以分為四種address mapping方式

  • Full Cone mapping
  • Restricted Cone mapping
  • Port Restricted Cone mapping
  • Symmetric mapping

當我們要從Addr1: Port1 經過NAT1: Port 0出去到Addr2: Port 2的時候

Full Cone mapping:
NAT1: Port 0會處理任何跟Addr1:Port 1的連線, 就算是Addr3:Port3, 只要能猜到NAT1:Port 0, 都可以跟Addr1: Port 1溝通

Restricted Cone mapping:
只有當Addr1: Port 1之前有連線到Addr 3, Addr 3 才可以透過NAT1: Port 0連進來 Addr1: Port 1

Port Restricted Cone mapping:
只有當Addr1: Port 1之前有連線到Addr 3: Port 3, Addr 3:Port 3 才可以透過NAT1: Port 0連進來 Addr1: Port 1

Symmetric mapping:
NAT會自動為每一組Addr1: Port 1所連出去的IP Port都準備獨立的Port mapping, 例如
Addr1: Port 1 -> NAT: Port 0 -> Addr2: Port 2 
Addr1: Port 1 -> NAT: Port 4 -> Addr2: Port 3

這四種mapping的方式會影響到, 你如何利用TCP 來對NAT 打洞 (TCP hole punching), 前三種都算好解, 畢竟妳只要有辦法知道Addr 1:Port 1連出去的 NAT: Port 0, 你就可以跟他溝通, 第四種可能只能靠port predict的方式來做

2011年9月6日 星期二

[C++] Derived class no need to write virtual when base class already has

From
http://stackoverflow.com/questions/4895294/c-virtual-keyword-for-functions-in-derived-classes-is-it-necessary

But I think it's more readable and clear to write on virtual...