Yes, this seems reasonable. You can run this job, hitting the cleanup servlet, once a day or any interval you see fit.
For more info: http://groups.google.com/group/google-appengine-java/browse_thread/thread/4f0d9af1c633d39a - Jason On Fri, Sep 11, 2009 at 6:45 PM, Erem <ehb...@gmail.com> wrote: > > Hey Jason, > > Thanks for the clarification. Unfortunately this leaves me at a loss > for how to elegantly clean up dead sessions and manage logged-in > status. Is the only remaining option to put cleanup scripts into a > cronjob? > > > On Sep 11, 6:04 pm, "Jason (Google)" <apija...@google.com> wrote: > > Hi Erum. App Engine doesn't support this callback, so when > sessionDestroyed > > is triggered by the development server, it's not within an active request > > and hence the exception that you're seeing. In the production > environment, > > you would see a similar result if the callback is even triggered at all. > > > > The fact that the development server does trigger sessionDestroyed is a > bug > > in the SDK. Please file a new report in our public tracker, and I'm sorry > > for the bad news. > > > > http://code.google.com/p/googleappengine/issues/list > > > > - Jason > > > > On Fri, Sep 11, 2009 at 3:54 PM, Erem <ehb...@gmail.com> wrote: > > > > > Hi Jason, > > > > > Thanks for the response. I'm seeing it in the development environment. > > > I can't even get ahold of a stack trace in production because the > > > logged events I try to throw just aren't reaching the Logs manager. I > > > do know that it's not working, however, because the object doesn't get > > > inserted in the following code. > > > > > Here's some sample code to show what's happening, and a stack trace of > > > the error it throws > > > > > public class SessionListener implements HttpSessionListener { > > > private static final Logger log = Logger > > > .getLogger("DataNucleus.JDO"); > > > @Override > > > public void sessionCreated(HttpSessionEvent ev) { > > > System.out.println("Session starting"); > > > ev.getSession().setMaxInactiveInterval(2); > > > } > > > > > @Override > > > public void sessionDestroyed(HttpSessionEvent ev) { > > > try { > > > System.out.println("Session ending"); > > > PersistenceManager pm = > > > PMF.get().getPersistenceManager(); > > > System.out.println(pm); > > > PersistMe me = new PersistMe(); > > > me.setName("Erem"); > > > pm.makePersistent(me); > > > pm.close(); > > > System.out.println("Session ended"); > > > } catch (Exception e) { > > > log.log(Level.SEVERE, "Failed in session > cleanup", > > > e); > > > } > > > } > > > } > > > > > This code, when run from the dev server makes this error > > > > > Sep 11, 2009 3:50:53 PM lotr.server.SessionListener sessionDestroyed > > > SEVERE: Failed in session cleanup > > > java.lang.NullPointerException: No API environment is registered for > > > this thread. > > > at > > > com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppId > > > (DatastoreApiHelper.java:63) > > > at > > > > > > com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppIdNamespace > > > (DatastoreApiHelper.java:73) > > > at com.google.appengine.api.datastore.Key.<init>(Key.java:100) > > > at com.google.appengine.api.datastore.Key.<init>(Key.java:85) > > > at com.google.appengine.api.datastore.Key.<init>(Key.java:81) > > > at > com.google.appengine.api.datastore.Entity.<init>(Entity.java:103) > > > at > com.google.appengine.api.datastore.Entity.<init>(Entity.java:84) > > > at org.datanucleus.store.appengine.DatastoreFieldManager.<init> > > > (DatastoreFieldManager.java:167) > > > at > > > > org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject > > > (DatastorePersistenceHandler.java:178) > > > at > org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent > > > (JDOStateManagerImpl.java:3185) > > > at org.datanucleus.state.JDOStateManagerImpl.makePersistent > > > (JDOStateManagerImpl.java:3161) > > > at org.datanucleus.ObjectManagerImpl.persistObjectInternal > > > (ObjectManagerImpl.java:1298) > > > at org.datanucleus.ObjectManagerImpl.persistObject > > > (ObjectManagerImpl.java:1175) > > > at org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent > > > (JDOPersistenceManager.java:669) > > > at org.datanucleus.jdo.JDOPersistenceManager.makePersistent > > > (JDOPersistenceManager.java:694) > > > at > > > lotr.server.SessionListener.sessionDestroyed(SessionListener.java: > > > 26) > > > at > org.mortbay.jetty.servlet.AbstractSessionManager.removeSession > > > (AbstractSessionManager.java:661) > > > at > org.mortbay.jetty.servlet.AbstractSessionManager$Session.timeout > > > (AbstractSessionManager.java:918) > > > at org.mortbay.jetty.servlet.HashSessionManager.scavenge > > > (HashSessionManager.java:200) > > > at org.mortbay.jetty.servlet.HashSessionManager.access$000 > > > (HashSessionManager.java:36) > > > at org.mortbay.jetty.servlet.HashSessionManager$1.run > > > (HashSessionManager.java:144) > > > at java.util.TimerThread.mainLoop(Unknown Source) > > > at java.util.TimerThread.run(Unknown Source) > > > > > On Sep 11, 11:37 am, "Jason (Google)" <apija...@google.com> wrote: > > > > Hi Erum. Are you seeing this error in the development environment or > in > > > > production? > > > > > > - Jason > > > > > > On Wed, Sep 9, 2009 at 5:43 PM, Erem <ehb...@gmail.com> wrote: > > > > > > > Hey All, > > > > > > > What is the best way to tie into session destruction events? > > > > > > > I have implemented an HttpSessionListener and put it in my web.xml. > > > > > The SessionListener gets called, but any attempt to do DataStore or > > > > > URLFetch API calls within sessionDestroyed results in errors. > > > > > > > For example, the JDO API throws: > > > > > > > Exception in thread "Timer-125" java.lang.NullPointerException: No > API > > > > > environment is registered for this thread. > > > > > at > > > > > > com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppId > > > > > (DatastoreApiHelper.java:63) > > > > > at > > > com.google.appengine.api.datastore.QueryTranslator.convertToPb > > > > > (QueryTranslator.java:35) > > > > > > > My app has constructs of "Visitors" (anyone who comes to the site) > and > > > > > "Users" (verified accounts). The former's data get stored in > sessions, > > > > > the latter explicitly in the datastore. > > > > > > > Every User has an ArrayList<Visitor>, listing the visitors > currently > > > > > logged in to the User's account. > > > > > > > When a session is destroyed, meaning a Visitor has left, I want to > > > > > remove that visitor from the user's "Logged in" ArrayList. > > > > > > > Having trouble thinking of another way to do it =( > > > > > > > Any advice would be much appreciated. > > > > > > > Erem > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Google App Engine for Java" group. To post to this group, send email to google-appengine-java@googlegroups.com To unsubscribe from this group, send email to google-appengine-java+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/google-appengine-java?hl=en -~----------~----~----~----~------~----~------~--~---