Re: Update: "Bogus Handlers" error using the WIRE package: where should error handling condition be applied?
"Denis Papathanasiou" <[email protected]>
| Newsgroups | gmane.lisp.cmucl.general |
|---|---|
| Message-ID | <[email protected]> |
On 3/3/07, Madhu <[email protected]> wrote: > --Multipart_Fri_Mar__2_22:58:12_2007-1 > Content-Type: text/plain; charset=US-ASCII > * "Denis Papathanasiou" <e4044eb40703020617m2d6875dfraa548b47bfbd9678@XXX> : > |> used an MP function in your code. I'd guess your bogus handler > |> messages are from some little tested interaction between MP and the > |> FD-HANDLERS packages. Perhaps you can eliminate the MP:PROCESS and > |> see if you still get the messages? > | > | It's plausible to try it in the interim, to find out whether or not > | that is indeed causing the error, but not using MP in the server > | creates more problems than it solves. > | > | I.e., in a single-threaded mode, when (reload) is busy, none of the > | public methods in the server process will be responsive enough when > | they're invoked by any of the client processes. > | > | Perhaps we should dump WIRE and switch to a model like what you use > | ("use TCP/IP on top of the MP package -- i.e. having a CMUCL > | MP:PROCESS doing a listen, and another to handle each connection."). > | > | Do you have any examples/code snippets of that that you could share? > > I'm attaching a file that sketches this to this message -- I'm > reasonably sure it works, but haven't debugged it. > > |> appropriate in this case, perhaps you can consider wrapping your code > |> inside a HANDLER-BIND that uses INVOKE-RESTART.] > | > | This may sound like a dumb question -- I really need to go back and > | study conditions again -- but if CMUCL is offering a restart that > | solves the problem ("REMOVE-THEM"), then if I were to wrap a > | handler-bind/invoke-restart (where the restart is "REMOVE-THEM") in > | the right place in the server code, then I can go on using WIRE and > | MP, correct? > > I need to double check but your handler could search for the restart > with FIND-RESTART. If found, you can call INVOKE-RESTART in the > handler, cross your fingers, and hope the correct condition is being > handled. If you don't find the restart, just decline to handle the > condition. (return NIL in the handler without transferring control) > -- > Madhu > Thanks very much for the replies and code samples; I'll start with invoke-restart on the current wire mechanism, but if that still doesn't work, I'll try switching to tcp/ip instead. > > --Multipart_Fri_Mar__2_22:58:12_2007-1 > Content-Type: application/octet-stream > Content-Disposition: attachment; filename="bogus-service.lisp" > Content-Transfer-Encoding: 7bit > > ;;; -*- Mode: LISP; Package: :cl-user; BASE: 10; Syntax: ANSI-Common-Lisp; -*- > ;;; > ;;; Touched: Fri Mar 02 20:17:37 2007 -0700 <[email protected]> > ;;; Time-stamp: <07/03/02 20:37:41 madhu> > ;;; > ;;; UNTESTED Sample skeleton code for providing a TCP service with > ;;; CMUCL MP. (Loosely based on Douglas Crosher's CL-HTTP port) > ;;; > (in-package "CL-USER") > > (defvar *bogus-service-invocation-count* 0) > > (defun bogus-service (stream &aux n) > (sleep 5) > (write-string "End of bogus service. You are our " stream) > (write (setq n (incf *bogus-service-invocation-count*)) > :base 10 :stream stream) > (write-string (if (<= 11 (setq n (abs (nth-value 1 (truncate n 100)))) 20) > "th" > (case (nth-value 1 (truncate n 10)) > (1 "st") (2 "nd") (3 "rd") (t "th"))) > stream) > (write-string " satisified customer!" stream) > (terpri stream) > (finish-output stream) > (close stream)) > > (defun make-bogus-tcp-stream (fd) > (sys:make-fd-stream fd :output t :input t :element-type 'character)) > > (defun handle-connection (fd) > (multiple-value-bind (client-address port) > (ext:get-peer-host-and-port fd) > (warn "handle-connection: port=~d client-address=~S" port client-address) > (let ((stream (make-bogus-tcp-stream fd))) > (mp:make-process (lambda () (bogus-service stream)))))) > > (defun listen-for-connections (&optional (port 8128) (interface "127.0.0.1")) > (flet ((listener () > (let (fd) > (unwind-protect > (progn > (setq fd (ext:create-inet-listener > port :stream :host interface ; misnamed in doc > :reuse-address t :backlog 1)) > (warn "listening on ~S:~D fd=~D" interface port fd) > (loop (mp:process-wait-until-fd-usable fd :input) > (let ((new-fd (ext:accept-tcp-connection fd))) > (warn "accepted new-fd=~D" new-fd) > (unix:unix-fcntl new-fd unix:f-setfl unix:fndelay) > (handle-connection new-fd)))) > (when fd (unix:unix-close fd)))))) > (mp:make-process #'listener > :name (format nil "Listener on port ~D" port)))) > > > #|| > (setq $l1 (listen-for-connections)) > ;; clients connect to localhost 3128 > (mp::destroy-process $l1) > ||# > > --Multipart_Fri_Mar__2_22:58:12_2007-1-- > >