[Erlang 0094] Erlang 雜記 VI


  最近一直忙Storm相關的東西,今天抽時間整理一下Erlang筆記,這一次的內容主要是一些開源項目:Mock ,worker pool......
  
 

安裝Erlan/OTP

  
 之前寫過一個關於 Centos安裝Erlang的文章,還是有人把Erlang編譯安裝這件事情做到了極致: Kerl
 
  Easy building and installing of Erlang/OTP instances;Kerl aims to be shell agnostic and its only dependencies, excluding what's required to actually build Erlang/OTP, are curl and git.
 
$ kerl list releases
Getting the available releases from erlang.org...
R10B-0 R10B-2 R10B-3 R10B-4 R10B-5 R10B-6 R10B-7 R10B-8 R10B-9 R11B-0 R11B-1
R11B-2 R11B-3 R11B-4 R11B-5 R12B-0 R12B-1 R12B-2 R12B-3 R12B-4 R12B-5 R13A
R13B R13B01 R13B02 R13B03 R13B04 R14A R14B R14B01 R14B02
Run "./kerl update releases" to update this list from erlang.org

 

  

2013-6-1 18:33:47更新 網友Wang Lihe的使用反饋,供參考

緣起是這樣:在公司開發項目,但是公司使用的redhat很老舊,只有5.3至5.8系列的,甚至還有4系列。官方庫里是沒有erlang的,於是epel。但是epel 5里面只R12,版本相當的老。於是忍着各種基礎不足(比如lists模塊居然都少幾個函數,binary根本沒有,rebar要求R13以上啊),開發功能。但是干到第二版時,基本的性能已經達到極限了,<<160000個>>的解析變換居然要100幾個毫秒,堅決不能同意。於是開始加入driver和nif。結果發現R14B才是nif真正可用的,R12根本沒這個接口,頭撞牆啊,倆小弟那無助的眼神啊,我只好放下功能,開始研究epel 6的rpm包(邪路,不小心中招,費力不討好,沒有成功編譯過,而且分成十幾個小包,巨細,且討厭)。猛然間發現,給erlang epel打包的俄國哥們其實已經給epel5打了R14B的包,只是redhat官方喜歡“穩定”(我懷疑就是想讓全世界開發新功能趕快升級就對了),進不去。不管怎么說,R14B成功進入開發系統。但是問題很快又出現了,這大哥打的包,不知是真的因為redhat太老,還是有失水准,R14B是沒有HIPE的,而且所有的lib的src都是空的,這讓我們開發挖源碼時不勝煩惱。於是一邊開發,一邊還是在研究打包。一開始是看着erlang-solutions的rhel5.5 coming soon眼發綠,但是好久沒有動靜,后來開始看官方編譯教程,猛然間,搜到了一個叫kerl的東西。這讓我大喜過望,試用結果非常好。kerl本身只是一個shell腳本,運行后在$HOME下建立.kerl目錄,所有的東西都放下面,不會擾亂其他的,而且從下載到編譯安裝一就俱全,特特別好的是,安裝並不需要安裝到系統,而是可以指定自己的位置,這樣,可以同時安裝好多個版本。只要引入不同的啟動文件,就可以在不同的erlang版本里切換,非常方便。我一路從R14B編譯至R16B,全部成功,哇卡卡,甚至可以在rhel4上使用,這是讓公司的老機器煥發青春么(磁盤滿了,編譯過了,好像沒安裝成功,有機會再重試,有成功的各位分享一下)?至此,在合適的時候,所有的開發和應用環境,都有機會使用最新版erlang了,以上,分享給各位。

各種網址:
epel: https://fedoraproject.org/wiki/EPEL
以前上面還有4系列的,rhel4上的erlang是R11,完全不能用。
rhel4系列的源還活着https://dl.fedoraproject.org/pub/epel/4/x86_64/,

俄國大哥的博客:https://lemenkov.wordpress.com/2010/11/07/erlang-otp-r14b-for-epel-5/
提到的rhel5上的r14b的源:http://repos.fedorapeople.org/repos/peter/erlang/

 

 

Erlang 多語言混搭

  
   Erlang和其它語言混搭一下,效果如何?有不少這樣的項目,有些純屬玩票,有的還是發展的不錯;
 
Reia 
     Reia就屬於玩票的那種,no realease ! no direct download links!
 
 Reia is a Ruby-like scripting language for the Erlang virtual machine. Reia brings you the best of both worlds between Ruby's friendly syntax, reflection, metaprogramming, and the amazing power of blocks, and Erlang's immense abilities for concurrency, distribution, hot code swapping, and fault tolerance.
Reia's source code is available on Github. There are no releases and thus no direct download links yet, sorry! See the README on Github for instructions on how to build Reia from source.
 
 項目地址:  http://reia-lang.org/
 
 
Erlang Meet Javascript
  
   Node.js着實讓Javascript又火了一把 ,Erlang與Javascript又會擦出什么火花? 看看

 
 
Elixir
  發展比較不錯的就屬Elixir了,周邊的項目也越來越多;
 
   Elixir is a functional meta-programming aware language built on top of the Erlang VM. It is a dynamic language with flexible syntax with macros support that leverages Erlang's abilities to build concurrent, distributed, fault-tolerant applications with hot code upgrades.
 
復制代碼
defmodule Hello do
  IO.puts "Defining the function world"

  def world do
    IO.puts "Hello World"
  end

  IO.puts "Function world defined"end

Hello.world
復制代碼

項目地址: http://elixir-lang.org/

相關鏈接:  http://expm.co/
 
 
Lua
 
Luerl - an implementation of Lua in Erlang   https://github.com/rvirding/luerl
 
Joxa
 
A Modern Lisp for the Erlang VM  https://github.com/ericbmerritt/joxa
 

Meck

 
    做測試Mock是利器,Erlang對應的解決方案是meck:
    With meck you can easily mock modules in Erlang. You can also perform some basic validations on the mocked modules, such as making sure no unexpected exceptions occurred or looking at the call history.
 
看看下面的例子是不是都是熟悉的東西:
   
復制代碼
Eshell V5.8.4  (abort with ^G)
1> meck:new(dog).
ok
2> meck:expect(dog, bark, fun() -> "Woof!" end).
ok
3> dog:bark().
"Woof!"
4> meck:validate(dog).
true
5> meck:unload(dog).
ok
6> dog:bark().
** exception error: undefined function dog:bark/0

7> meck:expect(dog, meow, fun() -> meck:exception(error, not_a_cat) end).
ok
8> catch dog:meow().
{'EXIT',{not_a_cat,[{meck,exception,2},
                    {meck,exec,4},
                    {dog,meow,[]},
                    {erl_eval,do_apply,5},
                    {erl_eval,expr,5},
                    {shell,exprs,6},
                    {shell,eval_exprs,6},
                    {shell,eval_loop,3}]}}
9> meck:validate(dog).
true
復制代碼

 

 項目地址: https://github.com/eproxus/meck

 還有一個gen_server_mock.erl 也可以看一下: https://github.com/jashmenn/gen_server_mock

 

 Poolboy 

 
    正如這個項目的描述 "A hunky Erlang worker pool factory"
復制代碼
init([]) ->
    {ok, Pools} = application:get_env(example, pools),
    PoolSpecs = lists:map(fun({Name, SizeArgs, WorkerArgs}) ->
        PoolArgs = [{name, {local, Name}},
                    {worker_module, example_worker}] ++ SizeArgs,
        poolboy:child_spec(Name, PoolArgs, WorkerArgs)
    end, Pools),
    {ok, {{one_for_one, 10, 10}, PoolSpecs}}.

squery(PoolName, Sql) ->
    poolboy:transaction(PoolName, fun(Worker) ->
        gen_server:call(Worker, {squery, Sql})
    end).

equery(PoolName, Stmt, Params) ->
    poolboy:transaction(PoolName, fun(Worker) ->
        gen_server:call(Worker, {equery, Stmt, Params})
    end).
復制代碼
 
 
 
 
常識一則:獲取gen_server gen_fsm的運行時Status
 
   這應該算是常識不算技巧了,使用sys:get_status/1,可以獲取gen_server等運行時的值.下面是process_info和sys:get_status的結果對比;這里使用的fsm_demo.erl是一個gen_fsm的程序.記錄一下,我總是忘記它所在的模塊;
 
復制代碼
Eshell V5.9  (abort with ^G)
1> fsm_demo:start(abc).
{ok,<0.34.0>}
2> {_,Pid}=v(1).
{ok,<0.34.0>}
3> erlang:process_info(Pid).
[{registered_name,fsm_demo},
{current_function,{gen_fsm,loop,7}},
{initial_call,{proc_lib,init_p,5}},
{status,waiting},
{message_queue_len,0},
{messages,[]},
{links,[]},
{dictionary,[{'$ancestors',[<0.32.0>]},
              {'$initial_call',{fsm_demo,init,1}}]},
{trap_exit,false},
{error_handler,error_handler},
{priority,normal},
{group_leader,<0.25.0>},
{total_heap_size,233},
{heap_size,233},
{stack_size,10},
{reductions,20},
{garbage_collection,[{min_bin_vheap_size,46368},
                      {min_heap_size,233},
                      {fullsweep_after,65535},
                      {minor_gcs,0}]},
{suspending,[]}]
4> sys:get_status(fsm_demo).
{status,<0.34.0>,
        {module,gen_fsm},
        [[{'$ancestors',[<0.32.0>]},
          {'$initial_call',{fsm_demo,init,1}}],
         running,<0.34.0>,[],
         [{header,"Status for state machine fsm_demo"},
          {data,[{"Status",running},
                 {"Parent",<0.34.0>},
                 {"Logged events",[]},
                 {"StateName",locked}]},
          {data,[{"StateData",{[],abc}}]}]]}
5> 
復制代碼

 

2012年12月18日 14:10:24 補記

復制代碼
Eshell V5.9  (abort with ^G)
1>  T={a,12,"good_man",<<2,3,4>>}.
{a,12,"good_man",<<2,3,4>>}
2> io:format("Data Dump:~p",[T]).
Data Dump:{a,12,"good_man",<<2,3,4>>}ok
3> rd(a,{age,name,desc}).
a
4> io:format("Data Dump:~p",[T]).
Data Dump:{a,12,"good_man",<<2,3,4>>}ok
5> T2=T.
#a{age = 12,name = "good_man",desc = <<2,3,4>>}
6> io:format("Data Dump:~p",[T2]).
Data Dump:{a,12,"good_man",<<2,3,4>>}ok
7> io:format(io_lib_pretty:print(T, fun(a, 3) -> [age,name,desc] end)).
#a{age = 12,name = "good_man",desc = <<2,3,4>>}ok
8> 
復制代碼

 

2012-12-19 21:55 補記

 今天群里面有人問到:一個進程被壓了很多消息,處理速度變慢,開啟了SMP更慢,何解?

 這個和timer的情況很類似:

Creating timers using erlang:send_after/3 and erlang:start_timer/3 is much more efficient than using the timers provided by the timer module. The timer module uses a separate process to manage the timers, and that process can easily become overloaded if many processes create and cancel timers frequently (especially when using the SMP emulator).

http://www.erlang.org/doc/efficiency_guide/commoncaveats.html#id62547

 

 

 

最后小圖一張:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM