Created
October 1, 2010 11:00
-
-
Save mietek/606057 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(code_change_test). | |
% How to use: | |
% | |
% 1. Compile with first st record definition uncommented | |
% | |
% 2. Start several processes: | |
% 1> {ok, Pid1} = code_change_test:start(). | |
% init | |
% {ok,<0.34.0>} | |
% 2> {ok, Pid2} = code_change_test:start(). | |
% init | |
% {ok,<0.36.0>} | |
% | |
% 3. Compile with second st record definition uncommented | |
% Do not use c() as it also purges and loads the code | |
% | |
% 4. Simulate time-consuming processing: | |
% 3> Pid1 ! {sleep, 10000} | |
% | |
% 5. Change all processes: | |
% 4> code_change_test:change_all([Pid1, Pid2], code_change_test, add_b, "b", 15000). | |
% code_change {add_b,{st,"a"},"b"} | |
% added b! {st,"a","b"} | |
% code_change {add_b,{st,"a"},"b"} | |
% added b! {st,"a","b"} | |
% false | |
% | |
% 6. Verify the change took place: | |
% 5> Pid1 ! hello. | |
% handle_info {hello,{st,"a","b"}} | |
% hello | |
% 6> Pid2 ! hello. | |
% handle_info {hello,{st,"a","b"}} | |
% hello | |
-export([change_all/5]). | |
-export([start/0]). | |
-behaviour(gen_server). | |
-export([init/1, | |
handle_call/3, | |
handle_cast/2, | |
handle_info/2, | |
code_change/3, | |
terminate/2]). | |
-record(st, {a :: string()}). | |
% -record(st, {a :: string(), | |
% b :: string()}). | |
% Triggering code_change properly for more than 1 process | |
-spec change_all([pid()], atom(), term(), term(), integer()) -> boolean(). | |
change_all(Pids, Mod, OldVsn, Extra, Timeout) -> | |
[sys:suspend(Pid, Timeout) || Pid <- Pids], | |
c:l(Mod), | |
[sys:change_code(Pid, Mod, OldVsn, Extra) || Pid <- Pids], | |
[sys:resume(Pid) || Pid <- Pids], | |
code:purge(Mod). | |
-spec start() -> {ok, pid()} | {error, term()}. | |
start() -> | |
gen_server:start(?MODULE, [], []). | |
-spec init([]) -> {ok, #st{}}. | |
init([]) -> | |
io:format("init~n", []), | |
St = #st{a = "a"}, | |
{ok, St}. | |
-spec handle_call(term(), term(), #st{}) -> term(). | |
handle_call(Msg, From, #st{} = St) -> | |
io:format("handle_call ~p~n", [{Msg, From, St}]), | |
{reply, ok, St}. | |
-spec handle_cast(term(), #st{}) -> term(). | |
handle_cast(Msg, #st{} = St) -> | |
io:format("handle_cast ~p~n", [{Msg, St}]), | |
{noreply, St}. | |
-spec handle_info(term(), #st{}) -> term(). | |
handle_info(Info, #st{} = St) -> | |
io:format("handle_info ~p~n", [{Info, St}]), | |
case Info of | |
{sleep, Time} -> | |
io:format(" sleeping...~n", []), | |
timer:sleep(Time); | |
_ -> | |
ok | |
end, | |
{noreply, St}. | |
-spec code_change(term(), #st{}, term()) -> {ok, #st{}}. | |
code_change(add_b, OldSt, Extra) -> | |
io:format("code_change ~p~n", [{add_b, OldSt, Extra}]), | |
NewSt = list_to_tuple(tuple_to_list(OldSt) ++ [Extra]), | |
io:format(" added b! ~p~n", [NewSt]), | |
{ok, NewSt}. | |
-spec terminate(term(), #st{}) -> term(). | |
terminate(Reason, #st{} = St) -> | |
io:format("terminate ~p~n", [{Reason, St}]), | |
ok. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment