OK... This question is probably better directed at clojure-dev, but my membership is still pending. I'm having trouble interpreting LockingTransaction.run. Where exactly are read-locks for ensures set? And what precisely is in the commutes map and sets set? Why does membership in sets short-circuit the commutes loop, and what if there is a read lock on a member of the sets set?
Everything is done with the exception of the actual compare and set operation with the BDB database. In other words, the real work. :) Thanks! Alyssa On Sep 1, 6:14 pm, Alyssa Kwan <alyssa.c.k...@gmail.com> wrote: > I'll go one step further and say that we shouldn't have to call > "persist namespace". It should be automatic such that a change to the > state of an identity is transactionally written. > > Let's start with refs. We can tackle the other identities later. > > The API is simple. Call (refp) instead of (ref) when creating a > persisted ref. Passed into the call are a persistence address (file > path, DB connection string, etc.) and a name that has to be unique to > that persistence address. Not all refs end up being referred to by a > top-level symbol in a package, and multi-process systems are hard... > Ensuring uniqueness of name is up to the programmer. Upon creation, > Clojure checks to see if the refp exists in the store; if so it > instantiates in memory with that state, else it uses the default in > the call. > > In a dosync block, the function runs as normal until commit time. > Then Clojure acquires a transactional write lock on each refp that is > alter-ed or ensure-d. It checks the value against memory. If it's > the same, commit data store changes. If not, retry after refreshing > memory with the current contents of the store. If the data store > commit fails, retry a number of times. If the data store commit still > can't proceed, roll back the whole thing. commute and refset are > slightly different, but for an initial implementation, just treat > commute as an alter, and ignore refset. > > Does this make sense? > > My intention is to cover the 80% case. The implementation would > necessarily be chatty, since the API is chatty. That's OK for most > systems. > > This API has the benefit of being able to be shared across Clojure > instances. It's a nice bonus. > > A dosync block may contain symbols pointing to refp's spanning > different data stores, which isn't too hard to handle. It simply > requires that if this is the case, each data store must support two- > phase commit or some other distributed transaction supporting > protocol. For an initial implementation, I would just throw an > exception. > > I've begun working on an implementation using BDB. > > What do people think? > > On Aug 30, 5:02 pm, nchubrich <nchubr...@gmail.com> wrote: > > > > > I'm not aware of any, but +1 for seeing persistence handled as part of > > the language. A big project and a long-term one, to be sure, but > > could it not be considered a goal? > > > In my student days, I was talking to a well-known Lisper (name > > suppressed for fear of Google indexing) about some data structures in > > MIT Scheme. When I asked about saving them to disk, he said in > > effect, "You're on your own----that's something that \should be > > handled, but never is". > > > I think people are so used to this state of affairs they forget how > > ugly it really is. Programming languages are like Moses without > > Joshua: they lead your data in the wilderness, but when it comes to > > finding it a permanent home, you have to talk to someone else. And > > these "someone elses" (who seem to be as numberless as the sons of > > Abraham) each have their own habits and ways of talking. > > > Persistence libraries always end up warping the entire codebase; I've > > never succeeded in keeping them at bay. Using data with Incanter is > > different from ClojureQL, which is different from just using > > contrib.sql, and all of it is different from dealing with just > > Clojure. (I've never even tried Clojure + Hibernate.) You might as > > well rewrite the program from scratch depending on what you use. > > Maybe other people have had better luck; but whatever luck they have, > > I'm sure it is a fight to keep programs abstracted from persistence. > > > I'd like to be able to work with mere Clojure until my program is > > complete, and then work in a completely separate manner on how to read > > and write data. Or maybe there would be off-the-shelf solutions I > > could plug in for different needs: low latency, high read, high write, > > large stores, etc. > > > On the Clojure side, you would simply call something like "persist > > namespace", which would save the state of your current or given > > namespace (unless you pass it the names of variables as well, in which > > case it only saves those). And to read data, you would simply require > > or use it into your namespace: you could choose what granularity to > > give first-class status: just tables, or columns as well, etc. And > > you could do this equally well for XML, JSON, relational data, or a > > graph store; your choice. And the only difference between these and > > ordinary variables would be----heaven forbid!----a disk access might > > happen when you deal with them! > > > To have such a system work well, you would need to enrich the way you > > query Clojure datastructures. I have some ideas on that, but I'd like > > to make sure I'm not shouting in the dark first. > > > I'd like to see a day when programmers need to worry about persistence > > about as much as they worry about garbage collection now. -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en