Session Handler

Home | Getting Started | API | Elements | Actions | Validators | Handlers | Configuration Options | Advanced Guides | Troubleshooting | About

Table of Contents

1 Session Handler

The session handler controls how session information and variables are set, stored, and retrieved. The default configuration uses the process registry to share session state between nodes, and uses a cookie to identify the user with the associated session.

Behavior Functions

init(Config, State)

Initialize the handler

  • Return Value - {ok, NewState}
finish(Config, State)

Clean up the handler

  • Return Value - {ok, NewState}
get_value(Key, DefaultValue, Config, State)

Retrieves the value of session variable associated with Key

  • Key - The key to retrieve
  • DefaultValue - If there is no value set for Key, then return this value
  • Return Value - {ok, Value, NewState}
set_value(Key, Value, Config, State)

Store the value of Value as a session variable with the Key as the identifier. If a value already exists, it's overwritten and the original value is returned.

  • Key - The key to store, any erlang term
  • Value - The value to store as Key
  • Return Value - {ok, OldValue, NewState}
clear_all(Config, State)

Wipe out this session and all associated session variables

  • Return Value - {ok, Newstate}
session_id(Config, State)

Return the unique session identifier.

  • Return Value - {ok, SessionId, NewState}


Here is the complete text of the default session handler

-module (simple_session_handler).
-include_lib ("wf.hrl").
-behaviour (session_handler).
-export ([
-record (state, {unique, node}).

init(_Config, _State) ->
    % Get the session cookie and node...
    Cookie = wf:cookie(get_cookie_name()),
    State = case wf:depickle(Cookie) of
        undefined -> new_state();
        Other -> Other
    {ok, State}.

finish(_Config, State) ->
    % Drop the session cookie...
    Timeout = wf:config_default(session_timeout, 20),
    ok = wf:cookie(get_cookie_name(), wf:pickle(State), "/", Timeout),
    {ok, []}.

get_value(Key, DefaultValue, Config, State) ->
    {ok, Pid} = get_session_pid(Config, State),
    Ref = make_ref(),
    Pid!{get_value, Key, self(), Ref},
    Value = receive
        {ok, undefined, Ref} -> DefaultValue;
        {ok, Other, Ref} -> Other
    {ok, Value, State}.

set_value(Key, Value, Config, State) ->
    {ok, Pid} = get_session_pid(Config, State),
    Ref = make_ref(),
    Pid!{set_value, Key, Value, self(), Ref},
    receive {ok, OldValue, Ref} -> ok end,
    {ok, OldValue, State}.

clear_all(Config, State) ->
    {ok, Pid} = get_session_pid(Config, State),
    Ref = make_ref(),
    Pid!{clear_all, self(), Ref},
    receive {ok, Ref} -> ok end,
    {ok, State}.

session_id(_Config, State) ->
    {ok, SessionId} = wf:hex_encode (State#state.unique),
    {ok, SessionId, State}.


get_cookie_name() ->
    wf:config_default(cookie_name, "newcookie").

get_session_pid(_Config, State) ->
    Timeout = wf:config_default(session_timeout, 20),
    F = fun() -> session_loop([], Timeout) end,
    SessionTag = {session, State#state.unique},
    {ok, _Pid} = process_registry_handler:get_pid(SessionTag, F).

session_loop(Session, Timeout) ->
    %% Timeout in 10 if the session is empty...
    TimeoutMS = case Session == [] of
        true  -> 10 * 1000;
        false -> Timeout * 60 * 1000
        {get_value, Key, Pid, Ref} ->
            Value = case lists:keysearch(Key, 1, Session) of
                {value, {Key, V}} -> V;
                false -> undefined
            Pid!{ok, Value, Ref},
            session_loop(Session, Timeout);

        {set_value, Key, Value, Pid, Ref} ->
            OldValue = case lists:keysearch(Key, 1, Session) of
                {value, {Key, V}} -> V;
                false -> undefined
            Session1 = lists:keystore(Key, 1, Session, {Key, Value}),
            Pid!{ok, OldValue, Ref},
            session_loop(Session1, Timeout);

        {clear_all, Pid, Ref} ->
            Pid!{ok, Ref},
            session_loop([], Timeout)

    after TimeoutMS ->

new_state() ->
    Unique = erlang:md5(term_to_binary({now(), erlang:make_ref()})),
    #state { unique=Unique }.

Date: 2014-11-12 19:50:37 CST

Author: Jesse Gumm (@jessegumm)

Org version 7.8.02 with Emacs version 23

Validate XHTML 1.0


Note:To specify code blocks, just use the generic code block syntax:
<pre><code>your code here</code></pre>

comments powered by Disqus