Dear Elephants, I'm trying to understand how one is supposed to recover from store-controller errors, and what the anticipated usage pattern for when to open controllers is. Consider this example:
(with-open-store (*elephant-connection-spec*) (setq u (last-room-update :room nil))) => #<WAITING-ROOM-UPDATE oid:86987> If you then attempt to access a slot on u, you get a CONTROLLER-LOST-ERROR signalled, with a continue restart saying "do you want to reopen": (timestamp u) ==> Condition #<CONTROLLER-LOST-ERROR #x300045D5CD5D> [Condition of type CONTROLLER-LOST-ERROR] Restarts: 0: [CONTINUE] Open a new instance and continue? 1: [RETRY] Retry SLIME REPL evaluation request. 2: [ABORT] Return to SLIME's top level. 3: [ABORT-BREAK] Reset this thread 4: [ABORT] Kill this thread This occurs because WITH-OPEN-STORE has now closed the controller which is referred to in the instance U. Fine. Now, I want to find out how to handle lost controllers, and automatically restart them. I attempted something like this: (handler-bind ((controller-lost-error #'(lambda (c) (describe c) (let ((r (find-restart 'continue c))) (when r (print 'continuing) (invoke-restart r)))))) (timestamp u)) However, that doesn't work because you then get There is no applicable method for the generic function: #<STANDARD-GENERIC-FUNCTION ELEPHANT::PERSISTENT-SLOT-READER #x30004284B1EF> when called with arguments: (NIL #<WAITING-ROOM-UPDATE oid:86987> TIMESTAMP) [Condition of type SIMPLE-ERROR] Restarts: 0: [CONTINUE] Try calling it again 1: [RETRY] Retry SLIME REPL evaluation request. 2: [ABORT] Return to SLIME's top level. 3: [ABORT-BREAK] Reset this thread Trying the RETRY restart at this point _does_ succeed, however. I think it's a bug to encounter this second condition; i.e. I think after the first CONTINUE, when the controller gets successfully re-opened, GET-CON should be able to return the new controller immediately, so that the retried SLOT-VALUE accessor should then succeed. Secondly, and, less important, I think using CERROR/CONTINUE is a bit too generic for this class of error; I think it'd be much friendlier to be able to invoke a specific restart, like REOPEN-LOST-CONTROLLER, so I could write some sort of REOPENING-STORE macro. Maybe I'm missing something basic, here, but the reason I delved into this is that I noticed that opening a new store controller is a HUGELY expensive operation; so an idiom like (defun some-web-responding-method (...) (with-open-store (spec) (with-transaction () (do-stuff)))) ends up being really, really, really slow; almost 1000 times slower than just (open-store spec) (defun some-web-responding-method (...) (with-transaction () (do-stuff))) That's fine - I understand why that is, but the above seems very unsafe. What am I supposed to do or catch if there are store related errors? So I was trying to write something sort of like (defun some-web-responding-method (...) (reopening-store (with-transaction () (do-stuff)))) if you know what I mean. Is this misguided? There a section in the manual about "Design Patterns" and "Multithreaded Web Applications", but it seems very incomplete and I think it should discuss at length these sorts of issues. I guess I'm also unsure of what _other_ sorts of errors might get thrown and how I'm supposed to handle them during "normal" elephant work. A section documenting the responsibilities of the programmer in this area would be invaluable, IMHO. Thanks for any pointers! --Alain Picard -- 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