sessions piling up

83 views
Skip to first unread message

Bob St John

unread,
Aug 9, 2015, 11:15:57 AM8/9/15
to web2py-users
Using 2.12.1

I run a small site... about 200 members who login (some using the 'Remember me for 30 days') plus about 1500 public visitors per day. The sessions are stored in the file system. I run the sessions2trash.py script once a day. I have noticed the sessions are increasing by about 1000 per day which did not seem right. I made the following changes to trash() and now the sessions remaining after being 'trashed' is about 200-300, which seems correct. I think the problem was when a large expiration was saved (30 days) and the next expired public sessions were not trashed....


CURRENT TRASH:
    def trash(self):
        """Trash expired sessions."""
        now = datetime.datetime.now()
        for item in self.get():
            status = 'OK'
            last_visit = item.last_visit_default()

            try:
                session = item.get()
                if session.auth:
                    if session.auth.expiration and not self.force:
                        self.expiration = session.auth.expiration
                    if session.auth.last_visit:
                        last_visit = session.auth.last_visit
            except:
                pass

            age = 0
            if last_visit:
                age = total_seconds(now - last_visit)

            if age > self.expiration or not self.expiration:
                item.delete()
                status = 'trashed'

            if self.verbose > 1:
                print 'key: %s' % str(item)
                print 'expiration: %s seconds' % self.expiration
                print 'last visit: %s' % str(last_visit)
                print 'age: %s seconds' % age
                print 'status: %s' % status
                print ''
            elif self.verbose > 0:
                print('%s %s' % (str(item), status))

MODIFIED TRASH:
    def trash(self):
        """Trash expired sessions."""
        now = datetime.datetime.now()
        for item in self.get():
            status = 'OK'
            last_visit = item.last_visit_default()
            expiration = self.expiration ### added this

            try:
                session = item.get()
                if session.auth:
                    if session.auth.expiration and not self.force:
                        ###self.expiration = session.auth.expiration
                        expiration = session.auth.expiration
                    if session.auth.last_visit:
                        last_visit = session.auth.last_visit
            except:
                pass

            age = 0
            if last_visit:
                age = total_seconds(now - last_visit)

            ###if age > self.expiration or not self.expiration:
            if age > expiration or not expiration:
                item.delete()
                status = 'trashed'

            if self.verbose > 1:
                print 'key: %s' % str(item)
                print 'expiration: %s seconds' % self.expiration
                print 'last visit: %s' % str(last_visit)
                print 'age: %s seconds' % age
                print 'status: %s' % status
                print ''
            elif self.verbose > 0:
                print('%s %s' % (str(item), status))

Massimo Di Pierro

unread,
Aug 10, 2015, 11:44:40 AM8/10/15
to web2py-users
You seem to have an old version of session2strash.py. The new one only uses self.expiration and not expiration.

Bob St John

unread,
Aug 13, 2015, 7:27:20 PM8/13/15
to web2py-users
I am using the latest version of sessions2trash.py as shown in the CURRENT TRASH above. I added counters to see how many sessions were being trashed, and how many were being left alone. This information is included in a reporting task I run every night as well.

The following are the results from the reporting task using the CURRENT TRASH above, as in the latest sessions2trash.py. I only added counters. As you can see the session files are stacking up by about 1000/day.

COMPLETED | start: 2015-08-02 21:31:10 | duration: 55 seconds | output: 6989 ok, 3731 trashed
COMPLETED | start: 2015-08-03 03:05:14 | duration: 38 seconds | output: 7138 ok, 152 trashed
COMPLETED | start: 2015-08-04 03:05:09 | duration: 51 seconds | output: 8040 ok, 495 trashed
COMPLETED | start: 2015-08-05 03:05:17 | duration: 67 seconds | output: 9491 ok, 1120 trashed
COMPLETED | start: 2015-08-06 03:05:09 | duration: 52 seconds | output: 10944 ok, 125 trashed
COMPLETED | start: 2015-08-07 03:05:05 | duration: 60 seconds | output: 11753 ok, 800 trashed
COMPLETED | start: 2015-08-08 03:05:16 | duration: 29 seconds | output: 12709 ok, 404 trashed
COMPLETED | start: 2015-08-09 03:05:05 | duration: 61 seconds | output: 13760 ok, 217 trashed

At this point I modified the sessions2trash.py as shown in the MODIFIED TRASH above. You can see the results are now stable, and what I expect from my site.

COMPLETED | start: 2015-08-09 06:45:19 | duration: 7 seconds | output: 404 ok, 13755 trashed
COMPLETED | start: 2015-08-10 03:05:13 | duration: 10 seconds | output: 160 ok, 1068 trashed
COMPLETED | start: 2015-08-11 03:05:10 | duration: 10 seconds | output: 143 ok, 1743 trashed
COMPLETED | start: 2015-08-12 03:45:07 | duration: 9 seconds | output: 155 ok, 1187 trashed
COMPLETED | start: 2015-08-13 03:45:09 | duration: 6 seconds | output: 146 ok, 930 trashed

Many of our members log on for long expiration (30 days). This is reflected in the 150 or so 'ok' sessions. The trashed sessions are mainly public visitors. When a long expiration was saved to the instance: "self.expiration = session.auth.expiration", any further public sessions would be compared to this long expiration, and would not be trashed. My change "expiration = session.auth.expiration" fixes that.

The following is the modified trash and single loop routines showing the counters and code modifications:

    def trash(self):
        """Trash expired sessions."""
        now = datetime.datetime.now()
        n_ok = 0                    # added 2 counters
        n_trash = 0
        for item in self.get():
            status = 'OK'
            last_visit = item.last_visit_default()
            expiration = self.expiration            # added this

            try:
                session = item.get()
                if session.auth:
                    if session.auth.expiration and not self.force:
                        #self.expiration = session.auth.expiration      # removed this
                        expiration = session.auth.expiration            # added this
                    if session.auth.last_visit:
                        last_visit = session.auth.last_visit
            except:
                pass

            age = 0
            if last_visit:
                age = total_seconds(now - last_visit)

            #if age > self.expiration or not self.expiration:           # removed this
            if age > expiration or not expiration:                      # added this
                item.delete()
                status = 'trashed'
                n_trash += 1                        # count the trashed sessions
            else:
                n_ok += 1                           # count the good sessions left alone

            if self.verbose > 1:
                print 'key: %s' % str(item)
                #print 'expiration: %s seconds' % self.expiration
                print 'expiration: %s seconds' % expiration
                print 'last visit: %s' % str(last_visit)
                print 'age: %s seconds' % age
                print 'status: %s' % status
                print ''
            elif self.verbose > 0:
                print('%s %s' % (str(item), status))
        return (n_ok, n_trash)                      # return the counters


def single_loop(expiration=None, force=False, verbose=False):
    if expiration is None:
        try:
            expiration = auth.settings.expiration
        except:
            expiration = EXPIRATION_MINUTES * 60

    set_files = SessionSetFiles(expiration, force, verbose)
    (n_ok1, n_trash1) = set_files.trash()           # counters for sessions in files
    set_db = SessionSetDb(expiration, force, verbose)
    (n_ok2, n_trash2) = set_db.trash()              # counters for sessions in db
    return (n_ok1+n_ok2, n_trash1+n_trash2)         # return sum of counters to be captured by reporting task




 
Reply all
Reply to author
Forward
0 new messages