Update of /project/cl-prevalence/cvsroot/cl-prevalence/src
In directory common-lisp.net:/tmp/cvs-serv10865/src
Modified Files:
prevalence.lisp
Log Message:
General code cleanup
Added method for snapshot, backup and restore specialized on guarded-prevalence-system that go through the guard thunk
Date: Sun Jun 27 09:37:10 2004
Author: scaekenberghe
Index: cl-prevalence/src/prevalence.lisp
diff -u cl-prevalence/src/prevalence.lisp:1.3 cl-prevalence/src/prevalence.lisp:1.4
--- cl-prevalence/src/prevalence.lisp:1.3 Tue Jun 22 01:37:23 2004
+++ cl-prevalence/src/prevalence.lisp Sun Jun 27 09:37:10 2004
@@ -1,6 +1,6 @@
;;;; -*- mode: Lisp -*-
;;;;
-;;;; $Id: prevalence.lisp,v 1.3 2004/06/22 08:37:23 scaekenberghe Exp $
+;;;; $Id: prevalence.lisp,v 1.4 2004/06/27 16:37:10 scaekenberghe Exp $
;;;;
;;;; Object Prevalence in Common Lisp
;;;;
@@ -122,6 +122,12 @@
()
(:documentation "Thrown by code inside a transaction to indicate that no rollback is needed"))
+(defmethod initiates-rollback ((condition condition))
+ t)
+
+(defmethod initiates-rollback ((no-rollback-error no-rollback-error))
+ nil)
+
;;; Implementation
(defmethod initialize-instance :after ((system prevalence-system) &rest initargs &key &allow-other-keys)
@@ -129,9 +135,10 @@
(declare (ignore initargs))
(with-slots (directory) system
(ensure-directories-exist directory)
- (setf (get-snapshot system) (merge-pathnames (make-pathname :name "snapshot" :type (get-file-extension system))
+ (setf (get-snapshot system) (merge-pathnames (make-pathname :name (get-snapshot-filename system)
+ :type (get-file-extension system))
directory)
- (get-transaction-log system) (merge-pathnames (make-pathname :name "transaction-log"
+ (get-transaction-log system) (merge-pathnames (make-pathname :name (get-transaction-log-filename system)
:type (get-file-extension system))
directory)))
(restore system))
@@ -145,14 +152,14 @@
:if-exists :append)))))
(defmethod close-open-streams ((system prevalence-system) &key abort)
- "Close all open stream associated with system"
+ "Close all open stream associated with system (optionally aborting operations in progress)"
(with-slots (transaction-log-stream) system
(when transaction-log-stream
(close transaction-log-stream :abort abort)
(setf transaction-log-stream nil))))
(defmethod totally-destroy ((system prevalence-system) &key abort)
- "Totally destroy system from permanent storage by deleting any files that we find"
+ "Totally destroy system from permanent storage by deleting any files used by the system, remove all root objects"
(close-open-streams system :abort abort)
(when (probe-file (get-directory system))
(dolist (pathname (directory (merge-pathnames (make-pathname :type (get-file-extension system))
@@ -161,9 +168,10 @@
(clrhash (get-root-objects system)))
(defmethod print-object ((transaction transaction) stream)
- (format stream "#<TRANSACTION ~a ~a>"
- (get-function transaction)
- (or (get-args transaction) "()")))
+ (print-unreadable-object (transaction stream :type t :identity t)
+ (format stream "~a ~a"
+ (get-function transaction)
+ (or (get-args transaction) "()"))))
(defmethod get-root-object ((system prevalence-system) name)
(gethash name (get-root-objects system)))
@@ -190,7 +198,9 @@
(handler-bind ((error #'(lambda (condition)
(when (and (get-option system :rollback-on-error)
(initiates-rollback condition))
- (format t ";; Notice: system rollback/restore due to error (~a)~%" condition)
+ (format *standard-output*
+ ";; Notice: system rollback/restore due to error (~a)~%"
+ condition)
(restore system)))))
(execute-on transaction system)))
(out (get-transaction-log-stream system)))
@@ -203,28 +213,11 @@
"Execute an exclusive query function on a sytem"
(apply function (cons system args)))
-(defmethod execute ((system guarded-prevalence-system) (transaction transaction))
- "Execute a transaction on a sytem controlled by a guard"
- (funcall (get-guard system)
- #'(lambda () (call-next-method system transaction))))
-
-(defmethod query ((system guarded-prevalence-system) function &rest args)
- "Execute an exclusive query function on a sytem controlled by a guard"
- (funcall (get-guard system)
- #'(lambda () (apply function (cons system args)))))
-
(defmethod execute-on ((transaction transaction) (system prevalence-system))
"Execute a transaction itself in the context of a system"
(apply (get-function transaction)
(cons system (get-args transaction))))
-(defun timetag ()
- (multiple-value-bind (second minute hour date month year)
- (decode-universal-time (get-universal-time) 0)
- (format nil
- "~d~2,'0d~2,'0dT~2,'0d~2,'0d~2,'0d"
- year month date hour minute second)))
-
(defmethod snapshot ((system prevalence-system))
"Write to whole system to persistent storage resetting the transaction log"
(let ((timetag (timetag))
@@ -232,14 +225,14 @@
(snapshot (get-snapshot system)))
(close-open-streams system)
(when (probe-file snapshot)
- (copy-file snapshot (merge-pathnames (make-pathname :name (format nil "snapshot-~a" timetag)
+ (copy-file snapshot (merge-pathnames (make-pathname :name (get-snapshot-filename timetag)
:type (get-file-extension system))
snapshot)))
(with-open-file (out snapshot
:direction :output :if-does-not-exist :create :if-exists :supersede)
(funcall (get-serializer system) (get-root-objects system) out *serialization-state*))
(when (probe-file transaction-log)
- (copy-file transaction-log (merge-pathnames (make-pathname :name (format nil "transaction-log-~a" timetag)
+ (copy-file transaction-log (merge-pathnames (make-pathname :name (get-transaction-log-filename timetag)
:type (get-file-extension system))
transaction-log))
(delete-file transaction-log))))
@@ -249,10 +242,10 @@
(let* ((timetag (timetag))
(transaction-log (get-transaction-log system))
(snapshot (get-snapshot system))
- (transaction-log-backup (merge-pathnames (make-pathname :name (format nil "transaction-log-~a" timetag)
+ (transaction-log-backup (merge-pathnames (make-pathname :name (get-transaction-log-filename timetag)
:type (get-file-extension system))
(or directory transaction-log)))
- (snapshot-backup (merge-pathnames (make-pathname :name (format nil "snapshot-~a" timetag)
+ (snapshot-backup (merge-pathnames (make-pathname :name (get-snapshot-filename timetag)
:type (get-file-extension system))
(or directory snapshot))))
(close-open-streams system)
@@ -273,7 +266,9 @@
(let ((position 0))
(handler-bind ((s-xml:xml-parser-error
#'(lambda (condition)
- (format t ";; Warning: error during transaction log restore: ~s~%" condition)
+ (format *standard-output*
+ ";; Warning: error during transaction log restore: ~s~%"
+ condition)
(truncate-file (get-transaction-log system) position)
(return-from restore))))
(with-open-file (in (get-transaction-log system) :direction :input)
@@ -284,6 +279,51 @@
(execute-on transaction system)
(return)))))))))
+(defmethod execute ((system guarded-prevalence-system) (transaction transaction))
+ "Execute a transaction on a system controlled by a guard"
+ (funcall (get-guard system)
+ #'(lambda () (call-next-method system transaction))))
+
+(defmethod query ((system guarded-prevalence-system) function &rest args)
+ "Execute an exclusive query function on a sytem controlled by a guard"
+ (funcall (get-guard system)
+ #'(lambda () (apply function (cons system args)))))
+
+(defmethod snapshot ((system guarded-prevalence-system))
+ "Make a snapshot of a system controlled by a guard"
+ (funcall (get-guard system)
+ #'(lambda () (call-next-method system))))
+
+(defmethod backup ((system guarded-prevalence-system) &key directory)
+ "Do a backup on a system controlled by a guard"
+ (funcall (get-guard system)
+ #'(lambda () (call-next-method system directory))))
+
+(defmethod restore ((system guarded-prevalence-system))
+ "Restore a system controlled by a guard"
+ (funcall (get-guard system)
+ #'(lambda () (call-next-method system))))
+
+;;; Some utilities
+
+(defun timetag (&optional (universal-time (get-universal-time)))
+ "Return a GMT string of universal-time as YYMMDDTHHMMSS"
+ (multiple-value-bind (second minute hour date month year)
+ (decode-universal-time universal-time 0)
+ (format nil
+ "~d~2,'0d~2,'0dT~2,'0d~2,'0d~2,'0d"
+ year month date hour minute second)))
+
+(defmethod get-transaction-log-filename ((system prevalence-system) &optional suffix)
+ "Return the name of the transaction-log filename, optionally using a suffix"
+ (format nil "transaction-log@[-~a]" suffix))
+
+(defmethod get-snapshot-filename ((system prevalence-system) &optional suffix)
+ "Return the name of the snapshot filename, optionally using a suffix"
+ (format nil "snapshot@[-~a]" suffix))
+
+;;; Some file manipulation utilities
+
(defun truncate-file (file position)
"Truncate the physical file at position by copying and replacing it"
(let ((tmp-file (merge-pathnames (concatenate 'string "tmp-" (pathname-name file)) file))
@@ -314,11 +354,7 @@
(write-sequence buffer out :end read-count)
(when (< read-count 4096) (return)))))))
-(defmethod initiates-rollback ((condition condition))
- t)
-
-(defmethod initiates-rollback ((no-rollback-error no-rollback-error))
- nil)
+;;; extra documentation
(setf (documentation 'get-guard 'function) "Access the guard function of a sytem")