Skip to content

Commit ea1d903

Browse files
committed
Restart a woker in ai_balance delay by n milliseconds
1 parent a79fbd1 commit ea1d903

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

src/pool/ai_balance.erl

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
name,
2626
supervisor,
2727
size,
28+
delay,
29+
delay_timers,
2830
workers
2931
}).
3032

@@ -65,13 +67,18 @@ start_link(Name, PoolArgs, WorkerArgs) ->
6567
ignore.
6668
init({Name,PoolArgs, WorkerArgs})->
6769
process_flag(trap_exit, true),
68-
init(PoolArgs,WorkerArgs,#state{name = Name}).
70+
init(PoolArgs,WorkerArgs,#state{
71+
name = Name, delay = 0,
72+
delay_timers = undefined
73+
}).
6974
init([{worker_module, Mod} | Rest], WorkerArgs, #state{name = Name} = State) when is_atom(Mod) ->
7075
%% 该进程挂了,会将所有进程全部挂掉
7176
{ok, Sup} = ai_balance_worker_sup:start_link(Name, Mod,WorkerArgs),
7277
init(Rest, WorkerArgs, State#state{supervisor = Sup});
7378
init([{size, Size} | Rest], WorkerArgs, State) when is_integer(Size) ->
7479
init(Rest, WorkerArgs, State#state{size = Size});
80+
init([{delay,Delay} | Rest], WorkerArgs, State) when is_integer(Delay) ->
81+
init(Rest, WorkerArgs, State#state{delay = Delay, delay_timers = []});
7582
init([_ | Rest], WorkerArgs, State) ->
7683
init(Rest, WorkerArgs, State);
7784
init([], _WorkerArgs, #state{size = Size, supervisor = Sup} = State) ->
@@ -122,15 +129,28 @@ handle_cast(_Request, State) ->
122129
{noreply, NewState :: term(), hibernate} |
123130
{stop, Reason :: normal | term(), NewState :: term()}.
124131

125-
handle_info({'EXIT', Pid, _Reason}, #state{supervisor = Sup} = State) ->
132+
handle_info({'EXIT', Pid, _Reason}, #state{supervisor = Sup, delay = 0, workers = Workers} = State) ->
126133
case lists:member(Pid, State#state.workers) of
127134
true ->
128-
W = lists:filter(fun (P) -> P =/= Pid end, State#state.workers),
135+
W = lists:filter(fun (P) -> P =/= Pid end, Workers),
129136
{noreply, State#state{workers = [new_worker(Sup) | W]}};
130137
false ->
131138
{noreply, State}
132139
end;
133-
140+
handle_info({'EXIT', Pid, _Reason}, #state{delay = Delay, delay_timers = Timers,
141+
workers = Workers} = State)->
142+
case lists:member(Pid, State#state.workers) of
143+
true ->
144+
W = lists:filter(fun (P) -> P =/= Pid end, Workers),
145+
Timer = ai_timer:start(Delay,new_worker,ai_timer:new([async])),
146+
{noreply, State#state{workers = W, delay_timers = [Timer | Timers]}};
147+
false ->
148+
{noreply, State}
149+
end;
150+
handle_info({timeout,TimerRef,new_worker},#state{supervisor = Sup, delay_timers = Timers,
151+
workers = Workers} = State)->
152+
Timers1 = lists:filter(fun(T)-> ai_timer:is_current(TimerRef,T) =/= true end,Timers),
153+
{noreply, State#state{workers = [new_worker(Sup)| Workers], delay_timers = Timers1}};
134154
handle_info(_Info, State) ->
135155
{noreply, State}.
136156

src/stdlib/ai_timer.erl

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,23 @@
44
-export([is_current/2,is_previous/2]).
55

66

7-
-record(ai_timer,{timeout,msg,prev_ref,ref,async,info}).
7+
-record(ai_timer,{
8+
timeout,
9+
msg,
10+
prev_ref,
11+
ref,
12+
async,
13+
info,
14+
abs}).
815

916
new()-> #ai_timer{timeout = infinity,msg = undefined,prev_ref = undefined,
10-
ref = undefined,async = false,info = false}.
17+
ref = undefined,async = false,info = false,abs = false}.
1118
new(Opts) ->
1219
Timer = new(),
1320
lists:foldl(fun(I,Acc)->
1421
if I == info -> Acc#ai_timer{info = true};
1522
I == async -> Acc#ai_timer{async = true};
23+
I == abs -> Acc#ai_timer{abs = true};
1624
true -> Acc
1725
end
1826
end,Timer,Opts).
@@ -25,9 +33,9 @@ cancel_internal(#ai_timer{async = Async,info = Info,ref = Ref} = Timer )->
2533
Timer#ai_timer{prev_ref = Ref,ref = undefined}
2634
end.
2735

28-
start_internal(Timeout,TimeoutMsg,Timer)->
36+
start_internal(Timeout,TimeoutMsg,#ai_timer{ abs = ABS } = Timer)->
2937
Timer1 = cancel_internal(Timer),
30-
Ref = erlang:start_timer(Timeout, self(), TimeoutMsg),
38+
Ref = erlang:start_timer(Timeout, self(), TimeoutMsg,[{abs,ABS}]),
3139
Timer1#ai_timer{timeout = Timeout,msg = TimeoutMsg,ref = Ref}.
3240

3341
check_rule(Timeout,TimeoutMsg)->
@@ -53,4 +61,4 @@ cancel( Timer)-> cancel_internal(Timer).
5361

5462
is_current(Ref,#ai_timer{ref = TRef}) -> Ref == TRef.
5563

56-
is_previous(Ref,#ai_timer{prev_ref = TRef}) -> Ref == TRef.
64+
is_previous(Ref,#ai_timer{prev_ref = TRef}) -> Ref == TRef.

0 commit comments

Comments
 (0)