diff --git a/README.md b/README.md index 6f176c0..436fc4c 100644 --- a/README.md +++ b/README.md @@ -8,22 +8,23 @@ you can get much more information about redis at http://github.com/antirez/redis $ make $ make install - the make install statement will install the redis library into the - $ERL_TOP/lib/ directory (kernel, stdlib also in that directory). - now you can use the redis client in your application. +the make install statement will install the redis library into the +$ERL_TOP/lib/ directory (kernel, stdlib also in that directory). +now you can use the redis client in your application. ## Usage - the redis library has two kinds of modes: - standalone mode: - you can use redis module to everything. first you must setup an connection - with redis server, then you can call commands and get reply from the server. - - application mode: - this mode is working like the standard erlang library. e.g. sasl, crypto, inets. - you must call application:start(redis) when you want to use redis client. - the erl redis application will manager the connections with redis server automatically. - - if you want do some trivial work you had better use standalone mode, it is simple enough. - if you want use redis in production, you had better use application mode. it is so robust - by use erlang OTP. +the redis library has two kinds of modes: + +standalone mode: + you can use redis module to everything. first you must setup an connection + with redis server, then you can call commands and get reply from the server. + +application mode: + this mode is working like the standard erlang library. e.g. sasl, crypto, inets. + you must call application:start(redis) when you want to use redis client. + the erl redis application will manager the connections with redis server automatically. + +if you want do some trivial work you had better use standalone mode, it is simple enough. +if you want use redis in production, you had better use application mode. it is so robust +by use erlang OTP. diff --git a/include/redis.hrl b/include/redis.hrl index 5ae33ae..710ca5e 100644 --- a/include/redis.hrl +++ b/include/redis.hrl @@ -1,6 +1,6 @@ %%%---------------------------------------------------------------------- %%% -%%% @copyright litaocheng@gmail +%%% @copyright erl-redis 2010 %%% %%% @author litaocheng@gmail.com %%% @doc redis client header file @@ -13,6 +13,8 @@ -include_lib("eunit/include/eunit.hrl"). -endif. +-include("redis_log.hrl"). + %% syntax similar with '?:' in c -ifndef(IF). -define(IF(C, T, F), (case (C) of true -> (T); false -> (F) end)). @@ -25,4 +27,6 @@ -define(N2S(N), integer_to_list(N)). -define(S2N(S), list_to_integer(S)). + + -endif. % REDIS_HRL diff --git a/include/redis_log.hrl b/include/redis_log.hrl new file mode 100644 index 0000000..90ba29c --- /dev/null +++ b/include/redis_log.hrl @@ -0,0 +1,71 @@ +%%%---------------------------------------------------------------------- +%%% +%%% @copyright erl-redis 2010 +%%% +%%% @author litaocheng@gmail.com +%%% @doc the log header +%%% +%%%---------------------------------------------------------------------- +-ifndef(REDIS_LOG_HRL). +-define(REDIS_LOG_HRL, ok). + +-ifdef(NOLOG). + -define(DEBUG(F), ok). + -define(DEBUG2(F, D), ok). + + -define(INFO(F), ok). + -define(INFO2(F, D), ok). + + -define(WARN(F), ok). + -define(WARN2(F, D), ok). + + -define(ERROR(F), ok). + -define(ERROR2(F, D), ok). + +-else. + + -ifdef(EUNIT). + + -define(EUNITFMT(T, F, D), (?debugFmt((T) ++ "(~p) " ++ (F), [self()] ++ (D)))). + + -define(DEBUG(F), ?EUNITFMT("[D]", F, [])). + -define(DEBUG2(F, D), ?EUNITFMT("[D]", F, D)). + + -define(INFO(F), ?EUNITFMT("[I]", F, [])). + -define(INFO2(F, D), ?EUNITFMT("[I]", F, D)). + + -define(WARN(F), ?EUNITFMT("[*W*]", F, [])). + -define(WARN2(F, D), ?EUNITFMT("[*W*]", F, D)). + + -define(ERROR(F), ?EUNITFMT("[**E**]", F, [])). + -define(ERROR2(F, D), ?EUNITFMT("[**E**]", F, D)). + + -else. + -define(ML_FMT(F), " (~p:~p) "++(F)). + -define(ML_DATA(D), [?MODLE, ?LINE]++(D)). + + -define(DEBUG(F), + error_logger:info_msg(?ML_FMT("[D]"++F), ?ML_DATA([])). + -define(DEBUG2(F, D), + error_logger:info_msg(?ML_FMT("[D]"++F), ?ML_DATA(D)). + + -define(INFO(F), + error_logger:info_msg(?ML_FMT("[I]"++F), ?ML_DATA([])). + -define(INFO2(F, D), + error_logger:info_msg(?ML_FMT("[I]"++F), ?ML_DATA(D)). + + -define(WARN(F), + error_logger:warning_msg(?ML_FMT("[*W*]"++F), ?ML_DATA([])). + -define(WARN2(F, D), + error_logger:warning_msg(?ML_FMT("[*W*]"++F), ?ML_DATA(D)). + + -define(ERROR(F), + error_logger:error_msg(?ML_FMT("[**E**]"++F), ?ML_DATA([])). + -define(ERROR2(F, D), + error_logger:error_msg(?ML_FMT("[**E**]"++F), ?ML_DATA(D)). + + -endif. %EUNIT + +-endif. %NOLOG + +-endif. % REDIS_LOG_HRL diff --git a/src/Makefile b/src/Makefile index 0ff4422..780812d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -12,11 +12,11 @@ INCLUDE_DIRS := ../include ./ INCLUDE_FILES := $(wildcard ../include/*.hrl) $(wildcard ./*.hrl) EBIN_DIRS := $(wildcard ../libs/*/ebin) -ERLC_FLAGS := -W $(addprefix -I , $(INCLUDE_DIRS)) $(EBIN_DIRS:%=-pa %) +ERLC_FLAGS := -W $(addprefix -I , $(INCLUDE_DIRS)) $(EBIN_DIRS:%=-pa %) + ifdef TEST - ERLC_FLAGS += -DTEST - ERLC_FLAGS += +debug_info #+bin_opt_info + ERLC_FLAGS += -DTEST +debug_info endif ifdef NOLOG @@ -27,6 +27,16 @@ ifdef HIPE ERLC_FLAGS += +native +"{hipe, [o3]}" endif +# in deploy environment, the ctl file set the log dir to /var/log/$APP_NAME +# set the etc dir to /etc/$APP_NAME +ifdef DEPLOY + LOGDIR =/var/log/$(APP_NAME) + CONFDIR =/etc/$(APP_NAME) +else + LOGDIR =./log + CONFDIR =./etc +endif + BASE_DIR := .. EBIN_DIR := ../ebin DOC_DIR = ../edoc @@ -42,14 +52,18 @@ ERL_OBJECTS_LOCAL := $(ERL_SOURCES:%.erl=./%.$(EMULATOR)) APP_TPL_FILES = $(wildcard *.app.src) APP_FILES = $(APP_TPL_FILES:%.src=%) -ALL_FILES = $(ERL_OBJECTS) $(addprefix $(EBIN_DIR)/, $(APP_FILES)) +ALL_FILES = $(ERL_OBJECTS) $(addprefix $(EBIN_DIR)/, $(APP_FILES)) $(EBIN_DIR)/%.app: %.app.src @echo "creating .app file... " - @sed -e 's:@APP_VSN@:$(APP_VSN):g' \ - -e 's:@APP_NAME@:$(APP_NAME):g' \ + @sed -e 's:@APP_NAME@:$(APP_NAME):g' \ + -e 's:@APP_VSN@:$(APP_VSN):g' \ -e 's:@MODULES@:$(ERL_MODULES_IN_APP):g' -e "s:\`:\':g" -e 's/,]/]/g' $< > $@ +$(BASE_DIR)/%ctl: %ctl.tpl + @sed -e 's:@LOGDIR@:$(LOGDIR):g' -e 's:@CONFDIR@:$(CONFDIR):g' $< > $@ + (chmod 775 $@) + $(EBIN_DIR)/%.$(EMULATOR): %.erl $(INCLUDE_FILES) $(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $< @@ -59,4 +73,4 @@ edoc: $(ERL) -noshell -eval "edoc:application($(APP_NAME), \".\", [${DOC_OPTS}]),init:stop()" clean: - (rm -rf ./*.beam; rm -f *.app;) + (rm -rf ./*.beam; rm -rf $(EBIN_DIR)/*.beam; rm -f *.app; rm -f *ctl) diff --git a/src/overview.edoc b/src/overview.edoc new file mode 100644 index 0000000..eeb9151 --- /dev/null +++ b/src/overview.edoc @@ -0,0 +1,7 @@ +** this is the overview.doc file for the application 'erl-redis' ** + +@author litaocheng +@copyright 2010 +@version @VERSION@ +@title Welcome to the `erl-redis' application! +@doc `erl-redis' is an erlang client for redis. diff --git a/src/redis.app.src b/src/redis.app.src index dbbb348..fd0b1e0 100644 --- a/src/redis.app.src +++ b/src/redis.app.src @@ -4,6 +4,7 @@ {modules, [@MODULES@]}, {registered, []}, {applications, [kernel, stdlib]}, + {mod, {redis_app, []}}, {env, []} ] }. diff --git a/src/redis.erl b/src/redis.erl new file mode 100644 index 0000000..a9f3c36 --- /dev/null +++ b/src/redis.erl @@ -0,0 +1,21 @@ +%%%---------------------------------------------------------------------- +%%% +%%% @copyright erl-redis 2010 +%%% +%%% @author litaocheng@gmail.com +%%% @doc the interface for redis +%%% @end +%%% +%%%---------------------------------------------------------------------- +-module(redis). +-author('ltiaocheng@gmail.com'). +-vsn('0.1'). +-include("redis.hrl"). + +-export([i/0]). + + +%% @doc show stats info in the stdout +-spec i() -> 'ok'. +i() -> + ok. diff --git a/src/redis_app.erl b/src/redis_app.erl new file mode 100644 index 0000000..9d6574c --- /dev/null +++ b/src/redis_app.erl @@ -0,0 +1,52 @@ +%%%---------------------------------------------------------------------- +%%% +%%% @copyright erl-redis 2010 +%%% +%%% @author litao cheng +%%% @doc redis app and supervisor callback +%%% @end +%%% +%%%---------------------------------------------------------------------- +-module(redis_app). +-author('litaocheng@gmail.com'). +-vsn('0.1'). +-include("redis.hrl"). + +-behaviour(application). +-behaviour(supervisor). + +-export([start/0]). +-export([start/2, stop/1]). +-export([init/1]). + +-define(MAIN_SUP, redis_sup). + +%% @doc start the application from the erl shell +-spec start() -> 'ok' | {'error', any()}. +start() -> + ?DEBUG2("start the ~p application", [?MODULE]), + application:start(redis). + +%% @doc the application start callback +-spec start(Type :: any(), Args :: any()) -> any(). +start(_Type, _Args) -> + ?INFO2("start the supervisor sup", []), + supervisor:start_link({local, ?MAIN_SUP}, ?MODULE, []). + +%% @doc the application stop callback +stop(_State) -> + ok. + +%% @doc supervisor callback +init(_Args) -> + ?DEBUG2("init supervisor~n", []), + Stragegy = {simple_one_for_one, 10, 10}, + Client = {undefined, {redis_client, start_link, []}, + permanent, 1000, worker, [redis_client]}, + + {ok, {Stragegy, [Client]}}. + +%% +%% internal API +%% + diff --git a/src/redis_client.erl b/src/redis_client.erl new file mode 100644 index 0000000..a061129 --- /dev/null +++ b/src/redis_client.erl @@ -0,0 +1,68 @@ +%%%---------------------------------------------------------------------- +%%% +%%% @copyright erl-redis 2010 +%%% +%%% @author litaocheng +%%% @doc +%%% @end +%%% +%%%---------------------------------------------------------------------- +-module(redis_client). +-author('litaocheng@gmail.com'). +-vsn('0.1'). +-behaviour(gen_server). +-include("redis.hrl"). + +-export([start/0, start_link/0]). + + +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). + +-record(state, { + }). + +-define(SERVER, ?MODULE). + +%% @doc start the redis_sysdata server +-spec start() -> {'ok', any()} | 'ignore' | {'error', any()}. +start() -> + ?DEBUG2("start ~p ~n", [?SERVER]), + gen_server:start({local, ?SERVER}, ?MODULE, [], []). + +%% @doc start_link the redis_sysdata server +-spec start_link() -> {'ok', any()} | 'ignore' | {'error', any()}. +start_link() -> + ?DEBUG2("start_link ~p ~n", [?SERVER]), + gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). + +%% +%% gen_server callbacks +%% +init(_Args) -> + {ok, #state{}}. + +handle_call(_Msg, _From, State) -> + {noreply, State}. + +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_Old, State, _Extra) -> + {ok, State}. + +%%----------------------------------------------------------------------------- +%% +%% internal API +%% +%%----------------------------------------------------------------------------- + +-ifdef(TEST). + +-endif.