2010年5月26日星期三
unix erlang man 安装
/usr/local/lib/e
2010年5月24日星期一
webtool 远程访问启动方式
2010年5月21日星期五
2010年5月20日星期四
mochiweb 不一定每个请求是一个新的process(转)
mochiweb 不一定每个请求是一个新的process
文章分类:综合技术 关键字: mochiweb
今天试了一下mochiweb,这个东东的文档实在是少的可怜,推荐一个不错的tutorial:
http://erlang-china.org/start/mochiweb_intro.html
做了一个简单的comet测试,在firefox下浏览时发现每个http请求处理的process id固定在2个,而且进程字典的数据也可以跨请求共享,找了下mochiweb的源码,发现其在http请求结束时,支持tcp连接复用(http1.1),代码如下:
mochiweb_http.erl
- after_response(Body, Req) ->
- Socket = Req:get(socket),
- case Req:should_close() of
- true ->
- gen_tcp:close(Socket),
- exit(normal);
- false ->
- Req:cleanup(),
- ?MODULE:loop(Socket, Body)
- end.
mochiweb_request.erl
- %% @spec should_close() -> bool()
- %% @doc Return true if the connection must be closed. If false, using
- %% Keep-Alive should be safe.
- should_close() ->
- ForceClose = erlang:get(mochiweb_request_force_close) =/= undefined,
- DidNotRecv = erlang:get(mochiweb_request_recv) =:= undefined,
- ForceClose orelse Version < {1, 0}
- %% Connection: close
- orelse get_header_value("connection") =:= "close"
- %% HTTP 1.0 requires Connection: Keep-Alive
- orelse (Version =:= {1, 0}
- andalso get_header_value("connection") =/= "Keep-Alive")
- %% unread data left on the socket, can't safely continue
- orelse (DidNotRecv
- andalso get_header_value("content-length") =/= undefined
- andalso list_to_integer(get_header_value("content-length")) > 0)
- orelse (DidNotRecv
- andalso get_header_value("transfer-encoding") =:= "chunked").
So, it's clear now.
2010年5月11日星期二
erlang学习笔记 跨系统erlang查询脚本
2010年5月5日星期三
erlang sys调试(转)
6 Sys and Proc_Lib
The module sys contains functions for simple debugging of processes implemented using behaviours.
There are also functions that, together with functions in the module proc_lib, can be used to implement a special process, a process which comply to the OTP design principles without making use of a standard behaviour. They can also be used to implement user defined (non-standard) behaviours.
Both sys and proc_lib belong to the STDLIB application.
6.1 Simple Debugging
The module sys contains some functions for simple debugging of processes implemented using behaviours. We use the code_lock example from the gen_event chapter to illustrate this:
% erl
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
Eshell V5.2.3.6 (abort with ^G)
1> code_lock:start_link([1,2,3,4]).
{ok,<0.32.0>}
2> sys:statistics(code_lock, true).
ok
3> sys:trace(code_lock, true).
ok
4> code_lock:button(4).
*DBG* code_lock got event {button,4} in state closed
ok
*DBG* code_lock switched to state closed
5> code_lock:button(3).
*DBG* code_lock got event {button,3} in state closed
ok
*DBG* code_lock switched to state closed
6> code_lock:button(2).
*DBG* code_lock got event {button,2} in state closed
ok
*DBG* code_lock switched to state closed
7> code_lock:button(1).
*DBG* code_lock got event {button,1} in state closed
ok
OPEN DOOR
*DBG* code_lock switched to state open
*DBG* code_lock got event timeout in state open
CLOSE DOOR
*DBG* code_lock switched to state closed
8> sys:statistics(code_lock, get).
{ok,[{start_time,{{2003,6,12},{14,11,40}}},
{current_time,{{2003,6,12},{14,12,14}}},
{reductions,333},
{messages_in,5},
{messages_out,0}]}
9> sys:statistics(code_lock, false).
ok
10> sys:trace(code_lock, false).
ok
11> sys:get_status(code_lock).
{status,<0.32.0>,
{module,gen_fsm},
[[{'$ancestors',[<0.30.0>]},
{'$initial_call',{gen,init_it,
[gen_fsm,<0.30.0>,<0.30.0>,
{local,code_lock},
code_lock,
[1,2,3,4],
[]]}}],
running,<0.30.0>,[],
[code_lock,closed,{[],[1,2,3,4]},code_lock,infinity]]}
6.2 Special Processes
This section describes how to write a process which comply to the OTP design principles, without making use of a standard behaviour. Such a process should:
be started in a way that makes the process fit into a supervision tree,
support the sys debug facilities, and
take care of system messages.
System messages are messages with special meaning, used in the supervision tree. Typical system messages are requests for trace output, and requests to suspend or resume process execution (used during release handling). Processes implemented using standard behaviours automatically understand these messages.
Example
The simple server from the Overview chapter, implemented using sys and proc_lib so it fits into a supervision tree:
-module(ch4).
-export([start_link/0]).
-export([alloc/0, free/1]).
-export([init/1]).
-export([system_continue/3, system_terminate/4,
write_debug/3]).
start_link() ->
proc_lib:start_link(ch4, init, [self()]).
alloc() ->
ch4 ! {self(), alloc},
receive
{ch4, Res} ->
Res
end.
free(Ch) ->
ch4 ! {free, Ch},
ok.
init(Parent) ->
register(ch4, self()),
Chs = channels(),
Deb = sys:debug_options([]),
proc_lib:init_ack(Parent, {ok, self()}),
loop(Chs, Parent, Deb).
loop(Chs, Parent, Deb) ->
receive
{From, alloc} ->
Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
ch4, {in, alloc, From}),
{Ch, Chs2} = alloc(Chs),
From ! {ch4, Ch},
Deb3 = sys:handle_debug(Deb2, {ch4, write_debug},
ch4, {out, {ch4, Ch}, From}),
loop(Chs2, Parent, Deb3);
{free, Ch} ->
Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
ch4, {in, {free, Ch}}),
Chs2 = free(Ch, Chs),
loop(Chs2, Parent, Deb2);
{system, From, Request} ->
sys:handle_system_msg(Request, From, Parent,
ch4, Deb, Chs)
end.
system_continue(Parent, Deb, Chs) ->
loop(Chs, Parent, Deb).
system_terminate(Reason, Parent, Deb, Chs) ->
exit(Reason).
write_debug(Dev, Event, Name) ->
io:format(Dev, "~p event = ~p~n", [Name, Event]).
Example on how the simple debugging functions in sys can be used for ch4 as well:
% erl
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
Eshell V5.2.3.6 (abort with ^G)
1> ch4:start_link().
{ok,<0.30.0>}
2> sys:statistics(ch4, true).
ok
3> sys:trace(ch4, true).
ok
4> ch4:alloc().
ch4 event = {in,alloc,<0.25.0>}
ch4 event = {out,{ch4,ch1},<0.25.0>}
ch1
5> ch4:free(ch1).
ch4 event = {in,{free,ch1}}
ok
6> sys:statistics(ch4, get).
{ok,[{start_time,{{2003,6,13},{9,47,5}}},
{current_time,{{2003,6,13},{9,47,56}}},
{reductions,109},
{messages_in,2},
{messages_out,1}]}
7> sys:statistics(ch4, false).
ok
8> sys:trace(ch4, false).
ok
9> sys:get_status(ch4).
{status,<0.30.0>,
{module,ch4},
[[{'$ancestors',[<0.25.0>]},{'$initial_call',{ch4,init,[<0.25.0>]}}],
running,<0.25.0>,[],
[ch1,ch2,ch3]]}
Starting the Process
A function in the proc_lib module should be used to start the process. There are several possible functions, for example spawn_link/3,4 for asynchronous start and start_link/3,4,5 for synchronous start.
A process started using one of these functions will store information that is needed for a process in a supervision tree, for example about the ancestors and initial call.
Also, if the process terminates with another reason than normal or shutdown, a crash report (see SASL User's Guide) is generated.
In the example, synchronous start is used. The process is started by calling ch4:start_link():
start_link() ->
proc_lib:start_link(ch4, init, [self()]).
ch4:start_link calls the function proc_lib:start_link. This function takes a module name, a function name and an argument list as arguments and spawns and links to a new process. The new process starts by executing the given function, in this case ch4:init(Pid), where Pid is the pid (self()) of the first process, that is the parent process.
In init, all initialization including name registration is done. The new process must also acknowledge that it has been started to the parent:
init(Parent) ->
...
proc_lib:init_ack(Parent, {ok, self()}),
loop(...).
proc_lib:start_link is synchronous and does not return until proc_lib:init_ack has been called.
Debugging
To support the debug facilites in sys, we need a debug structure, a term Deb which is initialized using sys:debug_options/1:
init(Parent) ->
...
Deb = sys:debug_options([]),
...
loop(Chs, Parent, Deb).
sys:debug_options/1 takes a list of options as argument. Here the list is empty, which means no debugging is enabled initially. See sys(3) for information about possible options.
Then for each system event that we want to be logged or traced, the following function should be called.
sys:handle_debug(Deb, Func, Info, Event) => Deb1
Deb is the debug structure.
Func is a tuple {Module, Name} (or a fun) and should specify a (user defined) function used to format trace output. For each system event, the format function is called as Module:Name(Dev, Event, Info), where:
Dev is the IO device to which the output should be printed. See io(3).
Event and Info are passed as-is from handle_debug.
Info is used to pass additional information to Func, it can be any term and is passed as-is.
Event is the system event. It is up to the user to define what a system event is and how it should be represented, but typically at least incoming and outgoing messages are considered system events and represented by the tuples {in,Msg[,From]} and {out,Msg,To}, respectively.
handle_debug returns an updated debug structure Deb1.
In the example, handle_debug is called for each incoming and outgoing message. The format function Func is the function ch4:write_debug/3 which prints the message using io:format/3.
loop(Chs, Parent, Deb) ->
receive
{From, alloc} ->
Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
ch4, {in, alloc, From}),
{Ch, Chs2} = alloc(Chs),
From ! {ch4, Ch},
Deb3 = sys:handle_debug(Deb2, {ch4, write_debug},
ch4, {out, {ch4, Ch}, From}),
loop(Chs2, Parent, Deb3);
{free, Ch} ->
Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
ch4, {in, {free, Ch}}),
Chs2 = free(Ch, Chs),
loop(Chs2, Parent, Deb2);
...
end.
write_debug(Dev, Event, Name) ->
io:format(Dev, "~p event = ~p~n", [Name, Event]).
Handling System Messages
System messages are received as:
{system, From, Request}
The content and meaning of these messages do not need to be interpreted by the process. Instead the following function should be called:
sys:handle_system_msg(Request, From, Parent, Module, Deb, State)
This function does not return. It will handle the system message and then call:
Module:system_continue(Parent, Deb, State)
if process execution should continue, or:
Module:system_terminate(Reason, Parent, Deb, State)
if the process should terminate. Note that a process in a supervision tree is expected to terminate with the same reason as its parent.
Request and From should be passed as-is from the system message to the call to handle_system_msg.
Parent is the pid of the parent.
Module is the name of the module.
Deb is the debug structure.
State is a term describing the internal state and is passed to system_continue/system_terminate.
In the example:
loop(Chs, Parent, Deb) ->
receive
...
{system, From, Request} ->
sys:handle_system_msg(Request, From, Parent,
ch4, Deb, Chs)
end.
system_continue(Parent, Deb, Chs) ->
loop(Chs, Parent, Deb).
system_terminate(Reason, Parent, Deb, Chs) ->
exit(Reason).
If the special process is set to trap exits, note that if the parent process terminates, the expected behavior is to terminate with the same reason:
init(...) ->
...,
process_flag(trap_exit, true),
...,
loop(...).
loop(...) ->
receive
...
{'EXIT', Parent, Reason} ->
..maybe some cleaning up here..
exit(Reason);
...
end.
6.3 User-Defined Behaviours
To implement a user-defined behaviour, write code similar to code for a special process but calling functions in a callback module for handling specific tasks.
If it is desired that the compiler should warn for missing callback functions, as it does for the OTP behaviours, implement and export the function:
behaviour_info(callbacks) ->
[{Name1,Arity1},...,{NameN,ArityN}].
where each {Name,Arity} specifies the name and arity of a callback function.
When the compiler encounters the module attribute -behaviour(Behaviour). in a module Mod, it will call Behaviour:behaviour_info(callbacks) and compare the result with the set of functions actually exported from Mod, and issue a warning if any callback function is missing.
Example:
%% User-defined behaviour module
-module(simple_server).
-export([start_link/2,...]).
-export([behaviour_info/1]).
behaviour_info(callbacks) ->
[{init,1},
{handle_req,1},
{terminate,0}].
start_link(Name, Module) ->
proc_lib:start_link(?MODULE, init, [self(), Name, Module]).
init(Parent, Name, Module) ->
register(Name, self()),
...,
Dbg = sys:debug_options([]),
proc_lib:init_ack(Parent, {ok, self()}),
loop(Parent, Module, Deb, ...).
...
In a callback module:
-module(db).
-behaviour(simple_server).
-export([init/0, handle_req/1, terminate/0]).
...
2010年4月30日星期五
erlang 数值计算
op Expr
Expr1 op Expr2
op Description Argument type
+ unary + number
- unary - number
+ number
- number
* number
/ floating point division number
bnot unary bitwise not integer
div integer division integer
rem integer remainder of X/Y integer
band bitwise and integer
bor bitwise or integer
bxor arithmetic bitwise xor integer
bsl arithmetic bitshift left integer
bsr bitshift right integer
Table 7.2: Arithmetic Operators.
2010年4月14日星期三
alarm_handler
alarm_handler
MODULE
MODULE SUMMARY
DESCRIPTION
The alarm handler process is a gen_event event manager process which receives alarms in the system. This process is not intended to be a complete alarm handler. It defines a place to which alarms can be sent. One simple event handler is installed in the alarm handler at start-up, but users are encouraged to write and install their own handlers.
The simple event handler sends all alarms as info reports to the error logger, and saves all of them in a list which can be passed to a user defined event handler, which may be installed at a later stage. The list can grow large if many alarms are generated. So it is a good reason to install a better user defined handler.
There are functions to set and clear alarms. The format of alarms are defined by the user. For example, an event handler for SNMP could be defined, together with an alarm MIB.
The alarm handler is part of the SASL application.
When writing new event handlers for the alarm handler, the following events must be handled:
- {set_alarm, {AlarmId, AlarmDescr}}
This event is generated by alarm_handler:set_alarm({AlarmId, AlarmDecsr}).
- {clear_alarm, AlarmId}
This event is generated by alarm_handler:clear_alarm(AlarmId).
The default simple handler is called alarm_handler and it may be exchanged by calling gen_event:swap_handler/3 as gen_event:swap_handler(alarm_handler, {alarm_handler, swap}, {NewHandler, Args}). NewHandler:init({Args, {alarm_handler, Alarms}}) is called. Refer to gen_event(3) for further details.
EXPORTS
clear_alarm(AlarmId) -> void()
Types:
Clears all alarms with id AlarmId.
Returns a list of all active alarms. This function can only be used when the simple handler is installed.
Types:
Sets an alarm with id AlarmId. This id is used at a later stage when the alarm is cleared.
See Also
error_logger(3), gen_event(3)
2010年4月12日星期一
erlang 常用 misc(补充ing)
2010年4月1日星期四
erlang 获取环境信息命令
code:lib_dir(rpcengine, ebin). %获取库位置
code:all_loaded(). %返回所有已经
init:get_argument(home). init:get_arguments().
例如:
% erl -a b c -a d
...
1> init:get_argument(a).
{ok,[["b","c"],["d"]]}
erlang 获取自定义属性信息
beam_lib("xxxx.beam", [attributes]).chunkid() = "Abst" | "Attr" | "CInf"
chunkid() = "Abst" | "Attr" | "CInf"
| "ExpT" | "ImpT" | "LocT"
| "Atom"
chunkname() = abstract_code | attributes | compile_info
| exports | labeled_exports
| imports | indexed_imports
| locals | labeled_locals
| atoms
chunkref() = chunkname() | chunkid()
chunks(Beam, [ChunkRef]) -> {ok, {Module, [ChunkData]}} | {error, beam_lib, Reason}