[elephant-devel] Bug in GET-CON

Alain Picard Dr.Alain.Picard at gmail.com
Thu Oct 15 04:32:49 UTC 2009


The current version of GET-CON is broken.  The code reads:

    (defmethod get-con ((instance persistent))
      (let ((con (fast-lookup-con-spec (db-spec instance))))
        (cond ((not con)
               (aif (slow-lookup-con-spec (db-spec instance))
                 (progn
                   (setf (db-spec instance)
                         (car (find it *dbconnection-spec* :key #'cdr)))
                   (get-con instance))
                 (restart-case
                     (signal-controller-lost-error instance)
                   (reopen-controller ()
                     :report "Re-open the store controller"
                     (open-controller
                      (get-controller (db-spec instance)))))))
              ;; If it's valid and open
              ((and con (connection-is-indeed-open con))
               con)
              ;; If the controller object exists but is closed, reopen
              (t (open-controller con)))))

    (defun open-store (spec &rest args)
      "Conveniently open a store controller.  Set *store-controller* to the new controller
       unless it is already set (opening a second controller means you must keep track of
       controllers yourself.  *store-controller* is a convenience variable for single-store
       applications or single-store per thread apps.  Multi-store apps should either confine
       their *store-controller* to a given dynamic context or wrap each store-specific op in
       a transaction using with or ensure transaction.  Returns the opened store controller."
      (assert (consp spec))
      ;; Ensure that parameters are set
      (initialize-user-parameters)
      (let ((controller (get-controller spec)))
        (apply #'open-controller controller args)
        (if *store-controller*
            (progn
    ;;	  (warn "Store controller already set so was not updated") ;; this was annoying me
              controller)
            (setq *store-controller* controller))))

Unfortunately OPEN-CONTROLLER has some arguments which can be
very important to set properly; e.g. in

    (defmethod open-controller ((sc bdb-store-controller) &key (recover t)
                                (recover-fatal nil) (thread t) (register nil)
                                (deadlock-detect t)
                                (cache-size elephant::*berkeley-db-cachesize*)
                                (max-locks elephant::*berkeley-db-max-locks*)
                                (max-objects elephant::*berkeley-db-max-objects*)
                                (max-transactions elephant::*berkeley-db-max-transactions*)
                                (mvcc elephant::*default-mvcc*)
                                error-log)

It is imperative that :REGISTER T be passed if one is to properly access
a DB environment from two separate processes (otherwise, each process
gets a DB_RUNRECOVERY error if the other one uses the store.

However you can see from the code that if the controller gets reopened
by GET-CON, it does not apply all of the arguments which are passed to
OPEN-STORE.

I'm currently changing the default value of :REGISTER in OPEN-CONTROLLER
to T in my code, but that's hardly a fix; the bug exists for all other
arguments.

The correct fix involved capturing the ARGS which are required to
properly reopen a store controller.  I'm not sure where those should
be captured (Perhaps as a slot on the store-controller?)  I'm happy to
attempt a fix if someone would confirm that the approach I propose is
likely not to break something else.

   --Alain



--
Please read about why Top Posting
is evil at: http://en.wikipedia.org/wiki/Top-posting
and http://www.dickalba.demon.co.uk/usenet/guide/faq_topp.html
Please read about why HTML in email is evil at: http://www.birdhouse.org/etc/evilmail.html





More information about the elephant-devel mailing list