Loading ...
Sorry, an error occurred while loading the content.

Re: apache:session and mod perl

Expand Messages
  • Chris Ochs
    ... If it is a scoping issue it s probably in one of the Apache::Session modules, or maybe I m not supplying all the necessary parameters when using File
    Message 1 of 10 , Dec 30, 2004
    • 0 Attachment
      >
      > > I tried setting Lock to File instead of Null, but there is some sort
      > > of contention issue because after the first request all other requests
      > > hang like they are waiting for a lock to be release.
      >
      > This usually means you have a scoping bug in your code. If the session
      > object never goes out of scope, it will not release the lock.
      >
      If it is a scoping issue it's probably in one of the Apache::Session
      modules, or maybe I'm not supplying all the necessary parameters when
      using File locking with Postgresql. Literally all I did is change
      Lock to File instead of Null and that's it. The session is kept in a
      global request object I use for all variables that need to be passed
      around. In the cleanup handler I untie the session and undefined the
      request object, and log it all with log4perl. If there were scoping
      issues with the global request object, it would show up all over the
      place. I just figured that File locking wasn't supported or tested
      with the Postgresql backend store, so I didn't spend any more time on
      it.


      > Yes, you should not need anything more than the Postgres locking.
      >
      > > I use the default isolation in postgresql.
      >
      > Then it really should be shielding you from this problem. Make sure your
      > scoping is correct (you could throw a warn into the A::S DESTROY() sub to
      > make sure it is getting called) and make sure you are issuing a commit
      > somewhere in there to save your changes.

      SELECT FOR UPDATE doesn't block reads.

      I put in the File backend store with the Transaction argument and it
      puts an exclusive lock on reads, which makes everything work as I
      wanted it to. Now I will go back and look closer at Apache::Session
      and see if the File locking is supported for the Postgresql store.

      Chris

      --
      Report problems: http://perl.apache.org/bugs/
      Mail list info: http://perl.apache.org/maillist/modperl.html
      List etiquette: http://perl.apache.org/maillist/email-etiquette.html
    • Chris Ochs
      ... I put some loggin into apache::session::lock::file, and then switched between using apache::session::file and apache::session::flex with postgres and Lock
      Message 2 of 10 , Dec 30, 2004
      • 0 Attachment
        > > I tried setting Lock to File instead of Null, but there is some sort
        > > of contention issue because after the first request all other requests
        > > hang like they are waiting for a lock to be release.
        >
        > This usually means you have a scoping bug in your code. If the session
        > object never goes out of scope, it will not release the lock.

        I put some loggin into apache::session::lock::file, and then switched
        between using apache::session::file and apache::session::flex with
        postgres and Lock set to File.
        With postgres it calls acquire_read lock a bunch of times in a row
        with an acquire_write_lock thrown in and then something blocks. Using
        apache::session::file it alternates correctly and doesn't do that.
        There has to be some logic in apache::session that is different than
        apache::session::file.

        Here is a log when using apache::session::file. I put the pid in front.

        96836 acquire_read_lock
        96836 acquire_write_lock
        96836 release_all_lock
        96836 DESTROY
        96836 release_all_lock
        96822 acquire_read_lock
        96822 acquire_write_lock
        96822 release_all_lock
        96822 DESTROY
        96822 release_all_lock
        96836 acquire_read_lock
        96836 acquire_write_lock
        96836 release_all_lock
        96836 DESTROY
        96836 release_all_lock

        Here is a log using flex with postgres and Lock set to File.
        96824 acquire_read_lock
        96834 acquire_read_lock
        96826 acquire_read_lock
        96824 acquire_write_lock
        96822 acquire_read_lock


        I'm not sure exactly what pages were being called in the log snippets
        above, but this pattern is always the same.

        Chris

        --
        Report problems: http://perl.apache.org/bugs/
        Mail list info: http://perl.apache.org/maillist/modperl.html
        List etiquette: http://perl.apache.org/maillist/email-etiquette.html
      • Chris Ochs
        I know what s happening now, it dawned on me after I wrote this last night. A deadlock happens when you have an updater that acquires a write lock, but it s
        Message 3 of 10 , Dec 31, 2004
        • 0 Attachment
          I know what's happening now, it dawned on me after I wrote this last night.

          A deadlock happens when you have an updater that acquires a write
          lock, but it's waiting for the first updater that is also in a SELECT
          FOR UPDATE but has not yet acquired a write lock. The first updater
          can't finish because it can't acquire a write lock that the second
          updater has already obtained, and the second updater can't update
          until the first one finishes, which it can't.

          Which also explains why Apache::Session::Flex doesn't list File as one
          of the supported Lock options.

          A workable hack would probably be to have Apache::Session::Lock::File
          always set Transaction to 1 if the backend store was postgres.

          Chris


          On Thu, 30 Dec 2004 23:41:16 -0800, Chris Ochs <snacktime@...> wrote:
          > > > I tried setting Lock to File instead of Null, but there is some sort
          > > > of contention issue because after the first request all other requests
          > > > hang like they are waiting for a lock to be release.
          > >
          > > This usually means you have a scoping bug in your code. If the session
          > > object never goes out of scope, it will not release the lock.
          >
          > I put some loggin into apache::session::lock::file, and then switched
          > between using apache::session::file and apache::session::flex with
          > postgres and Lock set to File.
          > With postgres it calls acquire_read lock a bunch of times in a row
          > with an acquire_write_lock thrown in and then something blocks. Using
          > apache::session::file it alternates correctly and doesn't do that.
          > There has to be some logic in apache::session that is different than
          > apache::session::file.
          >
          > Here is a log when using apache::session::file. I put the pid in front.
          >
          > 96836 acquire_read_lock
          > 96836 acquire_write_lock
          > 96836 release_all_lock
          > 96836 DESTROY
          > 96836 release_all_lock
          > 96822 acquire_read_lock
          > 96822 acquire_write_lock
          > 96822 release_all_lock
          > 96822 DESTROY
          > 96822 release_all_lock
          > 96836 acquire_read_lock
          > 96836 acquire_write_lock
          > 96836 release_all_lock
          > 96836 DESTROY
          > 96836 release_all_lock
          >
          > Here is a log using flex with postgres and Lock set to File.
          > 96824 acquire_read_lock
          > 96834 acquire_read_lock
          > 96826 acquire_read_lock
          > 96824 acquire_write_lock
          > 96822 acquire_read_lock
          >
          > I'm not sure exactly what pages were being called in the log snippets
          > above, but this pattern is always the same.
          >
          > Chris
          >

          --
          Report problems: http://perl.apache.org/bugs/
          Mail list info: http://perl.apache.org/maillist/modperl.html
          List etiquette: http://perl.apache.org/maillist/email-etiquette.html
        • Perrin Harkins
          ... There is no such thing as a write lock for the Postgres subclass. It grabs a lock when you materialize the session and doesn t give it up or try to get
          Message 4 of 10 , Jan 3, 2005
          • 0 Attachment
            On Fri, 2004-12-31 at 09:51 -0800, Chris Ochs wrote:
            > A deadlock happens when you have an updater that acquires a write
            > lock, but it's waiting for the first updater that is also in a SELECT
            > FOR UPDATE but has not yet acquired a write lock.

            There is no such thing as a write lock for the Postgres subclass. It
            grabs a lock when you materialize the session and doesn't give it up or
            try to get another one until the session object is DESTROYed.

            > The first updater
            > can't finish because it can't acquire a write lock that the second
            > updater has already obtained, and the second updater can't update
            > until the first one finishes, which it can't.

            Only one can get a lock on a particular session at once, which is by
            design. There is no deadlock though, since only a single lock is
            involved here.

            > A workable hack would probably be to have Apache::Session::Lock::File
            > always set Transaction to 1 if the backend store was postgres.

            You *really* should not need Apache::Session::Lock::File with Postgres
            if you are not doing anything crazy with Postgres isolation levels and
            transactions. I regret bringing it up now. You need to back up and
            figure out what's going wrong with your Postgres stuff. Are you doing
            commits on this same database handle that would cause the lock to be
            released too early?

            Going back to an earlier mail:
            > If it is a scoping issue it's probably in one of the Apache::Session
            > modules

            I think someone would have found that by now.

            > The session is kept in a
            > global request object I use for all variables that need to be passed
            > around. In the cleanup handler I untie the session and undefined the
            > request object, and log it all with log4perl.

            That should work, but no other request will be able to read the same
            session until your cleanup handler has run.

            > I just figured that File locking wasn't supported or tested
            > with the Postgresql backend store

            It's not.

            > > I put some loggin into apache::session::lock::file, and then switched
            > > between using apache::session::file and apache::session::flex with
            > > postgres and Lock set to File.

            Can you try it with just Postgres?

            - Perrin



            --
            Report problems: http://perl.apache.org/bugs/
            Mail list info: http://perl.apache.org/maillist/modperl.html
            List etiquette: http://perl.apache.org/maillist/email-etiquette.html
          Your message has been successfully submitted and would be delivered to recipients shortly.