2017-10-08 88 views
0

我在一個節點上創建一個文件流,我擔心文件訪問,如果我從另一個節點啓動流,該怎麼辦?從另一個節點開始流?

一樣,在節點A,我沒有啓動它創建流:

stream= File.stream!(path) 
Agent.start(fn -> %{"stream" => stream} end, name: {:global, :my_stream}) 

然後,在節點B,我開始流:

stream= Agent.get({:global, :my_stream}, fn %{"stream" => stream } -> stream end) 
Task.start_link(Stream, :run, [stream]) 

請問流中查找文件在預期的節點A上?或者它會在節點B上查找它(考慮節點B是流的啓動位置),因爲如果這樣做會失敗,因爲文件實際上存在於節點A上。

我應該關聯哪個節點該文件存儲?我會怎麼做?我一定要嗎?

有什麼想法?

+0

這是什麼路徑?如果是文件,則必須從兩個節點同樣可見。這在遠程節點上不一定是正確的。 – GavinBrelstaff

+0

'path'是文件(包括路徑),我有每個節點都在一個單獨的服務器上,所以,你認爲我的方法不安全嗎?或者至少,不保證工作? – simo

+0

根據我在網絡連接節點上使用'File.stream'的經驗,您需要每個erlang-VM上的文件的本地副本,其路徑名適用於每個文件系統/操作系統 - 否則它不會工作。 「文件」不是一個URL。 – GavinBrelstaff

回答

0

File.stream!返回File.Stream結構含有4個字段:pathmodesraw,和line_or_bytes。該文件實際上只在流執行時才使用,例如, Stream.run/1或任何Enum功能。當您使用Agent將該結構傳遞給另一個節點時,只傳遞此4字段結構,並且如果您在該另一個節點上調用Stream.run,則該節點將嘗試打開path所指向的文件,如果文件不' t存在於該節點的文件系統上。所以,你的問題的答案是,除非文件存在於相同的路徑,否則操作將失敗。

另一方面,Elixir中的文件句柄是內部存儲對打開的文件的引用的PID。它們可以被創建,例如使用File.open!/1。如果您將通過此調用返回的PID傳遞給另一個節點,然後對其執行操作,例如該節點上的IO.read(不是File.read),它將成功,因爲操作作爲消息發送到PID。如果文件句柄的PID來自另一個節點,則文件操作將透明地通過連接傳輸)。所以,如果你想訪問這樣的文件,你可以使用File.open!,然後從另一個節點使用IO.read