%%%-------------------------------------------------------------------
%%% @author Jessamine
%%% @copyright (C) 2024, <COMPANY>
%%% @doc
%%%
%%% @end
%%% Created : 28. 8月 2024 23:33
%%%-------------------------------------------------------------------
-module(my_job_center).
-author("Jessamine").
%% API
-export([start_link/0, init/1, work_wanted/0, add_job/1, job_done/1, statistics/0, handle_call/3, handle_cast/2, work_failed/1]).
%%-export([handle_cast/2, handle_info/2, terminate/2, code_change/3]).
start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
add_job(F) -> gen_server:call(?MODULE, {add, F}).
work_wanted() ->
case gen_server:call(?MODULE, get) of
no -> io:format("暂无任务");
{JobNumber, F} ->
F,
job_done(JobNumber)
end.
work_failed(JobNumber) -> gen_server:cast(?MODULE, {failed, JobNumber}).
job_done(JobNumber) -> gen_server:cast(?MODULE, {complete, JobNumber}).
%% 让它报告队列内、进行中和已完成任务的状态
statistics() -> gen_server:call(?MODULE, statistics).
%% 启动服务器
%% 并初始化当前队列的任务数量为0以及任务已经发布到的编号
init([]) -> {ok, ets:new(?MODULE, [])}.
%% State = pending等待,doing正在做,done完成
handle_call({add, F}, _From, Tab) ->
NewJobNumber = case ets:lookup(Tab, job_count) of
[] ->
FirstNumber = 1,
InitIndex = 1,
ets:insert(Tab, {job_count, FirstNumber}),
ets:insert(Tab, {current_job_index, InitIndex}),
FirstNumber;
[{job_count, JobNumber}] ->
JobNumber + 1
end,
ets:insert(Tab, {NewJobNumber, {F, pending}}),
ets:insert(Tab, {job_count, NewJobNumber}),
NewJobNumber,
{reply, NewJobNumber, Tab};
%%获取任务,并将任务状态改为doing
handle_call(get, _From, Tab) ->
Count = case ets:lookup(Tab, job_count) of
[] -> no;
[{job_count, JobCount}] -> JobCount
end,
JobIndex = case ets:lookup(Tab, current_job_index) of
[] -> no;
[{current_job_index, CurrentJobIndex}] -> CurrentJobIndex end,
Reply = if (Count =:= JobIndex) or (Count =:= no) ->
no;
true ->
[{JobIndex, {F, _}}] = ets:lookup(Tab, JobIndex),
ets:insert(Tab, {current_job_index, JobIndex + 1}),
ets:insert(Tab, {JobIndex, {F, doing}}),
{JobIndex, F}
end,
{reply, Reply, Tab};
handle_call(statistics, _From, Tab) ->
KeyValueList = ets:tab2list(Tab),
Reply = get_job_map(KeyValueList),
{reply, Reply, Tab}.
%% 完成任务,并将任务状态改为done
handle_cast({complete, JobNumber}, Tab) ->
case ets:lookup(Tab, JobNumber) of
[] -> not_found;
[{JobNumber, {F, _}}] -> ets:insert(Tab, {JobNumber, {F, done}})
end,
{noreply, Tab}.
%% 执行任务失败,并将任务状态改为pending
%%handle_cast({failed, JobNumber}, , Tab) ->
%% case ets:lookup(Tab, JobNumber) of
%% [] -> not_found;
%% [{JobNumber, {F, _}}] -> ets:insert(Tab, {JobNumber, {F, pending}})
%% end,
%% {noreply, Tab}.
get_job_map(KeyValueList) ->
get_job_map(KeyValueList, #{done_list => [], doing_list => [], pending_list => []}).
get_job_map([], Map) -> Map;
get_job_map([{Key, Value} | T], Map) ->
case is_integer(Key) of
false -> get_job_map(T, Map);
true ->
{F, State} = Value,
NewMap = case State of
done ->
DoneList = maps:get(done_list, Map),
maps:put(done_list, [{Key, F} | DoneList], Map);
doing ->
DoingList = maps:get(doing_list, Map),
maps:put(doing_list, [{Key, F} | DoingList], Map);
pending ->
PendingList = maps:get(pending_list, Map),
maps:put(pending_list, [{Key, F} | PendingList], Map)
end,
get_job_map(T, NewMap)
end.
【无标题】
最新推荐文章于 2024-10-09 22:27:58 发布