Source

chut / src / client.erl

Full commit
%%%===================================================================
%%% The client module is an additional abstraction step over the usr
%%% module, focused on tasks frequently used by a client process.
%%%===================================================================
-module(client).
-export([connect/1, disconnect/2, message/3, listen/2, history/1]).

-define(SESSION_LIFE, 15000).
-define(LISTEN_TIMEOUT, 25000). %% set to 25s; opera dies after 30s.
-define(HISTORY_LIMIT, 10).

%%--------------------------------------------------------------------
%% Function: connect(Id) -> {ok, HandlerId}.
%% Description: Let's a client initiate a connection to some user.
%% If the user doesn't exist, it should be started, otherwise the
%% client connects normally.
%% The client should keep track of the HandlerId as it acts a bit as
%% its session ID for a given user.
%%--------------------------------------------------------------------
connect(Id) ->
    usr:start(Id, ?SESSION_LIFE, ?HISTORY_LIMIT),
    usr:subscribe(Id).

%%--------------------------------------------------------------------
%% Function: disconnect(Id, HandlerId) -> ok
%% Description: Removes a client's listener from a given user.
%%--------------------------------------------------------------------
disconnect(Id, HandlerId) ->
    usr:unsubscribe(Id, HandlerId).

%%--------------------------------------------------------------------
%% Function: message(From, To, Message) -> ok
%% Description: Sends a message from a given user to another one
%%--------------------------------------------------------------------
message(From, To, Message) ->
    usr:message(From, To, Message).

%%--------------------------------------------------------------------
%% Function: listen(Id, HandlerId) -> [Message]
%% Description: Fetches messages belonging to user Id from HandlerId.
%% If the user has been terminated for some reason, there will be
%% an exit exception raised.
%%--------------------------------------------------------------------
listen(Id, HandlerId) ->
    receive
        {{Id, HandlerId}, Msg} -> [Msg | listen1(Id, HandlerId)];
        {gen_event_EXIT, HandlerId, Reason} ->
            case Reason of
                normal -> ok;
                Reason -> exit(Reason)
            end
    after ?LISTEN_TIMEOUT ->
        []
    end.

listen1(Id, HandlerId) ->
    receive
        {{Id, HandlerId}, Msg} -> [Msg | listen1(Id, HandlerId)]
    after 0 ->
        []
    end.

%%--------------------------------------------------------------------
%% Function: history(Id) -> [Message]
%% Description: Fetches previous messages that were routed through
%% the user.
%%--------------------------------------------------------------------
history(Id) -> usr:history(Id).