1 %%%-------------------------------------------------------------------
6 %%% Created : 25 Mar 2011 by <>
7 %%%-------------------------------------------------------------------
9 -include("makerl.hrl").
13 -behaviour(gen_server
).
21 %% gen_server callbacks
22 -export([init
/1, handle_call
/3, handle_cast
/2, handle_info
/2,
23 terminate
/2, code_change
/3]).
25 -define(TIMEOUT
, infinity
).
29 % The status field could be calculated each time through Hook:build, but a
30 % poorly implemented hook could hang the system, so we considered a hook fulfilled
31 % if it has run once... and thus we need a field.
32 -record(state
, { status
:: status_type(),
34 result
:: build_result() }).
36 %%====================================================================
38 %%====================================================================
40 %% @doc Create a new task and register it.
41 -spec
new(string()) -> {ok
, pid()}.
43 gen_server:start_link(?MODULE
, [Target
], []).
45 build_target(Target
) ->
46 {ok
, Pid
} = makerl
.task_registry:find_pid_by_target(Target
),
47 gen_server:call(Pid
, build_target
, ?TIMEOUT
).
49 %%====================================================================
50 %% gen_server callbacks
51 %%====================================================================
53 %%--------------------------------------------------------------------
54 %% Function: init(Args) -> {ok, State} |
55 %% {ok, State, Timeout} |
58 %% Description: Initiates the server
59 %%--------------------------------------------------------------------
61 {ok
, Task
} = makerl
.task_registry:find_by_target(Target
),
62 Hook
= Task#task
.module
,
63 InitialStatus
= Hook:get_status(Target
,
64 Task#task
.prerequisites
,
66 makerl
.task_registry:set_pid(Target
, self()),
67 {ok
, #state
{status
=InitialStatus
,
69 result
= makerl
.dispatcher:unit() }}.
71 %%--------------------------------------------------------------------
72 %% Function: %% handle_call(Request, From, State) -> {reply, Reply, State} |
73 %% {reply, Reply, State, Timeout} |
75 %% {noreply, State, Timeout} |
76 %% {stop, Reason, Reply, State} |
77 %% {stop, Reason, State}
78 %% Description: Handling call messages
79 %%--------------------------------------------------------------------
80 handle_call(build_target
, _From
, State
) ->
81 case State#state
.status
of
82 fulfilled
-> {reply
, State#state
.result
, State
};
83 %% Shouldn't we issue a warning and execute nevertheless?. This should't happen if
84 %% get_status worked properly *and* nothing strange happened...
86 Task
= get_task_from_state(State
),
87 ?
DEBUG("BUILDING: ~p~n", [Task
]),
88 DepResultList
= makerl
.dispatcher:build_dependencies(Task#task
.prerequisites
),
89 AggregatedResult
= makerl
.dispatcher:aggregate_results(DepResultList
),
90 Hook
= Task#task
.module
,
91 Result
= Hook:build(Task#task
.target
, Task#task
.prerequisites
, Task#task
.options
),
92 CombinedResult
= makerl
.dispatcher:combine_result(AggregatedResult
, Result
),
93 {reply
, CombinedResult
, State#state
{ status
= fulfilled
, result
= State#state
.result
} }
96 handle_cast(_Msg
, State
) -> {noreply
, State
}.
97 handle_info(_Info
, State
) -> {noreply
, State
}.
98 terminate(_Reason
, _State
) -> ok
.
99 code_change(_OldVsn
, State
, _Extra
) -> {ok
, State
}.
101 %%--------------------------------------------------------------------
102 %% Internal functions
103 %%--------------------------------------------------------------------
104 get_task_from_state(State
) ->
105 {ok
, Task
} = makerl
.task_registry:find_by_target(State#state
.target
),