2015-04-01 26 views
0

問題:我有多個Erlang服務,每個都由它們的Erlang PID標識。我希望在我的數據庫(MySQL)中保存{PID,ServiceName},使得我的羣集中需要訪問任何服務的任何Erlang進程只需要選擇服務名稱以獲取其PID,然後執行一個gen_server調用它。Erlang全局PID - 如何將它保存在MySQL中

  1. 後,我將其與term_to_binary轉換爲一個「全球性」的PID PID應保存(個體經營()) - 基本上,想象Erlang進程一個節點1上節約本身作爲< 0.45.0>在db:此意味着節點2上的進程B嘗試訪問由< 0.45.0>表示的服務將不會成功,因爲「< 0.45.0>」僅在節點1上有效;保存爲PID = term_to_binary(self())將正確解碼爲全局PID,如果我們在Node2上運行binary_to_term(PID)時,我們從db中讀取它
  2. MySQL查詢格式爲「INSERT INTO ServiceTable ...」 「++ io_lib:format(」ServicePID ='〜p',「[binary_to_list(term_to_binary(self()))])++
  3. 當我從數據庫中讀取PID時,我得到類似< <」 [131,103,100,0,23,115「... >>這是我的問題是:我可以將這個二進制轉換回像< < 131,103,100等... >>?

(我知道我可以通過例如註冊我的服務等解決這一問題 - 但我有我的理由不這樣做)。

謝謝。

+2

我強烈*建議您仔細想想爲什麼你認爲你需要做到這一點。 – zxq9 2015-04-01 12:15:39

回答

0

基於你所展示的,我猜你可以避免從二進制到列表的轉換,所以io_lib:格式會將二進制轉換爲它的字符串表示。

稍後,您可以檢索使用erl_parse和erl_eval模塊PID:

1> Pid = self(). 
<0.32.0> 
2> 
2> String = lists:flatten(io_lib:format("~p.~n",[term_to_binary(Pid)])). 
"<<131,103,100,0,13,110,111,110,111,100,101,64,110,111,104,111,115,116,0,0,0,32,\n 0,0,0,0,0>>.\n" 
3> %% to get an equivalent form of what you get from sql. 
3> {done,{ok,T,_},[]} = erl_scan:tokens([],String,1). 
{done,{ok,[{'<<',1}, 
      {integer,1,131}, 
      {',',1}, 
      {integer,1,103}, 
      {',',1}, 
      {integer,1,100}, 
      {',',1}, 
      {integer,1,0}, 
      {',',1}, 
      {integer,1,13}, 
      {',',1}, 
      {integer,1,110}, 
      {',',1}, 
      {integer,1,111}, 
      {',',1}, 
      {integer,1,110}, 
      {',',1}, 
      {integer,1,111}, 
      {',',1}, 
      {integer,1,100}, 
      {',',1}, 
      {integer,1,101}, 
      {',',1}, 
      {integer,...}, 
      {...}|...], 
      3}, 
     []} 
4> {ok,Tree} = erl_parse:parse_exprs(T). 
{ok,[{bin,1, 
      [{bin_element,1,{integer,1,131},default,default}, 
      {bin_element,1,{integer,1,103},default,default}, 
      {bin_element,1,{integer,1,100},default,default}, 
      {bin_element,1,{integer,1,0},default,default}, 
      {bin_element,1,{integer,1,13},default,default}, 
      {bin_element,1,{integer,1,110},default,default}, 
      {bin_element,1,{integer,1,111},default,default}, 
      {bin_element,1,{integer,1,110},default,default}, 
      {bin_element,1,{integer,1,111},default,default}, 
      {bin_element,1,{integer,1,100},default,default}, 
      {bin_element,1,{integer,1,101},default,default}, 
      {bin_element,1,{integer,1,64},default,default}, 
      {bin_element,1,{integer,1,110},default,default}, 
      {bin_element,1,{integer,1,111},default,default}, 
      {bin_element,1,{integer,1,104},default,default}, 
      {bin_element,1,{integer,1,111},default,default}, 
      {bin_element,1,{integer,1,115},default,default}, 
      {bin_element,1,{integer,1,...},default,default}, 
      {bin_element,1,{integer,...},default,...}, 
      {bin_element,1,{...},...}, 
      {bin_element,1,...}, 
      {bin_element,...}, 
      {...}|...]}]} 
5> {value,Res,[]} = erl_eval:exprs(Tree,[]). 
{value,<<131,103,100,0,13,110,111,110,111,100,101,64,110, 
     111,104,111,115,116,0,0,0,32,0,0,0,0,0>>, 
     []} 
6> Pid = binary_to_term(Res). %% that's it :o) 
<0.32.0> 
+0

我相信這是我的問題的答案。謝謝,帕斯卡。 – ionut 2015-04-04 06:32:33

0

最簡單的方法是使用pid_to_list/1list_to_pid/1函數。

+1

假設我在Node1上並且self()返回<0.45.0> - pid_to_list(self())將在數據庫中保存「<0.45.0>」,並且如果Node2上的進程讀取它並嘗試向<0.45.0>發送消息,則它將失敗因爲<0.45.0>是僅在Node1上有效的ID - 您需要執行term_to_binary(self()),以便Node2瞭解PID所在的位置。 – ionut 2015-04-01 10:09:43

1

您應該使用預先存在的解決方案,如gproc(由烏爾夫Wiger)。

我最近在ErlangFactory 2015上看到了一個類似的解決方案,他稱martinsk可能很快就會被稱爲「Industry」。它比gproc做得更多,其中包括諸如木筏共識協議支持等功能,以確定最佳服務器的領先地位......我想,更多與他的使用案例有關。

Gproc可能是您最好的第一步。如果您使用MySQL作爲全球註冊的知識庫以外的其他資源,配置和緩存選項可能會爲您提供實際存儲數據所需的支持。

但是,也要回答你的具體問題,如果你真的想自己做,也許atom_to_list(node()) ++ pid_to_list(self()).可以工作。

例如爲:

([email protected])6> atom_to_list(node()) ++ pid_to_list(self()). "[email protected]<0.43.0>"

+0

我看着gproc,但它不處理網絡分割。另外,__all__我的節點需要__before__我開始使用gproc。 – ionut 2015-04-03 00:27:08

+0

@ user3479863這整個話語正在走向一個你不應該前往的地方;行動中的XY問題的說明性案例。這個聲明,「[gproc]不處理netsplitting」,說這一切。 – zxq9 2015-04-03 05:31:31

+0

@ zxq9 - 我同意你的觀點,我正在陷入一個XY問題。我會採取你以前的建議和__strongly__想想爲什麼我需要這個。順便說一句,使用gproc的一些問題在這裏描述:[Erlang gproc失敗語義](http://christophermeiklejohn.com/erlang/2013/06/05/erlang-gproc-failure-semantics.html)。我會就這個問題提出另一個更清晰的問題。謝謝。 – ionut 2015-04-04 06:23:21