[rucksack-devel] Re: Rucksack, ECLM

Nikodemus Siivola nikodemus at random-state.net
Wed May 17 15:54:09 UTC 2006


Getting back to this after pulling my head out of my rectum...

"Arthur Lemmens" <alemmens at xs4all.nl> writes:

> Now that I think about it, maybe I don't understand you correctly when
> you say that the younger transaction should be aborted.  I thought that
> you meant that it should be aborted at step 2 in your scenario, but
> maybe you're saying that it should only be aborted at step 3?  *That*
> sounds like it could be a reasonable solution.  It makes use of multiple
> versions as long as possible and comes up with a simple non-locking
> conflict resolution when there really is no other choice left.
> I think I'll go for that, unless you, Luke or Edi has a good reason why
> I shouldn't.  (Luke, do you think this also solves your left-to-right
> vs. right-to-left scenario?  I think that was basically the same thing
> that Nikodemus describes here, but maybe I'm missing something?

I said earlier that this was what I ment, but that is wrong.

Scenario:

 C (counter) has value 0.

 A (transaction) enters.
 A increments C -> 1.
 B (transaction) enters.
 B sees the pristine C (as A hasn't committed yet), and increments it C -> 1.

at this point only one of the two can commit, as their views aren't
consistent anymore. After both have succesfully committed C should b
2.

Since rollbacks are expensive the abort should happen as soon as
possible, and it needs to be B so that younger transactions cannot
starve older ones. Ergo, B should be aborted when it tries to
increment C.

So in this scenario copy-on-write doesn't buy much. :/

(If this was what _you_ ment, then everything is dandy and I was
just being blind.)

Other stuff:

* Rucksacks: There are currently provisions for multiple Rucksacks,
  which I find good, but a single object can only belong to a single 
  Rucksack (which I find good too).

  I am, however, a bit confused on what is the intention in the
  following cases:

    (defclass x () 
      ((y :persistence t :accessor y-of)) 
      (:metaclass persistent-class))

    (let ((x (make-instance 'x)))
      ;; OK so far -- X may is potentially persitent, but not reachable
      ;; from any root-set or index, so no problems.
      (with-rucksack (r *my-rucksack*) 
        (with-transaction () 
          (add-rucksack-root x r)))
      ;; Still OK -- X has been saved, but that's all there is to it...
      ;; Untill we try the following:
      (setf (y-of x) 'y)
      ;; If this works, then I believe the instance in *my-rucksack* should be
      ;; updated -- otherwise persistence is a very precarious thing!
      ;;
      ;; If this fails, then what we have is a "dangling object"... not nice.
      ;;
      ;; In either case, another hairy case follows:
      (with-rucksack (r *other-rucksack*)
         (with-transaction ()           
           (add-rucksack-root x r)))
      ;; ...either this should signal an error because the rucksack is wrong,
      ;; transport the object from *my-rucksack* to *other-rucksack*, or
      ;; multiple Rucksacks per object should be allowed -- in which case
      ;; later pulling X from *my-rucksack* and updating it should also update
      ;; the X in *other-rucksack*.
      ;;
      ;; A combination of the above:
      (with-rucksack (r *my-rucksack*)
        (let (x1)
          (with-transaction ()
            (add-rucksack-root (setf x1 (make-instance 'x))))
          (with-rucksack (r *other-rucksack*)
            (with-tranaction ()
              ;; In which Rucksack is X1?
              (add-rucksack-root (make-instance 'x :y x1) r))))))

  I think there are many valid answers to the questions posed above (and
  the implicit questions about P-EQL in the above cases), but I think they
  boil down mostly to a meta-question:

     Is a single Rucksack a "universe" or a "container"?

  If a Rucksack is a universe, then it would make sense to enforce
  certain restrictions on that universe: eg. you cannot assign objects
  belonging to other universes to persistent slots.

  If a Rucksack is seen as a container, then giving both Rucksacks
  their own copies would be fine, but so (I think) would be allowing
  cross-rucksack references (so that *my-rucksack* could hold a
  pointer to an object in *other-rucksack*).

  In the universe case there is a relatively simple option that might
  untangle some things: make Rucksack a property of a class.

   (defclass foo-class (persistent-class) ()
     (:default-initargs :rucksack "/var/rucksacks/foo/"))

   (defclass foo () (:metaclass foo-class))

   or
  
    (defclass bar () () (:metaclass persisten-class) (:rucksack ...))

  This would have implications on the whole API of course, but most
  that come to mind seem like simplifications -- not all though: eg.
  "What to do with PERSISTENT-DATA?"

* Default transactions: are transactions intended to be explicit,
  or is the intention that eventually a simple (setf some-slot) would
  generate its own transaction unless there already was one?

  There is a pleasing clarity to explicit transactions, but they
  also mean that persistent objects cannot be manipulated by functions
  who don't know they are persistent. 

  I think in at least 90% of the cases it would be natural for the
  called to provide a surrounding transaction contexts, but I'm not
  sure how universal that is.

* GC of live-in-lisp but dead-on-disk objects. I should just read the
  code, I suppose, but what is the intended result here:

    (with-rucksack ...
      (let (x)
         (with-transaction ()
            (setf x (make-instance 'persistent-thing)))
         ... do enough stuff to cause X to be GC'd from
             the file...
         (add-rucksack-root x ...)))

  Does X get a new object-id, or what?

I realize this is long and long-winded. No rush on any of this: I
mostly just wanted to get this downloaded from my head to list
archives. ;-)

Cheers,

  -- Nikodemus              Schemer: "Buddha is small, clean, and serious."
                   Lispnik: "Buddha is big, has hairy armpits, and laughs."



More information about the rucksack-devel mailing list