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


_______________________________________________
elephant-devel site list
elephant-devel@common-lisp.net
http://common-lisp.net/mailman/listinfo/elephant-devel

Reply via email to