Current section

Files

Jump to
worker_pool src wpool_time_checker.erl
Raw

src/wpool_time_checker.erl

% This file is licensed to you under the Apache License,
% Version 2.0 (the "License"); you may not use this file
% except in compliance with the License. You may obtain
% a copy of the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing,
% software distributed under the License is distributed on an
% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
% KIND, either express or implied. See the License for the
% specific language governing permissions and limitations
% under the License.
%%% @hidden
-module(wpool_time_checker).
-author('elbrujohalcon@inaka.net').
-behaviour(gen_server).
-record(state, { wpool :: wpool:name()
, handler :: {atom(), atom()}
}).
-type state() :: #state{}.
%% api
-export([ start_link/3
]).
%% gen_server callbacks
-export([ init/1
, terminate/2
, code_change/3
, handle_call/3
, handle_cast/2
, handle_info/2
]).
%%%===================================================================
%%% API
%%%===================================================================
%% @private
-spec start_link(wpool:name(), atom(), {atom(), atom()}) ->
{ok, pid()} | {error, {already_started, pid()} | term()}.
start_link(WPool, Name, Handler) ->
gen_server:start_link({local, Name}, ?MODULE, {WPool, Handler}, []).
%%%===================================================================
%%% init, terminate, code_change, info callbacks
%%%===================================================================
%% @private
-spec init({wpool:name(), {atom(), atom()}}) -> {ok, state()}.
init({WPool, Handler}) -> {ok, #state{wpool = WPool, handler = Handler}}.
%% @private
-spec terminate(atom(), state()) -> ok.
terminate(_Reason, _State) -> ok.
%% @private
-spec code_change(string(), state(), any()) -> {ok, state()}.
code_change(_OldVsn, State, _Extra) -> {ok, State}.
%% @private
-spec handle_cast(term(), state()) -> {noreply, state()}.
handle_cast(_Cast, State) -> {noreply, State}.
-type from() :: {pid(), reference()}.
%% @private
-spec handle_call(term(), from(), state()) -> {reply, ok, state()}.
handle_call(_Call, _From, State) -> {reply, ok, State}.
%%%===================================================================
%%% real (i.e. interesting) callbacks
%%%===================================================================
%% @private
-spec handle_info(any(), state()) -> {noreply, state()}.
handle_info({check, Pid, TaskId, Runtime}, State) ->
case erlang:process_info(Pid, dictionary) of
{dictionary, Values} ->
run_task(
TaskId, proplists:get_value(wpool_task, Values), Pid,
State#state.wpool, State#state.handler, Runtime);
_ -> ok
end,
{noreply, State};
handle_info(_Info, State) -> {noreply, State}.
run_task(TaskId, {TaskId, _, Task}, Pid, Pool, {Mod, Fun}, Runtime) ->
catch Mod:Fun([ {alert, overrun}
, {pool, Pool}
, {worker, Pid}
, {task, Task}
, {runtime, Runtime}
]),
case 2 * Runtime of
NewOverrunTime when NewOverrunTime =< 4294967295 ->
erlang:send_after(
Runtime, self(), {check, Pid, TaskId, NewOverrunTime}),
ok;
_ -> ok
end;
run_task(_TaskId, _Value, _Pid, _Pool, _Handler, _Runtime) -> ok.