From bb333986140ebb8c0bd571919e0de264424a9315 Mon Sep 17 00:00:00 2001 From: Jesse Gumm Date: Thu, 30 Apr 2015 14:31:41 -0500 Subject: [PATCH] Remove dependency on a server Everything just uses application vars and procdict now. --- src/qdate.app.src | 2 +- src/qdate.erl | 38 +--------- src/qdate_app.erl | 20 ------ src/qdate_srv.erl | 174 +++++++++++++++++----------------------------- src/qdate_sup.erl | 32 --------- 5 files changed, 67 insertions(+), 199 deletions(-) delete mode 100644 src/qdate_app.erl delete mode 100644 src/qdate_sup.erl diff --git a/src/qdate.app.src b/src/qdate.app.src index f9eafa2..2f72fb3 100644 --- a/src/qdate.app.src +++ b/src/qdate.app.src @@ -7,6 +7,6 @@ kernel, stdlib ]}, - {mod, { qdate_app, []}}, + {modules, [qdate, qdate_srv]}, {env, []} ]}. diff --git a/src/qdate.erl b/src/qdate.erl index 75d438d..8610597 100644 --- a/src/qdate.erl +++ b/src/qdate.erl @@ -95,10 +95,10 @@ -define(else, true). start() -> - application:start(qdate). + application:load(qdate). stop() -> - application:stop(qdate). + ok. to_string(Format) -> to_string(Format, os:timestamp()). @@ -616,6 +616,7 @@ try_registered_parsers(RawDate) -> try_parsers(_RawDate,[]) -> undefined; try_parsers(RawDate,[{ParserKey,Parser}|Parsers]) -> + io:format("Trying Parser: ~p~n", [ParserKey]), try Parser(RawDate) of {{_,_,_},{_,_,_}} = DateTime -> {DateTime,undefined}; @@ -686,7 +687,6 @@ tz_test_() -> simple_test(SetupData), compare_test(SetupData), tz_tests(SetupData), - test_process_die(SetupData), parser_format_test(SetupData), test_deterministic_parser(SetupData), test_disambiguation(SetupData), @@ -819,38 +819,6 @@ parser_format_test(_) -> ?_assertEqual("2/8/2008 12:00am",to_string(longdate,"2008-02-08 12:00am")), ?_assertEqual("2/8/2008 12:00am",to_string(longdate,"20080208")) ]}. - -test_process_die(_) -> - TZ = "MST", - Caller = self(), - Pid = spawn(fun() -> - set_timezone(TZ), - Caller ! tz_set, - receive tz_set_ack -> ok end, - Caller ! get_timezone() - end), - - PidTZFromOtherProc = receive - tz_set -> - T = get_timezone(Pid), - Pid ! tz_set_ack, - T - after 1000 -> fail - end, - ReceivedTZ = receive - TZ -> TZ - after 2000 -> - fail - end, - - [ - %% Verify we can read the spawned process's TZ from another proc - ?_assertEqual(TZ,PidTZFromOtherProc), - %% Verify the spawned process properly set the TZ - ?_assertEqual(TZ,ReceivedTZ), - %% Verify the now-dead spawned process's TZ is cleared - ?_assertEqual(undefined,get_timezone(Pid)) - ]. arith_tests(_) -> {inorder,[ diff --git a/src/qdate_app.erl b/src/qdate_app.erl deleted file mode 100644 index 757de7e..0000000 --- a/src/qdate_app.erl +++ /dev/null @@ -1,20 +0,0 @@ -% vim: ts=4 sw=4 et -% Copyright (c) 2013 Jesse Gumm -% See LICENSE for licensing information. - --module(qdate_app). - --behaviour(application). - -%% Application callbacks --export([start/2, stop/1]). - -%% =================================================================== -%% Application callbacks -%% =================================================================== - -start(_StartType, _StartArgs) -> - qdate_sup:start_link(). - -stop(_State) -> - ok. diff --git a/src/qdate_srv.erl b/src/qdate_srv.erl index fe7d395..431acde 100644 --- a/src/qdate_srv.erl +++ b/src/qdate_srv.erl @@ -1,22 +1,11 @@ % vim: ts=4 sw=4 et -% Copyright (c) 2013 Jesse Gumm +% Copyright (c) 2013-2015 Jesse Gumm % See LICENSE for licensing information. -module(qdate_srv). --behaviour(gen_server). -define(SRV, ?MODULE). --export([ - start_link/0, - init/1, - handle_call/3, - handle_cast/2, - handle_info/2, - code_change/3, - terminate/2 -]). - -export([ set_timezone/1, set_timezone/2, @@ -37,135 +26,98 @@ get_formats/0 ]). +%% Simple wrappers for unique keys +-define(BASETAG, qdate_var). +-define(KEY(Name), {?BASETAG, Name}). + +-define(TZTAG, qdate_tz). +-define(TZKEY(Name), {?TZTAG, Name}). +-define(PARSERTAG, qdate_parser). +-define(PARSERKEY(Name), {?PARSERTAG, Name}). +-define(FORMATTAG, qdate_format). +-define(FORMATKEY(Name), {?FORMATTAG, Name}). + %% PUBLIC API FUNCTIONS -start_link() -> - gen_server:start_link({local, ?SRV}, ?MODULE, [], []). - set_timezone(TZ) -> - set_timezone(self(),TZ). + put_pd(?TZTAG, TZ). -set_timezone(Key,TZ) -> - ok = gen_server:call(?SRV,{set_timezone,Key,TZ}). +set_timezone(Key, TZ) -> + set_env(?TZKEY(Key), TZ). get_timezone() -> - get_timezone(self()). + get_pd(?TZTAG). get_timezone(Key) -> - gen_server:call(?SRV,{get_timezone,Key}). + get_env(?TZKEY(Key)). clear_timezone() -> - clear_timezone(self()). + unset_pd(?TZTAG). clear_timezone(Key) -> - ok = gen_server:call(?SRV, {clear_timezone, Key}). + unset_env(?TZKEY(Key)). register_parser(Parser) when is_function(Parser,1) -> register_parser(erlang:make_ref(),Parser). register_parser(Key,Parser) when is_function(Parser,1) -> - Key = gen_server:call(?SRV,{register_parser,Key,Parser}). + set_env(?PARSERKEY(Key), Parser). deregister_parser(Key) -> - ok = gen_server:call(?SRV,{deregister_parser,Key}). + unset_env(?PARSERKEY(Key)). deregister_parsers() -> - ok = gen_server:call(?SRV,{deregister_parsers}). + [deregister_parser(Key) || {Key, _} <- get_parsers()]. get_parsers() -> - gen_server:call(?SRV,get_parsers). + get_all_env(?PARSERTAG). -register_format(Key,Format) -> - ok = gen_server:call(?SRV,{register_format,Key,Format}). +register_format(Key, Format) -> + set_env(?FORMATKEY(Key), Format). get_format(Key) -> - gen_server:call(?SRV,{get_format,Key}). + get_env(?FORMATKEY(Key)). deregister_format(Key) -> - ok = gen_server:call(?SRV,{deregister_format,Key}). + unset_env(?FORMATKEY(Key)). get_formats() -> - gen_server:call(?SRV, get_formats). - -%% SERVER FUNCTIONS - --record(state, {tz, parsers, formats}). - -init(_) -> - State = #state{tz=dict:new(),parsers=dict:new(),formats=dict:new()}, - {ok, State}. - -handle_cast(_,State) -> - {noreply, State}. - -handle_info({'DOWN', MonitorRef, process, Pid, _Reason}, State) -> - erlang:demonitor(MonitorRef), - NewTZ = dict:erase(Pid, State#state.tz), - NewParsers = dict:erase(Pid, State#state.parsers), - NewFormats = dict:erase(Pid, State#state.formats), - NewState = State#state{tz=NewTZ, parsers=NewParsers, formats=NewFormats}, - {noreply, NewState }; -handle_info(_, State) -> - {noreply, State}. - -handle_call({set_timezone,Key,TZ}, _From, State) -> - monitor_if_pid(Key), - NewTZ = dict:store(Key, TZ, State#state.tz), - NewState = State#state{tz=NewTZ}, - {reply, ok, NewState}; -handle_call({clear_timezone,Key},_From, State) -> - NewTZ = dict:erase(Key, State#state.tz), - NewState = State#state{tz=NewTZ}, - {reply, ok, NewState}; -handle_call({get_timezone,Key},_From, State) -> - Reply = case dict:find(Key, State#state.tz) of - error -> undefined; - {ok,TZ} -> TZ - end, - {reply, Reply, State}; - -handle_call({register_parser,Key,Parser},_From,State) -> - NewParsers = dict:store(Key, Parser, State#state.parsers), - NewState = State#state{parsers=NewParsers}, - {reply, Key, NewState}; -handle_call(get_parsers,_From,State) -> - Reply = dict:to_list(State#state.parsers), - {reply, Reply, State}; -handle_call({deregister_parser,Key},_From,State) -> - NewParsers = dict:erase(Key, State#state.parsers), - NewState = State#state{parsers=NewParsers}, - {reply, ok, NewState}; -handle_call({deregister_parsers},_From,State) -> - NewState = State#state{parsers=dict:new()}, - {reply, ok, NewState}; - -handle_call({register_format,Key,Format},_From,State) -> - NewFormats = dict:store(Key, Format, State#state.formats), - NewState = State#state{formats=NewFormats}, - {reply, ok, NewState}; -handle_call({get_format,Key},_From,State) -> - Reply = case dict:find(Key, State#state.formats) of - error -> undefined; - {ok, Format} -> Format - end, - {reply, Reply,State}; -handle_call(get_formats,_From,State) -> - Reply = dict:to_list(State#state.formats), - {reply, Reply, State}; -handle_call({deregister_format,Key},_From,State) -> - NewFormats = dict:erase(Key, State#state.formats), - NewState = State#state{formats=NewFormats}, - {reply, ok, NewState}. - -terminate(_Reason, _State) -> - ok. - -code_change(_OldVersion, State, _Extra) -> - {ok, State}. + get_all_env(?FORMATTAG). %% PRIVATE TOOLS -monitor_if_pid(Key) when is_pid(Key) -> - erlang:monitor(process,Key); -monitor_if_pid(_) -> - do_nothing. +%% App Vars + +set_env(Key, Val) -> + application:set_env(qdate, ?KEY(Key), Val). + +get_env(Key) -> + get_env(Key, undefined). + +get_env(Key, Default) -> + %% Soon, this can just be replaced with application:get_env/3 + %% which was introduced in R16B. + case application:get_env(qdate, ?KEY(Key)) of + undefined -> Default; + {ok, Val} -> Val + end. + +unset_env(Key) -> + application:unset_env(qdate, ?KEY(Key)). + +get_all_env(FilterTag) -> + All = application:get_all_env(qdate), + %% Maybe this is a little nasty. + [{Key, V} || {{?BASETAG, {Tag, Key}}, V} <- All, Tag==FilterTag]. + +%% ProcDic Vars + +get_pd(Key) -> + erlang:get(?KEY(Key)). + +put_pd(Key, Val) -> + erlang:put(?KEY(Key), Val), + ok. + +unset_pd(Key) -> + put_pd(Key, undefined). diff --git a/src/qdate_sup.erl b/src/qdate_sup.erl deleted file mode 100644 index 2f47585..0000000 --- a/src/qdate_sup.erl +++ /dev/null @@ -1,32 +0,0 @@ -% vim: ts=4 sw=4 et -% Copyright (c) 2013 Jesse Gumm -% See LICENSE for licensing information. - --module(qdate_sup). - --behaviour(supervisor). - -%% API --export([start_link/0]). - -%% Supervisor callbacks --export([init/1]). - -%% Helper macro for declaring children of supervisor --define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}). - -%% =================================================================== -%% API functions -%% =================================================================== - -start_link() -> - supervisor:start_link({local, ?MODULE}, ?MODULE, []). - -%% =================================================================== -%% Supervisor callbacks -%% =================================================================== - -init([]) -> - Server = ?CHILD(qdate_srv, worker), - {ok, { {one_for_one, 5, 10}, [Server]} }. -