Re: onSessionStart / onSessionEnd

"kRAkEn/gORe" <[email protected]>
Newsgroups gmane.comp.java.helma.general
Message-ID <[email protected]>
yeah i know, this is the update version.
it works on my side, and a new session ISN't created for every
request. i've tested widely (adding stuff to session.data in the
onSessionStart) and it works ok. i can see it calling on a new request
that don't have a session already allocated, and after the timeout, it
calls the cleanup onSessionEnd. you can't put complex things in that,
but i just needed a function to get told when a new session starts so
i can fill session things up (basically a map engine), and let the map
engine clean up when the session end, freeing up the remaining files
previously allocated by the user

lucio


On 6/6/07, Hannes Wallnoefer <[email protected]> wrote:
> 2007/5/31, kRAkEn/gORe <[email protected]>:
> > just wondering, any possibility to have these added in the repository ?
> > i need to know when a new session is started up and when it is
> > released (freeing any associated maps generated by my map engine).
>
> The problem I see with your patch is that the functions are not
> invoked with the actual session. That's because
> RequestEvaluator.invokeInternal() (and invokeDirectFunction(), which
> would probably be a better choice in this case, because it runs the
> function in the caller thread) only install a dummy session in the JS
> scope (only invokeHttp() uses an actual HTTP user session).
>
> The easiest way to fix this would be to simply pass the session as
> argument to the function.
>
> Apart from that, I'm still unsure about the additional overhead of
> these two callbacks. Helma creates a new session for each request,
> regardless of whether it is actually accessed. I'd really like to get
> an idea about session fluctuation on some real site like antville.org.
>
> What about other users? Does anybody else have a need for these callbacks?
>
> hannes
>
> > thanx
> >
> > _______________________________________________
> > Helma-user mailing list
> > [email protected]
> > http://helma.org/mailman/listinfo/helma-user
> >
> >
> >
> _______________________________________________
> Helma-user mailing list
> [email protected]
> http://helma.org/mailman/listinfo/helma-user
>

_______________________________________________
Helma-user mailing list
[email protected]
http://helma.org/mailman/listinfo/helma-user
SessionManager.java (text/x-java, 8.6 KB)
/*
 * Helma License Notice
 *
 * The contents of this file are subject to the Helma License
 * Version 2.0 (the "License"). You may not use this file except in
 * compliance with the License. A copy of the License is available at
 * http://adele.helma.org/download/helma/license.txt
 *
 * Copyright 1998-2003 Helma Software. All Rights Reserved.
 *
 * $RCSfile: SessionManager.java,v $
 * $Author: hannes $
 * $Revision: 1.5 $
 * $Date: 2006/05/24 12:29:09 $
 */
package helma.framework.core;

import helma.objectmodel.INode;
import helma.objectmodel.db.Node;
import helma.scripting.ScriptingEngine;

import java.util.*;
import java.io.*;

public class SessionManager {

    protected Hashtable sessions;

    protected Application app;

    public SessionManager() {
        sessions = new Hashtable();
    }

    public void init(Application app) {
        this.app = app;
    }

    public void shutdown() {
        sessions.clear();
    }

    public Session createSession(String sessionId) {
        Session session = getSession(sessionId);

        if (session == null) {
            session = new Session(sessionId, app);
            sessions.put(sessionId, session);

            // as first thing, invoke global onSessionStart() function
            RequestEvaluator eval = null;
            try {
                eval = app.getEvaluator();
                SessionBean bean = new SessionBean (session);
                Object[] param = {bean};
                eval.invokeInternal(null, "onSessionBegin", param); // RequestEvaluator.EMPTY_ARGS);
            } catch (Exception xcept) {
                app.logError("Error in onSessionBegin()", xcept);
            } finally {
                app.releaseEvaluator(eval);
            }
        }

        return session;
    }

    public Session getSession(String sessionId) {
        if (sessionId == null)
            return null;

        return (Session) sessions.get(sessionId);
    }

    /**
     *  Return the whole session map. We return a clone of the table to prevent
     * actual changes from the table itself, which is managed by the application.
     * It is safe and allowed to manipulate the session objects contained in the table, though.
     */
    public Map getSessions() {
        return (Map) sessions.clone();
    }

    /**
     * Returns the number of currenty active sessions.
     */
    public int countSessions() {
        return sessions.size();
    }

    /**
     * Remove the session from the sessions-table and logout the user.
     */
    public void discardSession(Session session) {
        logoutSession(session);

        // as first thing, invoke global onSessionStart() function
        RequestEvaluator eval = null;
        try {
            eval = app.getEvaluator();
            eval.invokeInternal(null, "onSessionEnd", RequestEvaluator.EMPTY_ARGS);
        } catch (Exception xcept) {
            app.logError("Error in onSessionEnd()", xcept);
        } finally {
            app.releaseEvaluator(eval);
        }

        sessions.remove(session.getSessionId());
    }

    /**
     * Log in a user given his or her user name and password.
     */
    public boolean loginSession(String uname, String password, Session session) {
        // Check the name/password of a user and log it in to the current session
        if (uname == null) {
            return false;
        }

        uname = uname.toLowerCase().trim();

        if ("".equals(uname)) {
            return false;
        }

        try {
            INode users = app.getUserRoot();
            Node unode = (Node) users.getChildElement(uname);
            String pw = unode.getString("password");

            if ((pw != null) && pw.equals(password)) {
                // let the old user-object forget about this session
                logoutSession(session);
                session.login(unode);

                return true;
            }
        } catch (Exception x) {
            return false;
        }

        return false;
    }

    /**
     * Log out a session from this application.
     */
    public void logoutSession(Session session) {
        session.logout();
    }


    /**
     * Return an array of <code>SessionBean</code> objects currently associated with a given
     * Helma user.
     */
    public List getSessionsForUsername(String username) {
        ArrayList list = new ArrayList();

        if (username == null) {
            return list;
        }

        Enumeration e = sessions.elements();
        while (e.hasMoreElements()) {
            Session s = (Session) e.nextElement();

            if (s != null && username.equals(s.getUID())) {
                // append to list if session is logged in and fits the given username
                list.add(new SessionBean(s));
            }
        }

        return list;
    }

    /**
     * Return a list of Helma nodes (HopObjects -  the database object representing the user,
     *  not the session object) representing currently logged in users.
     */
    public List getActiveUsers() {
        ArrayList list = new ArrayList();

        for (Enumeration e = sessions.elements(); e.hasMoreElements();) {
            Session s = (Session) e.nextElement();

            if (s != null && s.isLoggedIn()) {
                // returns a session if it is logged in and has not been
                // returned before (so for each logged-in user is only added once)
                INode node = s.getUserNode();

                // we check again because user may have been logged out between the first check
                if (node != null && !list.contains(node)) {
                    list.add(node);
                }
            }
        }

        return list;
    }


    /**
     * Dump session state to a file.
     *
     * @param f the file to write session into, or null to use the default sesssion store.
     */
    public void storeSessionData(File f, ScriptingEngine engine) {
        if (f == null) {
            f = new File(app.dbDir, "sessions");
        }

        try {
            OutputStream ostream = new BufferedOutputStream(new FileOutputStream(f));
            ObjectOutputStream p = new ObjectOutputStream(ostream);

            synchronized (sessions) {
                p.writeInt(sessions.size());

                for (Enumeration e = sessions.elements(); e.hasMoreElements();) {
                    try {
                        engine.serialize(e.nextElement(), p);
                        // p.writeObject(e.nextElement());
                    } catch (NotSerializableException nsx) {
                        // not serializable, skip this session
                        app.logError("Error serializing session.", nsx);
                    }
                }
            }

            p.flush();
            ostream.close();
            app.logEvent("stored " + sessions.size() + " sessions in file");
        } catch (Exception e) {
            app.logError("error storing session data.", e);
        }
    }

    /**
     * loads the serialized session table from a given file or from dbdir/sessions
     */
    public void loadSessionData(File f, ScriptingEngine engine) {
        if (f == null) {
            f = new File(app.dbDir, "sessions");
        }

        // compute session timeout value
        int sessionTimeout = 30;

        try {
            sessionTimeout = Math.max(0,
                                      Integer.parseInt(app.getProperty("sessionTimeout",
                                                                         "30")));
        } catch (Exception ignore) {
            System.out.println(ignore.toString());
        }

        long now = System.currentTimeMillis();

        try {
            // load the stored data:
            InputStream istream = new BufferedInputStream(new FileInputStream(f));
            ObjectInputStream p = new ObjectInputStream(istream);
            int size = p.readInt();
            int ct = 0;
            Hashtable newSessions = new Hashtable();

            while (ct < size) {
                Session session = (Session) engine.deserialize(p);

                if ((now - session.lastTouched()) < (sessionTimeout * 60000)) {
                    session.setApp(app);
                    newSessions.put(session.getSessionId(), session);
                }

                ct++;
            }

            p.close();
            istream.close();
            sessions = newSessions;
            app.logEvent("loaded " + newSessions.size() + " sessions from file");
        } catch (FileNotFoundException fnf) {
            // suppress error message if session file doesn't exist
        } catch (Exception e) {
            app.logError("error loading session data.", e);
        }
    }

}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.