从另一个节点开始流?
问题描述:
我在一个节点上创建一个文件流,我担心文件访问,如果我从另一个节点启动流,该怎么办?从另一个节点开始流?
一样,在节点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上。
我应该关联哪个节点该文件存储?我会怎么做?我一定要吗?
有什么想法?
答
File.stream!
返回File.Stream
结构含有4个字段:path
,modes
,raw
,和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
。
这是什么路径?如果是文件,则必须从两个节点同样可见。这在远程节点上不一定是正确的。 – GavinBrelstaff
'path'是文件(包括路径),我有每个节点都在一个单独的服务器上,所以,你认为我的方法不安全吗?或者至少,不保证工作? – simo
根据我在网络连接节点上使用'File.stream'的经验,您需要每个erlang-VM上的文件的本地副本,其路径名适用于每个文件系统/操作系统 - 否则它不会工作。 “文件”不是一个URL。 – GavinBrelstaff