[elephant-devel] A thorny problem....
Robert L. Read
read at robertlread.net
Fri Feb 17 16:20:03 UTC 2006
Yes, this is a great solution. I was fumbling towards it, having
defined "get-transaction-macro-symbol" already,
but you have a much greater command of it. Clearly, something like this
where a completely
back-end specific method accomplishes the "with-transaction" need is the
clean way to go,
and allows for expansion to other back-ends (like a simple file) later.
I completely agree
that having different directories for different back-ends is a very
clean and clarifying way to
handle it.
I would be very grateful if you would do this Ian; I suspect you can do
it faster than I can.
I will support you in anyway possible.
It's not hard to be a maintainer when people such as yourself are so
very helpful!
If you can complete the entire plan you've outlined in 0.6.0, great! If
not, I think if
we can just solve the "transaction problem" (which I think will make us
green on all
of the tests for all of the currently tested implementation), then I
would be happy to
release 0.6.0 at that point. But remember the Inventor's Paradox:
sometimes doing
the more ambitious thing is easier.
Let me know how I can help.
On Fri, 2006-02-17 at 10:50 -0500, Ian Eslick wrote:
> I've been absently noodling over the same problem. I think in general
> we want to factor out the backends more cleanly so we can have a load
> system like that in UCW, Slime, CL-SQL, etc. (multiple backends where
> only one needs to be loaded). Robert has already done much of the work
> toward this with cursors, btrees, etc
>
> One way to handle the transaction macro, although we should think about
> this a bit because it adds a function call cost during short
> transactions and I may also be missing some dependency:
>
> (defmacro with-transaction ((&key store-controller ...) &body body)
> `(execute-store-transaction store-controller
> (lambda (*store-controller* *auto-commit* ...)
> (declare (special *store-controller* *auto-commit*))
> , at body)))
>
> Then for BDB:
>
> (defmethod execute-store-transaction ((store bdb-store-controller) body
> args)
> `(loop
> ....
> (let ((,txn (db-transaction-begin ...insert args...)))
> (catch 'transaction
> (unwind-protect
> (prog1 (funcall body store-controller nil)
> (setq ,success t)
> (db-transaction-success ...)
> (unless ,success
> (db-transaction-abort ...)
> ...))
>
> Don't you just love lisp? This is one of the functions of closures; to
> dynamically manipulate lexical environments without having to do source
> transformations. I think the closure will naturally reference
> external specials like *store-controller* without us needed to pass them
> in the lambda - but passing
> them in the lambda gives us more control over the body of the
> transaction. cl-prevalence did something
> very similar to this (all transaction bodies were named lambdas that
> could be called later to replay
> a transaction).
>
> In this way a backend needs to implement:
> store protocol
> transaction protocol
> btree protocol
> indexed-btree
> btree-index
> cursor protocol
> persistent object protocol (those aux functions you created are a good
> start)
>
> The current implementation of class indexing should come for free, I
> tried to make it backend independant but for performance we might want
> to implement a native protocol later.
>
> The load sequence can be like CL-SQL and UCW: a main load (elephant), to
> define the interface and common functionality followed by a backend load
> (ele-bdb or ele-sqlite3 or ele-postgres). You can also make the backend
> load part of a dispatch list in the (open-store) function. You open a
> store with a keyword specified of :type 'bdb and :spec "/pathname/" and
> that code calls asdf:load-op on the appropriate backend loader.
>
> Ideally each family of backends would have its own subdirectory and
> files to implement the protocols and any other functionality (like
> sleepycat).
>
> I have a pretty good idea of what this should look like and would be
> happy to help do it as part of 0.6.0 as I don't think it's that much
> work if done incrementally and carefully.
>
> Robert, do you want me to take a crack at the transaction fix? I've got
> a great stress test application on my side with lots of rapid
> transactions and some good performance data to compare against.
>
> Anyway, my ten cents...
>
> Ian
>
> Robert L. Read wrote:
> > I think I've a identified a serious problem relating to the
> > the dependencies on various modules that I offer up
> > for you comment.
> >
> > I major goal of the multiple backend system is to allow
> > you to not need to install the software related to the system
> > you don't need. If you want to use BerkeleyDB, you shouldn't have
> > to install CL-SQL. If you want to use CL-SQL and a relational database,
> > you can't shouldn't have to install BerkeleyDB (which would subject
> > you to their license, in any case.)
> >
> > Unfortunately, the "with-transaction" macro, which exists in
> > cl-sql, BDB, and also Elephant, must be in place at compilation
> > time.
> >
> > I have written this macro to take a key argument, and, based on
> > the type of the passed-in store-controller, to resolve either to
> > the CL-SQL with-transaction macro, or the existing with-transaciton
> > macro for BDB.
> >
> > I don't know how to write this macro without having CL-SQL macro
> > loaded (which implies that you have it installed.)
> >
> > I am therefore in a bind:
> > I can't right a generic with-transaction macro without loading CL-SQL,
> > and I can't make you install CL-SQL if you don't want to use it.
> > The macros cannot be treated as functions, (which could easily remain
> > undefined if they did not actually need to be executed), since the
> > "with-transaction" idea cannot possibly be written as a function.
> >
> > I can think of two solutions:
> >
> > 1) Create two asdf systems: one for with clsql, one without. Then
> > it would not be possible or necessary to load "elephant" without
> > choosing a back-end (or a set of back-ends).
> > 2) Alternatively, the loading of the cl-sql module could reload the
> > files with macro in place. This will technically work, but is hideous
> > in the sense that performing a
> > (asdf:operate 'asdf:load-op :ele-clsql)
> > would perform a reloading or a recompilation of more than half the
> > project.
> >
> > Unless someone can provide me some better advice, I'm going to
> > investigate
> > #1.
> >
> > I find all of these dependencies complicated, and macros tend to
> > exacerbate
> > the problem. Perhaps there is a much simpler way of dealing with this
> > that someone can suggest.
> >
> >
> > I must admit that I don't understand how 0.5.0 works, and why only now
> > Ian Eslick's code in the head brings this problem to light.
> >
> >
> > ----
> > Robert L. Read, PhD read &T
> > robertlread.net
> > Consider visiting Progressive Engineering: http://robertlread.net/pe
> > In Austin: 912-8593 "Think
> > globally, Act locally." -- RBF
> >
> >
> > ------------------------------------------------------------------------
> >
> > _______________________________________________
> > elephant-devel site list
> > elephant-devel at common-lisp.net
> > http://common-lisp.net/mailman/listinfo/elephant-devel
> _______________________________________________
> elephant-devel site list
> elephant-devel at common-lisp.net
> http://common-lisp.net/mailman/listinfo/elephant-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/elephant-devel/attachments/20060217/e44e2409/attachment.html>
More information about the elephant-devel
mailing list