[pg-devel] [PATCH] pg-disconnect and abnormal exits
Vladimir Sekissov
svg at surnet.ru
Fri Nov 24 10:31:53 UTC 2006
Good day,
Current implementation of WITH-PG-CONNECTION forces abnormal
connection aborting on any programming error. What about to move
stream handling to PG-DISCONNECT? Here is a possible patch.
In this version PG-DISCONNECT is trying to close connection according
to protocol and only in case of failure or ABORT = T forces stream closing.
Best Regards,
Vladimir Sekissov
diff -Naur --exclude=CVS --exclude='*.fasl' --exclude='*~' pg.orig/utility.lisp pg/utility.lisp
--- pg.orig/utility.lisp 2006-11-21 01:50:36.000000000 +0500
+++ pg/utility.lisp 2006-11-24 15:16:00.000000000 +0500
@@ -36,14 +36,10 @@
CONNECTION. If the connection is unsuccessful, the forms are not
evaluated. Otherwise, the BODY forms are executed, and upon
termination, normal or otherwise, the database connection is closed."
- (let ((ok (gensym)))
- `(let ((,con (pg-connect , at open-args))
- (,ok nil))
- (unwind-protect
- (multiple-value-prog1
- (progn , at body)
- (setf ,ok t))
- (when ,con (pg-disconnect ,con :abort (not ,ok)))))))
+ `(let ((,con (pg-connect , at open-args)))
+ (unwind-protect
+ (progn , at body)
+ (when ,con (pg-disconnect ,con :abort nil)))))
;; this is the old version
#+(or)
@@ -101,4 +97,28 @@
:do (funcall callback (first res)))
(pg-exec conn "CLOSE " cursor))))))
+(defun close-stream (stream &key force)
+ "Close STREAM, if failed and FORCE is T try to close harder.
+Returns T,NIL on success and NIL,ERROR on failer."
+ (let (err)
+ (mapc
+ #'(lambda (attempt)
+ (multiple-value-bind (r e) (ignore-errors (funcall attempt) t)
+ (if r
+ (return-from close-stream (values t nil))
+ (setf err e))))
+ (cons
+ #'(lambda () (close stream))
+ (when force
+ (list
+ #'(lambda () (close stream :abort t))
+ #+cmu
+ #'(lambda ()
+ (unix:unix-close (sys:fd-stream-fd stream)))
+ #+sbcl
+ #'(lambda ()
+ (sb-unix:unix-close (sb-sys:fd-stream-fd stream)))
+ ))))
+ (values nil err)))
+
;; EOF
diff -Naur --exclude=CVS --exclude='*.fasl' --exclude='*~' pg.orig/v2-protocol.lisp pg/v2-protocol.lisp
--- pg.orig/v2-protocol.lisp 2006-11-21 01:50:36.000000000 +0500
+++ pg/v2-protocol.lisp 2006-11-24 15:07:48.000000000 +0500
@@ -238,14 +238,12 @@
(defmethod pg-disconnect ((connection pgcon-v2) &key abort)
- (cond
- (abort
- (close (pgcon-stream connection) :abort t))
- (t
- (write-byte 88 (pgcon-stream connection))
- (%flush connection)
- (close (pgcon-stream connection))))
- (values))
+ (close-stream (pgcon-stream connection)
+ :force (or abort
+ (not (ignore-errors
+ (write-byte 88 (pgcon-stream connection))
+ (%flush connection)
+ t)))))
;; Attribute information is as follows
diff -Naur --exclude=CVS --exclude='*.fasl' --exclude='*~' pg.orig/v3-protocol.lisp pg/v3-protocol.lisp
--- pg.orig/v3-protocol.lisp 2006-11-21 01:50:36.000000000 +0500
+++ pg/v3-protocol.lisp 2006-11-24 15:08:48.000000000 +0500
@@ -642,14 +642,13 @@
(defmethod pg-disconnect ((connection pgcon-v3) &key abort)
- (cond
- (abort
- (close (pgcon-stream connection) :abort t))
- (t
- (send-packet connection #\X nil)
- (%flush connection)
- (close (pgcon-stream connection))))
- (values))
+
+ (close-stream (pgcon-stream connection)
+ :force (or abort
+ (not (ignore-errors
+ (send-packet connection #\X nil)
+ (%flush connection)
+ t)))))
;; Attribute information is as follows
More information about the pg-devel
mailing list