linux samba share user
2012-09-12 21:37
232 查看
关于erlang提供的gen_fsm有限状态机模型,可以说是很好很强大,正是有了它,才使erlang编写复杂业务逻辑成为一件轻松愉快的事情
但是由于erlang的速错设计原则,我们的状态机进程可能在某些异常下直接退出,这点可能跟我们的需要有点背离
最常见的情况是,状态转移中的错误处理问题,如下代码:
我要实现的是一个简单的状态转移,
初始状态是 wait_player,收到 {join,UserId} 的消息后,进行简单业务逻辑处理判断,当有3个人加入进来,则转移到下一状态 wait_start,这时的StateName是 wait_start,
但是,假如这时客户端继续调用了join接口,也就是发送了{join,UserId}的消息给gen_fsm进程,那么gen_fsm实际回调的是 Mod:StateName,
也就是我们的wait_start({join,UserId},State)方法,结果就是undef 错误,然后整个gen_fsm进程退出,这就不是我想要的了,我希望我的gen_fsm进程能够不理会这种错误的消息或行为(只记录下错误调用日志即可),而不是直接退出
再来简单看一下gen_fsm处理流程(其实基本和gen_server差不多的),
gen_fsm进程启动后会进入一个main loop,等待处理mailbox里的消息,根据消息类型(接口处打上不同的label)分类处理,回调等
main_loop 代码
跟踪到这里
dispatch函数实际就是根据消息label,调用不同回调接口的地方,然后可以看到,根据回调接口的返回,来进行不同处理,
异步的消息直接返回{next_state,...},
同步则是{reply,...}
其实最重要的是告知gen_fsm的下一状态名,也就是NStateName
实际,消息回调发生问题,或者错误的状态消息,则会返回{'EXIT',What}这个消息,gen_fsm源码是一律 terminate
我添加了2行注释,可以不直接退出
实际我们要做的就是在这个基础上完善一下就可以了,比如可以根据Reason判断那种情况该terminate,那种情况可以忽略,继续loop进入主循环处理下一消息
另外一个注意的问题是,尽管加了这2行代码后,gen_fsm不会立即由于undef function而直接退出,但是由于我们的join接口是sync同步调用,实际在gen.erl里会等待gen_fsm进程处理完该消息的返回,
而实际由于是一个错误的调用,所以我们可以返回一个自定义的错误,或者干脆不理会这个返回,如果不理会,则gen.erl由于等待消息超时一样会crash,实际crash的是调用者进程,所以要做好catch
这样,通过添加2行代码到gen_fsm就可以使我们的gen_fsm进程更稳定了
时间仓促,没有多考虑,应该会有更好的办法
但是由于erlang的速错设计原则,我们的状态机进程可能在某些异常下直接退出,这点可能跟我们的需要有点背离
最常见的情况是,状态转移中的错误处理问题,如下代码:
%% ==================================================================== %% Interface Function %% ==================================================================== join(UserId)-> io:format("join UserId=~p~n",[UserId]), gen_fsm:sync_send_event(?MODULE, {join,UserId}). start()-> gen_fsm:send_event(?MODULE,start). %% ==================================================================== %% Callback Function %% ==================================================================== wait_player({join,UserId},_From, State) -> Count=State#state.count+1, if Count =:= 3 -> io:format("jump to next phrase -> start~n"), {reply,next_phrase,wait_start,State}; true-> NewState=State#state{count=Count}, {reply,stand_still,wait_player,NewState} end. wait_start(start,State)-> io:format("recv start event ~n"), {next_state,wait_start,State}. start_link()-> gen_fsm:start_link({local,?MODULE}, ?MODULE, [] ,[]). init([])-> {ok, wait_player, #state{count=0}}.
我要实现的是一个简单的状态转移,
初始状态是 wait_player,收到 {join,UserId} 的消息后,进行简单业务逻辑处理判断,当有3个人加入进来,则转移到下一状态 wait_start,这时的StateName是 wait_start,
但是,假如这时客户端继续调用了join接口,也就是发送了{join,UserId}的消息给gen_fsm进程,那么gen_fsm实际回调的是 Mod:StateName,
也就是我们的wait_start({join,UserId},State)方法,结果就是undef 错误,然后整个gen_fsm进程退出,这就不是我想要的了,我希望我的gen_fsm进程能够不理会这种错误的消息或行为(只记录下错误调用日志即可),而不是直接退出
再来简单看一下gen_fsm处理流程(其实基本和gen_server差不多的),
gen_fsm进程启动后会进入一个main loop,等待处理mailbox里的消息,根据消息类型(接口处打上不同的label)分类处理,回调等
main_loop 代码
loop(Parent, Name, StateName, StateData, Mod, Time, Debug) -> Msg = receive Input -> Input after Time -> {'$gen_event', timeout} end, decode_msg(Msg,Parent, Name, StateName, StateData, Mod, Time, Debug, false).
跟踪到这里
handle_msg(Msg, Parent, Name, StateName, StateData, Mod, _Time) -> %No debug here From = from(Msg), case catch dispatch(Msg, Mod, StateName, StateData) of {next_state, NStateName, NStateData} -> loop(Parent, Name, NStateName, NStateData, Mod, infinity, []); {next_state, NStateName, NStateData, Time1} -> loop(Parent, Name, NStateName, NStateData, Mod, Time1, []); {reply, Reply, NStateName, NStateData} when From =/= undefined -> reply(From, Reply), loop(Parent, Name, NStateName, NStateData, Mod, infinity, []); {reply, Reply, NStateName, NStateData, Time1} when From =/= undefined -> reply(From, Reply), loop(Parent, Name, NStateName, NStateData, Mod, Time1, []); {stop, Reason, NStateData} -> terminate(Reason, Name, Msg, Mod, StateName, NStateData, []); {stop, Reason, Reply, NStateData} when From =/= undefined -> {'EXIT', R} = (catch terminate(Reason, Name, Msg, Mod, StateName, NStateData, [])), reply(From, Reply), exit(R); {'EXIT', What} -> %%{Reason,StackInfo}=What, %%loop(Parent, Name, StateName, StateData, Mod, infinity, []); terminate(What, Name, Msg, Mod, StateName, StateData, []); Reply -> terminate({bad_return_value, Reply}, Name, Msg, Mod, StateName, StateData, []) end.
dispatch函数实际就是根据消息label,调用不同回调接口的地方,然后可以看到,根据回调接口的返回,来进行不同处理,
异步的消息直接返回{next_state,...},
同步则是{reply,...}
其实最重要的是告知gen_fsm的下一状态名,也就是NStateName
实际,消息回调发生问题,或者错误的状态消息,则会返回{'EXIT',What}这个消息,gen_fsm源码是一律 terminate
我添加了2行注释,可以不直接退出
%%{Reason,StackInfo}=What, %%loop(Parent, Name, StateName, StateData, Mod, infinity, []);
实际我们要做的就是在这个基础上完善一下就可以了,比如可以根据Reason判断那种情况该terminate,那种情况可以忽略,继续loop进入主循环处理下一消息
另外一个注意的问题是,尽管加了这2行代码后,gen_fsm不会立即由于undef function而直接退出,但是由于我们的join接口是sync同步调用,实际在gen.erl里会等待gen_fsm进程处理完该消息的返回,
而实际由于是一个错误的调用,所以我们可以返回一个自定义的错误,或者干脆不理会这个返回,如果不理会,则gen.erl由于等待消息超时一样会crash,实际crash的是调用者进程,所以要做好catch
这样,通过添加2行代码到gen_fsm就可以使我们的gen_fsm进程更稳定了
时间仓促,没有多考虑,应该会有更好的办法
相关文章推荐
- Linux Kernel Samba Share Local Privilege Elevation Vulnerability
- samba share files between windows and ubuntu LINUX 文件共享
- Ubuntu14.04利用samba实现Linuxwindows共享出现Failed to add entry for user linux.问题的解决方案
- 快速设置linux主机与PC之间共享目录--sudo mount -t cifs //192.168.0.41/share_ share_pc/ -o user=lms
- ubntu samba linux share mount
- vmware linux samba share with windows
- Configuring a single samba server to share folds between xp and linux
- Linux添加用户(user)到用户组(group)
- How can I add a user to a group under Linux operating system?
- windows系统访问linux系统samba服务案例
- Linux 系统中这样修复 SambaCry 漏洞
- Linux中Samba详细安装
- Linux 为普通user增加sudo权限
- Setup MySQL in user home without superuser using generic linux distribution
- APK 签名 shareuserId
- 一步一学Linux与Windows 共享文件Samba
- Windows系统与Linux系统之间资源samba共享【转】
- smbpasswd命令_Linux smbpasswd 命令用法详解:samba用户和密码管理工具
- Linux下文件服务器配置 Samba高级应用
- ubuntu 9.04 下samba配置实现linux与XP文件共享