fix micro service
This commit is contained in:
parent
af2891724d
commit
d713c32899
@ -13,6 +13,10 @@
|
|||||||
|
|
||||||
-behaviour(gen_server).
|
-behaviour(gen_server).
|
||||||
|
|
||||||
|
%% 当前微服务的状态
|
||||||
|
-define(STATUS_STOPPED, stopped).
|
||||||
|
-define(STATUS_RUNNING, running).
|
||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start_link/2]).
|
-export([start_link/2]).
|
||||||
-export([get_name/1, get_pid/1, start_service/1, stop_service/1, attach_channel/2]).
|
-export([get_name/1, get_pid/1, start_service/1, stop_service/1, attach_channel/2]).
|
||||||
@ -25,7 +29,9 @@
|
|||||||
%% 通道id信息
|
%% 通道id信息
|
||||||
channel_pid :: pid() | undefined,
|
channel_pid :: pid() | undefined,
|
||||||
%% 当前进程的port信息, OSPid = erlang:port_info(Port, os_pid)
|
%% 当前进程的port信息, OSPid = erlang:port_info(Port, os_pid)
|
||||||
port :: undefined | port()
|
port :: undefined | port(),
|
||||||
|
%% 当前服务的运行状态
|
||||||
|
running_status = ?STATUS_STOPPED
|
||||||
}).
|
}).
|
||||||
|
|
||||||
%%%===================================================================
|
%%%===================================================================
|
||||||
@ -44,9 +50,11 @@ get_pid(ServiceId) when is_binary(ServiceId) ->
|
|||||||
attach_channel(Pid, ChannelPid) when is_pid(Pid), is_pid(ChannelPid) ->
|
attach_channel(Pid, ChannelPid) when is_pid(Pid), is_pid(ChannelPid) ->
|
||||||
gen_server:call(Pid, {attach_channel, ChannelPid}).
|
gen_server:call(Pid, {attach_channel, ChannelPid}).
|
||||||
|
|
||||||
|
-spec start_service(Pid :: pid()) -> ok | {error, Reason :: binary()}.
|
||||||
start_service(Pid) when is_pid(Pid) ->
|
start_service(Pid) when is_pid(Pid) ->
|
||||||
gen_server:call(Pid, start_service).
|
gen_server:call(Pid, start_service).
|
||||||
|
|
||||||
|
-spec stop_service(Pid :: pid()) -> ok | {error, Reason :: binary()}.
|
||||||
stop_service(Pid) when is_pid(Pid) ->
|
stop_service(Pid) when is_pid(Pid) ->
|
||||||
gen_server:call(Pid, stop_service).
|
gen_server:call(Pid, stop_service).
|
||||||
|
|
||||||
@ -65,9 +73,11 @@ start_link(Name, Service = #micro_service{}) when is_atom(Name) ->
|
|||||||
-spec(init(Args :: term()) ->
|
-spec(init(Args :: term()) ->
|
||||||
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
|
{ok, State :: #state{}} | {ok, State :: #state{}, timeout() | hibernate} |
|
||||||
{stop, Reason :: term()} | ignore).
|
{stop, Reason :: term()} | ignore).
|
||||||
init([Service]) ->
|
init([Service = #micro_service{status = Status}]) ->
|
||||||
erlang:start_timer(0, self(), boot_service),
|
%% 数据的状态和运行状态是2回事
|
||||||
{ok, #state{service = Service}}.
|
Status == 1 andalso erlang:start_timer(0, self(), boot_service),
|
||||||
|
|
||||||
|
{ok, #state{service = Service, running_status = ?STATUS_STOPPED}}.
|
||||||
|
|
||||||
%% @private
|
%% @private
|
||||||
%% @doc Handling call messages
|
%% @doc Handling call messages
|
||||||
@ -91,19 +101,32 @@ handle_call({attach_channel, ChannelPid}, _From, State = #state{channel_pid = Ol
|
|||||||
{reply, {error, <<"serivce stopped">>}, State}
|
{reply, {error, <<"serivce stopped">>}, State}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
%% 启动服务
|
%% 启动服务: 当前服务如果正常运行,则重启
|
||||||
handle_call(start_service, _From, State = #state{service = Service = #micro_service{service_id = ServiceId}}) ->
|
handle_call(start_service, _From, State = #state{running_status = RunningStatus, port = Port, service = Service = #micro_service{service_id = ServiceId}}) ->
|
||||||
|
%% 运行中的服务,先停止
|
||||||
|
RunningStatus == ?STATUS_RUNNING andalso stop_port(Port),
|
||||||
|
|
||||||
%% 更新数据库状态
|
%% 更新数据库状态
|
||||||
ok = micro_service_model:start_service(ServiceId),
|
ok = micro_service_model:start_service(ServiceId),
|
||||||
%% 异步启动服务
|
%% 异步启动服务
|
||||||
erlang:start_timer(0, self(), boot_service),
|
case boot_service(Service) of
|
||||||
{reply, ok, State#state{service = Service#micro_service{status = 1}}};
|
{ok, Port} ->
|
||||||
|
{reply, ok, State#state{running_status = ?STATUS_RUNNING, port = Port, service = Service#micro_service{status = 1}}};
|
||||||
|
{error, Reason} ->
|
||||||
|
%% 启动失败不能更新数据库里面的状态
|
||||||
|
{reply, {error, Reason}, State#state{running_status = ?STATUS_STOPPED}}
|
||||||
|
end;
|
||||||
|
|
||||||
%% 停止服务
|
%% 停止服务
|
||||||
handle_call(stop_service, _From, State = #state{port = Port, service = Service = #micro_service{service_id = ServiceId}}) ->
|
handle_call(stop_service, _From, State = #state{running_status = RunningStatus, port = Port, service = Service = #micro_service{service_id = ServiceId}}) ->
|
||||||
ok = micro_service_model:stop_service(ServiceId),
|
case RunningStatus of
|
||||||
stop_port(Port),
|
?STATUS_STOPPED ->
|
||||||
{reply, ok, State#state{port = undefined, service = Service#micro_service{status = 0}}};
|
{reply, {error, <<"service not running">>}, State};
|
||||||
|
?STATUS_RUNNING ->
|
||||||
|
ok = micro_service_model:stop_service(ServiceId),
|
||||||
|
stop_port(Port),
|
||||||
|
{reply, ok, State#state{port = undefined, service = Service#micro_service{status = 0}}}
|
||||||
|
end;
|
||||||
|
|
||||||
handle_call(_Request, _From, State = #state{}) ->
|
handle_call(_Request, _From, State = #state{}) ->
|
||||||
{reply, ok, State}.
|
{reply, ok, State}.
|
||||||
@ -129,20 +152,25 @@ handle_info({timeout, _, boot_service}, State = #state{service = #micro_service{
|
|||||||
handle_info({timeout, _, boot_service}, State = #state{service = Service = #micro_service{service_id = ServiceId, status = 1}}) ->
|
handle_info({timeout, _, boot_service}, State = #state{service = Service = #micro_service{service_id = ServiceId, status = 1}}) ->
|
||||||
case boot_service(Service) of
|
case boot_service(Service) of
|
||||||
{ok, Port} ->
|
{ok, Port} ->
|
||||||
{noreply, State#state{port = Port}};
|
{noreply, State#state{running_status = ?STATUS_RUNNING, port = Port}};
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
lager:debug("[efka_micro_service] service: ~p, boot_service get error: ~p", [ServiceId, Reason]),
|
lager:debug("[efka_micro_service] service: ~p, boot_service get error: ~p", [ServiceId, Reason]),
|
||||||
{noreply, State}
|
{noreply, State#state{running_status = ?STATUS_STOPPED}}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
handle_info({Port, {data, Data}}, State = #state{port = Port, service = Service}) ->
|
handle_info({Port, {data, Data}}, State = #state{port = Port, service = Service}) ->
|
||||||
lager:debug("[efka_micro_service] service_id: ~p, port data: ~p", [Service#micro_service.service_id, Data]),
|
lager:debug("[efka_micro_service] service_id: ~p, port data: ~p", [Service#micro_service.service_id, Data]),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
%% 处理port的消息
|
%% 处理port的消息, Port的被动关闭会触发;因此这个时候的Port和State.port的值是相等的
|
||||||
handle_info({Port, {exit_status, Code}}, State = #state{port = Port, service = Service}) ->
|
handle_info({Port, {exit_status, Code}}, State = #state{port = Port, service = Service}) ->
|
||||||
lager:debug("[efka_micro_service] service_id: ~p, port exit with code: ~p", [Service#micro_service.service_id, Code]),
|
lager:debug("[efka_micro_service] service_id: ~p, port exit with code: ~p", [Service#micro_service.service_id, Code]),
|
||||||
erlang:start_timer(5000, self(), boot_service),
|
erlang:start_timer(5000, self(), boot_service),
|
||||||
|
|
||||||
|
{noreply, State#state{port = undefined}};
|
||||||
|
|
||||||
|
%% 主动关闭的port,不能启动重启的逻辑
|
||||||
|
handle_info({Port, {exit_status, Code}}, State = #state{service = Service}) when is_port(Port) ->
|
||||||
|
lager:debug("[efka_micro_service] service_id: ~p, port close with code: ~p", [Service#micro_service.service_id, Code]),
|
||||||
{noreply, State#state{port = undefined}}.
|
{noreply, State#state{port = undefined}}.
|
||||||
|
|
||||||
%% @private
|
%% @private
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user