1 %%%-------------------------------------------------------------------
6 %%% Created : 25 Mar 2011 by <>
7 %%%-------------------------------------------------------------------
9 -include("makerl.hrl").
11 -behaviour(gen_server
).
17 %% gen_server callbacks
18 -export([init
/1, handle_call
/3, handle_cast
/2, handle_info
/2,
19 terminate
/2, code_change
/3]).
21 -define(TIMEOUT
, infinity
).
25 % The status field could be calculated each time through Hook:build, but a
26 % poorly implemented hook could hang the system, so we considered a hook fulfilled
27 % if it has run once... and thus we need a field.
28 -record(state
, { status
:: status_type(),
30 task_registry
:: tid(),
31 result
:: build_result() }).
33 %%====================================================================
35 %%====================================================================
37 %% @doc Create a new task and register it.
38 -spec
new(tid(), #task
{}) -> {ok
, pid()}.
39 new(TaskRegistry
, Task
) ->
40 gen_server:start_link(?MODULE
, [TaskRegistry
, Task
], []).
42 build_target(TaskRegistry
, Target
) ->
43 {ok
, Pid
} = mkrl_task_registry:find_pid_by_target(TaskRegistry
, Target
),
44 gen_server:call(Pid
, build_target
, ?TIMEOUT
).
46 %%====================================================================
47 %% gen_server callbacks
48 %%====================================================================
50 %%--------------------------------------------------------------------
51 %% Function: init(Args) -> {ok, State} |
52 %% {ok, State, Timeout} |
55 %% Description: Initiates the server
56 %%--------------------------------------------------------------------
57 init([TaskRegistry
, Task
]) ->
58 Hook
= Task#task
.module
,
59 InitialStatus
= Hook:get_status(Task#task
.target
,
60 Task#task
.prerequisites
,
62 mkrl_task_registry:add(TaskRegistry
, Task#task
{ pid = self()}),
63 {ok
, #state
{status
=InitialStatus
,
64 task_registry
= TaskRegistry
,
65 target
= Task#task
.target
,
66 result
= mkrl_dispatcher:unit() }}.
68 %%--------------------------------------------------------------------
69 %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
70 %% {reply, Reply, State, Timeout} |
72 %% {noreply, State, Timeout} |
73 %% {stop, Reason, Reply, State} |
74 %% {stop, Reason, State}
75 %% Description: Handling call messages
76 %%--------------------------------------------------------------------
77 handle_call(build_target
, _From
, State
) ->
78 case State#state
.status
of
79 fulfilled
-> {reply
, State#state
.result
, State
};
80 %% Shouldn't we issue a warning and execute nevertheless?. This should't happen if
81 %% get_status worked properly *and* nothing strange happened...
83 Task
= get_task_from_state(State
),
84 ?
DEBUG("BUILDING: ~p~n", [Task
]),
85 DepResultList
= mkrl_dispatcher:build_dependencies(Task#task
.prerequisites
),
86 AggregatedResult
= mkrl_dispatcher:aggregate_results(DepResultList
),
87 Hook
= Task#task
.module
,
88 Result
= Hook:build(Task#task
.target
, Task#task
.prerequisites
, Task#task
.options
),
89 CombinedResult
= mkrl_dispatcher:combine_result(AggregatedResult
, Result
),
90 {reply
, CombinedResult
, State#state
{ status
= fulfilled
, result
= State#state
.result
} }
93 handle_cast(_Msg
, State
) -> {noreply
, State
}.
94 handle_info(_Info
, State
) -> {noreply
, State
}.
95 terminate(_Reason
, _State
) -> ok
.
96 code_change(_OldVsn
, State
, _Extra
) -> {ok
, State
}.
98 %%--------------------------------------------------------------------
100 %%--------------------------------------------------------------------
101 get_task_from_state(State
) ->
102 {ok
, Task
} = mkrl_task_registry:find_by_target(State#state
.target
),