Why dont I get any terminal output after hot code loading in Erlang?
up vote
3
down vote
favorite
While trying to understand how to work with servers and hot code loading I stumbled over a problem which I have stripped down to the following code:
server.erl
-module(server).
-export([start/0, connect/1]).
start() ->
{ok, Listen} = gen_tcp:listen(8080, [binary, {packet, raw}, {active, true}]),
spawn(?MODULE, connect, [Listen]).
connect(Listen) ->
{ok, Socket} = gen_tcp:accept(Listen),
spawn(?MODULE, connect, [Listen]),
loop(Socket).
loop(Socket) ->
receive
{tcp, Socket, Data} ->
io:format("1st version received ~p~n", [Data]),
loop(Socket);
{tcp_closed, Socket} ->
io:format("socket closed~n")
end.
client.erl
-module(client).
-export([request/0]).
request() ->
{ok, Socket} = gen_tcp:connect("localhost", 8080, [{packet, raw}, binary]),
gen_tcp:send(Socket, <<"Hello">>).
Starting the server and sending a request creates the expected output.
1> server:start().
<0.62.0>
2> client:request().
ok
1st version received <<"Hello">>
After changing the format statement to "2nd version", compiling and loading the code and executing two requests (because the connect/1 process currently waiting for connections was spawned before the change) the result is still as expected.
3> c(server).
{ok,server}
4> client:request().
ok
1st version received <<"Hello">>
5> client:request().
ok
2nd version received <<"Hello">>
However, after compiling and loading the code twice in a row, there is no output printed in the terminal any more, although the server is obviously still running, since gen_tcp:connect returns a socket.
6> c(server).
{ok,server}
7> c(server).
{ok,server}
8> client:request().
ok
I suspect that this behaviour has something to do with erlang killing all processes with code older than two versions but I fail to really understand what is happening here.
Since this is educational I am more interested in knowing why this exact code doesn't work rather than an actual solution to the problem.
Thanks
erlang
add a comment |
up vote
3
down vote
favorite
While trying to understand how to work with servers and hot code loading I stumbled over a problem which I have stripped down to the following code:
server.erl
-module(server).
-export([start/0, connect/1]).
start() ->
{ok, Listen} = gen_tcp:listen(8080, [binary, {packet, raw}, {active, true}]),
spawn(?MODULE, connect, [Listen]).
connect(Listen) ->
{ok, Socket} = gen_tcp:accept(Listen),
spawn(?MODULE, connect, [Listen]),
loop(Socket).
loop(Socket) ->
receive
{tcp, Socket, Data} ->
io:format("1st version received ~p~n", [Data]),
loop(Socket);
{tcp_closed, Socket} ->
io:format("socket closed~n")
end.
client.erl
-module(client).
-export([request/0]).
request() ->
{ok, Socket} = gen_tcp:connect("localhost", 8080, [{packet, raw}, binary]),
gen_tcp:send(Socket, <<"Hello">>).
Starting the server and sending a request creates the expected output.
1> server:start().
<0.62.0>
2> client:request().
ok
1st version received <<"Hello">>
After changing the format statement to "2nd version", compiling and loading the code and executing two requests (because the connect/1 process currently waiting for connections was spawned before the change) the result is still as expected.
3> c(server).
{ok,server}
4> client:request().
ok
1st version received <<"Hello">>
5> client:request().
ok
2nd version received <<"Hello">>
However, after compiling and loading the code twice in a row, there is no output printed in the terminal any more, although the server is obviously still running, since gen_tcp:connect returns a socket.
6> c(server).
{ok,server}
7> c(server).
{ok,server}
8> client:request().
ok
I suspect that this behaviour has something to do with erlang killing all processes with code older than two versions but I fail to really understand what is happening here.
Since this is educational I am more interested in knowing why this exact code doesn't work rather than an actual solution to the problem.
Thanks
erlang
add a comment |
up vote
3
down vote
favorite
up vote
3
down vote
favorite
While trying to understand how to work with servers and hot code loading I stumbled over a problem which I have stripped down to the following code:
server.erl
-module(server).
-export([start/0, connect/1]).
start() ->
{ok, Listen} = gen_tcp:listen(8080, [binary, {packet, raw}, {active, true}]),
spawn(?MODULE, connect, [Listen]).
connect(Listen) ->
{ok, Socket} = gen_tcp:accept(Listen),
spawn(?MODULE, connect, [Listen]),
loop(Socket).
loop(Socket) ->
receive
{tcp, Socket, Data} ->
io:format("1st version received ~p~n", [Data]),
loop(Socket);
{tcp_closed, Socket} ->
io:format("socket closed~n")
end.
client.erl
-module(client).
-export([request/0]).
request() ->
{ok, Socket} = gen_tcp:connect("localhost", 8080, [{packet, raw}, binary]),
gen_tcp:send(Socket, <<"Hello">>).
Starting the server and sending a request creates the expected output.
1> server:start().
<0.62.0>
2> client:request().
ok
1st version received <<"Hello">>
After changing the format statement to "2nd version", compiling and loading the code and executing two requests (because the connect/1 process currently waiting for connections was spawned before the change) the result is still as expected.
3> c(server).
{ok,server}
4> client:request().
ok
1st version received <<"Hello">>
5> client:request().
ok
2nd version received <<"Hello">>
However, after compiling and loading the code twice in a row, there is no output printed in the terminal any more, although the server is obviously still running, since gen_tcp:connect returns a socket.
6> c(server).
{ok,server}
7> c(server).
{ok,server}
8> client:request().
ok
I suspect that this behaviour has something to do with erlang killing all processes with code older than two versions but I fail to really understand what is happening here.
Since this is educational I am more interested in knowing why this exact code doesn't work rather than an actual solution to the problem.
Thanks
erlang
While trying to understand how to work with servers and hot code loading I stumbled over a problem which I have stripped down to the following code:
server.erl
-module(server).
-export([start/0, connect/1]).
start() ->
{ok, Listen} = gen_tcp:listen(8080, [binary, {packet, raw}, {active, true}]),
spawn(?MODULE, connect, [Listen]).
connect(Listen) ->
{ok, Socket} = gen_tcp:accept(Listen),
spawn(?MODULE, connect, [Listen]),
loop(Socket).
loop(Socket) ->
receive
{tcp, Socket, Data} ->
io:format("1st version received ~p~n", [Data]),
loop(Socket);
{tcp_closed, Socket} ->
io:format("socket closed~n")
end.
client.erl
-module(client).
-export([request/0]).
request() ->
{ok, Socket} = gen_tcp:connect("localhost", 8080, [{packet, raw}, binary]),
gen_tcp:send(Socket, <<"Hello">>).
Starting the server and sending a request creates the expected output.
1> server:start().
<0.62.0>
2> client:request().
ok
1st version received <<"Hello">>
After changing the format statement to "2nd version", compiling and loading the code and executing two requests (because the connect/1 process currently waiting for connections was spawned before the change) the result is still as expected.
3> c(server).
{ok,server}
4> client:request().
ok
1st version received <<"Hello">>
5> client:request().
ok
2nd version received <<"Hello">>
However, after compiling and loading the code twice in a row, there is no output printed in the terminal any more, although the server is obviously still running, since gen_tcp:connect returns a socket.
6> c(server).
{ok,server}
7> c(server).
{ok,server}
8> client:request().
ok
I suspect that this behaviour has something to do with erlang killing all processes with code older than two versions but I fail to really understand what is happening here.
Since this is educational I am more interested in knowing why this exact code doesn't work rather than an actual solution to the problem.
Thanks
erlang
erlang
asked Nov 19 at 12:31
Samuel
184
184
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
I am pretty certain this is the two-versions limit.
If you want to confirm that, replace the calls from spawn(...)
to spawn_link(...)
-- if the processes die, your shell will crash as well and you'll know they have been killed.
Another way to test it is whether you can replace the following:
6> c(server).
{ok,server}
7> c(server).
{ok,server}
8> client:request().
ok
By:
6> c(server).
{ok,server}
7> client:request().
ok
8> c(server).
{ok,server}
9> client:request().
ok
If this works fine, the difference is the message in the middle that allows the code to update to a newer code version of the fully-qualified function call (Module:Fun(Args)
), preventing the crash.
Using spawn_link shows the processes getting killed after two updates and it still works, when a message is sent in between. I got confused about which processes are connected, but it is starting to make sense now.
– Samuel
Nov 23 at 9:20
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
I am pretty certain this is the two-versions limit.
If you want to confirm that, replace the calls from spawn(...)
to spawn_link(...)
-- if the processes die, your shell will crash as well and you'll know they have been killed.
Another way to test it is whether you can replace the following:
6> c(server).
{ok,server}
7> c(server).
{ok,server}
8> client:request().
ok
By:
6> c(server).
{ok,server}
7> client:request().
ok
8> c(server).
{ok,server}
9> client:request().
ok
If this works fine, the difference is the message in the middle that allows the code to update to a newer code version of the fully-qualified function call (Module:Fun(Args)
), preventing the crash.
Using spawn_link shows the processes getting killed after two updates and it still works, when a message is sent in between. I got confused about which processes are connected, but it is starting to make sense now.
– Samuel
Nov 23 at 9:20
add a comment |
up vote
1
down vote
accepted
I am pretty certain this is the two-versions limit.
If you want to confirm that, replace the calls from spawn(...)
to spawn_link(...)
-- if the processes die, your shell will crash as well and you'll know they have been killed.
Another way to test it is whether you can replace the following:
6> c(server).
{ok,server}
7> c(server).
{ok,server}
8> client:request().
ok
By:
6> c(server).
{ok,server}
7> client:request().
ok
8> c(server).
{ok,server}
9> client:request().
ok
If this works fine, the difference is the message in the middle that allows the code to update to a newer code version of the fully-qualified function call (Module:Fun(Args)
), preventing the crash.
Using spawn_link shows the processes getting killed after two updates and it still works, when a message is sent in between. I got confused about which processes are connected, but it is starting to make sense now.
– Samuel
Nov 23 at 9:20
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
I am pretty certain this is the two-versions limit.
If you want to confirm that, replace the calls from spawn(...)
to spawn_link(...)
-- if the processes die, your shell will crash as well and you'll know they have been killed.
Another way to test it is whether you can replace the following:
6> c(server).
{ok,server}
7> c(server).
{ok,server}
8> client:request().
ok
By:
6> c(server).
{ok,server}
7> client:request().
ok
8> c(server).
{ok,server}
9> client:request().
ok
If this works fine, the difference is the message in the middle that allows the code to update to a newer code version of the fully-qualified function call (Module:Fun(Args)
), preventing the crash.
I am pretty certain this is the two-versions limit.
If you want to confirm that, replace the calls from spawn(...)
to spawn_link(...)
-- if the processes die, your shell will crash as well and you'll know they have been killed.
Another way to test it is whether you can replace the following:
6> c(server).
{ok,server}
7> c(server).
{ok,server}
8> client:request().
ok
By:
6> c(server).
{ok,server}
7> client:request().
ok
8> c(server).
{ok,server}
9> client:request().
ok
If this works fine, the difference is the message in the middle that allows the code to update to a newer code version of the fully-qualified function call (Module:Fun(Args)
), preventing the crash.
answered Nov 19 at 15:09
I GIVE TERRIBLE ADVICE
7,91022539
7,91022539
Using spawn_link shows the processes getting killed after two updates and it still works, when a message is sent in between. I got confused about which processes are connected, but it is starting to make sense now.
– Samuel
Nov 23 at 9:20
add a comment |
Using spawn_link shows the processes getting killed after two updates and it still works, when a message is sent in between. I got confused about which processes are connected, but it is starting to make sense now.
– Samuel
Nov 23 at 9:20
Using spawn_link shows the processes getting killed after two updates and it still works, when a message is sent in between. I got confused about which processes are connected, but it is starting to make sense now.
– Samuel
Nov 23 at 9:20
Using spawn_link shows the processes getting killed after two updates and it still works, when a message is sent in between. I got confused about which processes are connected, but it is starting to make sense now.
– Samuel
Nov 23 at 9:20
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53374726%2fwhy-dont-i-get-any-terminal-output-after-hot-code-loading-in-erlang%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown