2017-11-08 4 views
2

일부 연금술 코드를 테스트하려고하는데 gen_tcp의 일부 동작을 경험했는데 이해가 안됩니다. 내가 gen_tcp.accept 소켓을 만들었을 때 내가 만든 태스크에서 "접근"할 수 있지만 다른 것은 아니었다. 나는 이것이 "controlling_process"문제라고 생각했지만, inet.getstat를 사용하면 잘못된 인수 오류가 발생합니다. 나는 또한 소켓에서 수신을 할 수 없다, Elixir는 그것이 폐쇄되어 있다고 주장하지만,이 질문에 대해서는 getstat가 더 쉬웠다. 아래를 참조다른 프로세스에서 실패한 태스크에서 소켓을 받아 들였습니다

defmodule ElixirQuestion do 
    def serve_one_client(socket, pid) 
    do 
    {:ok, server_socket} = :gen_tcp.accept(socket) 
    :ok = :gen_tcp.controlling_process(server_socket, pid) 
    IO.inspect(:inet.getstat(server_socket)) 
    server_socket 
    end 
end 

{:ok, socket} = :gen_tcp.listen(0, [:binary, 
             {:packet, :raw}, 
             {:active, false}]) 
{:ok, port_number} = :inet.port(socket) 
server_task = Task.async(fn -> ElixirQuestion.serve_one_client(socket, self()) end) 
{:ok, _client_socket} = :gen_tcp.connect('localhost', port_number, [active: false]) 
server_socket = Task.await(server_task) 

IO.inspect(:inet.getstat(server_socket)) 

예상 출력

{:ok, 
[recv_oct: 0, recv_cnt: 0, recv_max: 0, recv_avg: 0, recv_dvi: 0, send_oct: 0, 
    send_cnt: 0, send_max: 0, send_avg: 0, send_pend: 0]} 
{:ok, 
[recv_oct: 0, recv_cnt: 0, recv_max: 0, recv_avg: 0, recv_dvi: 0, send_oct: 0, 
    send_cnt: 0, send_max: 0, send_avg: 0, send_pend: 0]} 

수신 출력

{:ok, 
[recv_oct: 0, recv_cnt: 0, recv_max: 0, recv_avg: 0, recv_dvi: 0, send_oct: 0, 
    send_cnt: 0, send_max: 0, send_avg: 0, send_pend: 0]} 
{:error, :einval} 

비약 버전

Erlang/OTP 19 [erts-8.3.5.3] [source] [64-bit] [smp:2:2] [async-threads:10] [hipe] [kernel-poll:false] 

Elixir 1.4.5 

답변

2

self()Task.async 내부의 PID를 반환합니다 프로세스는 Task입니다. 상위 프로세스의 값을 여기에서 원하기 때문에 fn 외부에이 값을 저장하고 Task.async에 전달한 다음 그 값을 사용해야합니다.

변경 :

server_task = Task.async(fn -> ElixirQuestion.serve_one_client(socket, self()) end) 

에 :

{:ok, 
[recv_oct: 0, recv_cnt: 0, recv_max: 0, recv_avg: 0, recv_dvi: 0, send_oct: 0, 
    send_cnt: 0, send_max: 0, send_avg: 0, send_pend: 0]} 
{:ok, 
[recv_oct: 0, recv_cnt: 0, recv_max: 0, recv_avg: 0, recv_dvi: 0, send_oct: 0, 
    send_cnt: 0, send_max: 0, send_avg: 0, send_pend: 0]} 
+1

감사 :

me = self() server_task = Task.async(fn -> ElixirQuestion.serve_one_client(socket, me) end) 

나에게 당신이 기대하는 출력을 제공합니다. 나는 그것이 내가 대답을 얻었을 때 내가 싫어하는 것이 될 것이라는 것을 알았다! 엄청 고마워! – janders