From: David
Subject: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <MlVZe.124$VI6.44@fe1.news.blueyonder.co.uk>
Hi all,

I'm developing a common lisp based web application using portable 
allegroserve. I'm using CMUCL 18e on a dedicated Linux server (x86) for 
the production server (connecting using emacs+slime+ssh tunnel - very 
cool) and testing things on OpenMCL on a mac. Recently I've been looking 
into saving a core image and starting from that, but I've run into a 
strange problem.

Initially I tried starting up the lisp application, so that it was 
serving pages, and then doing an (extensioins:save-lisp "core"). When I 
start up from that core, though, I get an error message:-

Error in function common-lisp::handler-descriptors-error:
    (#<Handler for input on BOGUS descriptor 6: #<Closure Over Function 
"defimplementation add-fd-handler"
                                                  {117B17A9}>>) has a 
bad file descriptor.

... which I presume is due to file descriptors (for sockets) not 
surviving the save-core/load-core process, which is not surprising.

So then I tried starting the lisp app to the point just before it starts 
the HTTP server (with (start :port 2001 :listeners 10 ...)) and THEN 
saving the image. When I load the resulting image and then start the 
HTTP server it basically works but seems to suffer a strange slowness in 
serving pages.

I've compared the app started from the image with the one started by 
just loading the lisp files separately and the former seems to take 2-3 
seconds per HTML page (not including images) whilst the latter seems to 
take 1 second, or perhaps less. When serving up a page with images it 
seems to be _really_ slow.

If anyone has any ideas of what could be causing this i'd be very 
grateful. Ideally I'd like to be able to stop the running server (I 
tried the aserve (shutdown) function but it didn't seem to help with 
dumping the image), dump a core image and then resume from that. Failing 
that I'll have to produce the image as a separate build step.

Thanks,

-- David

From: Edi Weitz
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <uachzsqx8.fsf@agharta.de>
On Mon, 26 Sep 2005 16:29:32 GMT, David <······@aaabbbccc.blueyonder.co.uk> wrote:

> I've compared the app started from the image with the one started by
> just loading the lisp files separately and the former seems to take
> 2-3 seconds per HTML page (not including images) whilst the latter
> seems to take 1 second, or perhaps less. When serving up a page with
> images it seems to be _really_ slow.

Maybe it's the usual problem that can be cured with

  (mp::startup-idle-and-top-level-loops).

Another thing that can make CMUCL potentially slow when creating web
pages is *PRINT-PRETTY* which is T by default.

Cheers,
Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: David
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <1127770678.971170.151640@g14g2000cwa.googlegroups.com>
Edi Weitz wrote:
> On Mon, 26 Sep 2005 16:29:32 GMT, David <······@aaabbbccc.blueyonder.co.uk> wrote:
>
> > I've compared the app started from the image with the one started by
> > just loading the lisp files separately and the former seems to take
> > 2-3 seconds per HTML page (not including images) whilst the latter
> > seems to take 1 second, or perhaps less. When serving up a page with
> > images it seems to be _really_ slow.
>
> Maybe it's the usual problem that can be cured with
>
>   (mp::startup-idle-and-top-level-loops).
>
> Another thing that can make CMUCL potentially slow when creating web
> pages is *PRINT-PRETTY* which is T by default.

Brilliant - that fixed it. Everything's working fine now. Thanks Edi.

I have already turned off pretty printing (though I'm using the HTML
generating library from Peter Seibel's book, not the aserve one) but
thanks for the tip.

Does anyone have any idea what I have to do to make a working core
image after starting the aserve HTTP server?

-- David
From: Edi Weitz
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <uwtl3qyt2.fsf@agharta.de>
On 26 Sep 2005 14:37:59 -0700, "David" <······@blueyonder.co.uk> wrote:

> Does anyone have any idea what I have to do to make a working core
> image after starting the aserve HTTP server?

Why do you want to save the image /after/ starting the server?  I have
saved images (with LispWorks) with PortableAllegroServe without
problems but I started the server from the saved image.

Cheers,
Edi.

-- 

Lisp is not dead, it just smells funny.

Real email: (replace (subseq ·········@agharta.de" 5) "edi")
From: David
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <1127772769.156556.182370@g47g2000cwa.googlegroups.com>
Well, if I could do that then I could start the server,
change/debug/enhance it from emacs with slime and then when I was
satisfied shut down the HTTPd part and dump a core image. Then restart
from the core and leave it running again.

In some ways I suppose that might not be good, because it would mean I
could end up not being able to get the thing running properly _without_
the core image.

It just seems a nice thing to do to be able to get the server running,
play about with it and then save it when I'm done. Maybe I've fiddled
with Squeak for just a _little_ too long? :)

-- David
From: Thomas F. Burdick
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <xcvu0g6hnpz.fsf@conquest.OCF.Berkeley.EDU>
[ When you reply to directly to something someone said, please quote them ]

"David" <······@blueyonder.co.uk> writes:

> Well, if I could do that then I could start the server,

["that" being saving an image with allegroserve running]

> change/debug/enhance it from emacs with slime and then when I was
> satisfied shut down the HTTPd part and dump a core image. Then restart
> from the core and leave it running again.

In order to save an image like that, you'll need to shut down anything
listening on a file descriptor that won't be valid when the image
starts again.  Given this error:

  Error in function common-lisp::handler-descriptors-error:
      (#<Handler for input on BOGUS descriptor 6: #<Closure Over Function 
  "defimplementation add-fd-handler"
  						    {117B17A9}>>) has a 
  bad file descriptor.

It looks like the culprit is SLIME.  A brute-force approach to
removing all your soon-to-be-bogus handlers would be:

  (dolist (h lisp::*descriptor-handlers*)
    (when (> (lisp::handler-descriptor h) 2)
      (sys:remove-fd-handler h)))

> In some ways I suppose that might not be good, because it would mean I
> could end up not being able to get the thing running properly _without_
> the core image.
>
> It just seems a nice thing to do to be able to get the server running,
> play about with it and then save it when I'm done. Maybe I've fiddled
> with Squeak for just a _little_ too long? :)

I recommend against using this image-based approach in CL, not because
it doesn't work, but because we don't (at the moment) have the tools
to support it the way that Smalltalk does.  It's fine to use an
image-based approach to development, *as long as* you periodically
check that you can load your system from the on-disk source files,
because those are the golden copy -- unlike with Squeak, we don't have
a way of recovering the source from the running image.

The Smalltalk language makes it easier to write the tools they need to
support the Squeak model of development.  However, even Lisp's macros
don't create an insurmountable problem -- it would be fairly
straightforward to write the development tools we would need, just no
one has.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: David
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <1127821884.095478.212720@g49g2000cwa.googlegroups.com>
OK, thanks. I'll try that way of removing all the handlers later.

I do periodically check that the system loads up from source files on
my local machine (I usually have connections to these 2 separate
systems from emacs), which I need to do anyway since I don't want to
have to shut down the 'live' one if I update stuff. The production lisp
system has been running since the 7th of September, but I'm pretty
confident that it will start up again if the machine reboots or
something (ah the joys of tempting fate!).

I'm still trying to decide whether there is any point at all in trying
to dump an image from a running server or whether it's better to make a
lisp script which loads everything and dumps an image, and then another
lisp script which starts the server up when run from that image. That
probably makes more sense I suppose.

-- David
From: Paul Wallich
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <dhbiff$h98$1@reader1.panix.com>
David wrote:
> OK, thanks. I'll try that way of removing all the handlers later.
> 
> I do periodically check that the system loads up from source files on
> my local machine (I usually have connections to these 2 separate
> systems from emacs), which I need to do anyway since I don't want to
> have to shut down the 'live' one if I update stuff. The production lisp
> system has been running since the 7th of September, but I'm pretty
> confident that it will start up again if the machine reboots or
> something (ah the joys of tempting fate!).
> 
> I'm still trying to decide whether there is any point at all in trying
> to dump an image from a running server or whether it's better to make a
> lisp script which loads everything and dumps an image, and then another
> lisp script which starts the server up when run from that image. That
> probably makes more sense I suppose.

Dumping an image from a running server is a little like dumping an image 
of a car in gear. That's not generally the state you want to start up 
in. You can set things up so that the running image doesn't have any 
state that would confuse it when it comes back into existence at another 
time on another system, but doing all the startup explicitly is probably 
a better idea.

paul
From: Pascal Bourguignon
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <87y85iikky.fsf@thalassa.informatimago.com>
Paul Wallich <··@panix.com> writes:
> Dumping an image from a running server is a little like dumping an
> image of a car in gear. That's not generally the state you want to
> start up in. You can set things up so that the running image doesn't
> have any state that would confuse it when it comes back into existence
> at another time on another system, but doing all the startup
> explicitly is probably a better idea.

You need to be able to signal the application close events for all
kind of resources.  For example, the server is expecting that TCP/IP
session can shut down "unexpectedly", but not necessarily the other
files or seeing the clock jump three days into the future.  Applications
should be prepared to deal with this kind of errors to gracefully
support being restarted from a saved image.


[···@thalassa pjb]$ clisp -norc
clisp -norc
[1]> (defparameter *file* (open "/tmp/a.lisp"))
*FILE*
[2]> (read-line *file*)
"(eval-when (:compile-toplevel :load-toplevel :execute)" ;
NIL
[3]> (ext:saveinitmem "test.mem")
2457632 ;
614408
[4]> (quit)
[···@thalassa pjb]$ clisp -norc -M test.mem
[1]> *file*
#<CLOSED INPUT BUFFERED FILE-STREAM CHARACTER #P"/tmp/a.lisp" @2>
[2]> (read-line *file*)

*** - READ-CHAR on
       #<CLOSED INPUT BUFFERED FILE-STREAM CHARACTER #P"/tmp/a.lisp" @2>
      is illegal
The following restarts are available:
ABORT          :R1      ABORT
Break 1 [3]> :q
:q
[4]> (setf *file* (open *file*))
#<INPUT BUFFERED FILE-STREAM CHARACTER #P"/tmp/a.lisp" @1>
[5]> (read-line *file*)
"(eval-when (:compile-toplevel :load-toplevel :execute)" ;
NIL
[6]> ;; oops: we should have saved a file-position somewhere...

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Until real software engineering is developed, the next best practice
is to develop with a dynamic system that has extreme late binding in
all aspects. The first system to really do this in an important way
is Lisp. -- Alan Kay
From: Thomas F. Burdick
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <xcvoe6egwum.fsf@conquest.OCF.Berkeley.EDU>
Pascal Bourguignon <····@mouse-potato.com> writes:

> Paul Wallich <··@panix.com> writes:
> > Dumping an image from a running server is a little like dumping an
> > image of a car in gear. That's not generally the state you want to
> > start up in. You can set things up so that the running image doesn't
> > have any state that would confuse it when it comes back into existence
> > at another time on another system, but doing all the startup
> > explicitly is probably a better idea.
> 
> You need to be able to signal the application close events for all
> kind of resources.  For example, the server is expecting that TCP/IP
> session can shut down "unexpectedly", but not necessarily the other
> files or seeing the clock jump three days into the future.  Applications
> should be prepared to deal with this kind of errors to gracefully
> support being restarted from a saved image.

What are you guys smoking, some lets-chase-the-newbie-back-to-Smalltalk herb?

Dumping an image of a running Lisp server application is not the
world's most common thing, it's a bit dangerous for a newbie from
ST[*], but it's sometimes a good idea, and certainly possible and not
rocket science.  Here's how you would go about dumping an image of a
typical web application:

  * Get control of the app.  In the case of green threads or event
    servers, this is easy.  For native threads, you'll need to
    temporarily stop all the other threads.

  * Fork.  Let the parent go back to serving requests.

  * Shut down all your client connections.  Stop listening on the
    server socket(s) and throw it (them) away.  Your web server
    probably makes this easy.

  * Close your database connections, and throw them away if you're
    pooling them.

  * Shut down any SWANK connections.

  * Save the image.  Quit if necessary (SBCL and CMUCL "helpfully" do
    this for you).

When the image starts back up, you'll have all your software loaded,
and none of it running.  Just start it up.

[*] Although I suspect that being told by experience Lispers to watch
out for image gotchas will be enough for the OP to watch himself and
not shoot himself in the foot too badly.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Ulrich Hobelmann
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <3ptm7kFc8aeaU1@individual.net>
Thomas F. Burdick wrote:
>   * Save the image.  Quit if necessary (SBCL and CMUCL "helpfully" do
>     this for you).
> 
> When the image starts back up, you'll have all your software loaded,
> and none of it running.  Just start it up.

Not sure that that's enough.  The listening socket is still open, and 
probably won't be opened automagically when the image is reloaded...

-- 
Do or do not.  There is no try.
   Yoda
From: Thomas F. Burdick
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <xcvek7agt3a.fsf@conquest.OCF.Berkeley.EDU>
Ulrich Hobelmann <···········@web.de> writes:

> Thomas F. Burdick wrote:
> >   * Save the image.  Quit if necessary (SBCL and CMUCL "helpfully" do
> >     this for you).
> > 
> > When the image starts back up, you'll have all your software loaded,
> > and none of it running.  Just start it up.
> 
> Not sure that that's enough.  The listening socket is still open, and 
> probably won't be opened automagically when the image is reloaded...

Please stop trolling.

Here is what I wrote:

 >   * Get control of the app.  In the case of green threads or event
 >     servers, this is easy.  For native threads, you'll need to
 >     temporarily stop all the other threads.
 > 
 >   * Fork.  Let the parent go back to serving requests.
 > 
 >   * Shut down all your client connections.  Stop listening on the
                                               ^^^^^^^^^^^^^^^^^^^^^
 >     server socket(s) and throw it (them) away.  Your web server
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 >     probably makes this easy.
       ^^^^^^^^^^^^^^^^^^^^^^^^
 > 
 >   * Close your database connections, and throw them away if you're
 >     pooling them.
 > 
 >   * Shut down any SWANK connections.
 > 
 >   * Save the image.  Quit if necessary (SBCL and CMUCL "helpfully" do
 >     this for you).



-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Ulrich Hobelmann
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <3ptqejFc1ee6U1@individual.net>
Thomas F. Burdick wrote:
>> Not sure that that's enough.  The listening socket is still open, and 
>> probably won't be opened automagically when the image is reloaded...
> 
> Please stop trolling.
> 
> Here is what I wrote:
> 
>  >   * Get control of the app.  In the case of green threads or event
>  >     servers, this is easy.  For native threads, you'll need to
>  >     temporarily stop all the other threads.
>  > 
>  >   * Fork.  Let the parent go back to serving requests.
>  > 
>  >   * Shut down all your client connections.  Stop listening on the
>                                                ^^^^^^^^^^^^^^^^^^^^^
>  >     server socket(s) and throw it (them) away.  Your web server
>        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>  >     probably makes this easy.
>        ^^^^^^^^^^^^^^^^^^^^^^^^

Oh sorry, seems like I read too fast and missed the server socket part. 
  (I parsed your list as each point containing only one action each, I 
guess).

OTOH it takes a decent amount of paranoia to attribute to trolling what 
could easily be explained through stupidity or inattentiveness...

-- 
Do or do not.  There is no try.
   Yoda
From: David
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <1127864001.595163.309000@g43g2000cwa.googlegroups.com>
Oooh. This sounds cool. I still haven't got around to trying to shut
down all the file descriptors yet, but...

So, by forking the lisp system serving pages and then dumping a core
image from the child (after shutting down what needs shutting down) I
can get a ready to go image without interfering with the serving up of
web pages? Useful.

This is what I really like about doing this kind of thing in Lisp -
being able to fix/enhance the server without stopping it from running.
Obviously a certain amount of care has to be taken, but I test
significant things on another copy first, and I've had remarkable
success in not killing the live server so far.

(BTW I wouldn't exactly call myself a newbie from ST - I've used that
far less than I've used lisp - I've just played with it a bit and it
seemed kind of cool being able to save images. More like a newbie from
Perl :)

Thanks,
-- David
From: Rob Warnock
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <NYKdnej_L4f7oKfeRVn-oA@speakeasy.net>
David <······@blueyonder.co.uk> wrote:
+---------------
| This is what I really like about doing this kind of thing in Lisp -
| being able to fix/enhance the server without stopping it from running.
| Obviously a certain amount of care has to be taken, but I test
| significant things on another copy first, and I've had remarkable
| success in not killing the live server so far.
+---------------

Ditto. I just added [after lots of testing on a development mirror,
of course!] a major feature to a production web app [Apache + CMUCL +
PostgreSQL] for which the Lisp image has been running continuously since
December, 2004. It was indeed nice to not have to shutdown/restart...  ;-}


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: Rob Warnock
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <RtKdnankLLJRoqfeRVn-uQ@speakeasy.net>
Thomas F. Burdick <···@conquest.OCF.Berkeley.EDU> wrote:
+---------------
| Dumping an image of a running Lisp server application is not the
| world's most common thing, it's a bit dangerous for a newbie from
| ST[*], but it's sometimes a good idea, and certainly possible and not
| rocket science.  Here's how you would go about dumping an image of a
| typical web application: ...
+---------------

It's also useful if you're trying to use Lisp for short-lived
processes such as CGI scripts and specialized system utilities.
Running a custom image is usually *far* faster than loading up
all the libraries your app needs.

And if you have a bunch of related apps [such as the above-mentioned
CGI scripts] that can share the same image, then execution is likely
to be even faster since your operating system will cache the Lisp
executable and image file in its buffer cache.


-Rob

-----
Rob Warnock			<····@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607
From: David
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <1127922251.381086.153030@f14g2000cwb.googlegroups.com>
I've been trying to dump an image of the running server as Thomas F.
Burdick outlined above. I've managed to dump the pre-running server in
both sbcl-0.9.5 and cmucl 18e and that starts up fine (and very
quickly).

In cmucl when I start the server up and then do
(mp::startup-idle-and-top-level-loops) and then try and save an image
(from a forked server or otherwise) I get an error:-
    Only the *initial-process* can shutdown multi-processing
If I don't do the (mp::startup-idle-and-top-level-loops) then I _can_
dump an image (haven't tried forking yet) but the performance is really
bad. Is there anything else I need to do in the forked child? Can it
switch back to the initial-process or something?

In SBCL with native thread support the docs say (of saving an image):-
      It will not work if multiple threads are in use.
and it appears to be right!! How do I temporarily stop all the other
threads and will this then allow me to dump the image from the forked
child?

(The performance in SBCL with native threads is a lot better
incidentally)

-- David
From: Thomas F. Burdick
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <xcvbr2dgdjj.fsf@conquest.OCF.Berkeley.EDU>
"David" <······@blueyonder.co.uk> writes:

> I've been trying to dump an image of the running server as Thomas F.
> Burdick outlined above. I've managed to dump the pre-running server in
> both sbcl-0.9.5 and cmucl 18e and that starts up fine (and very
> quickly).
> 
> In cmucl when I start the server up and then do
> (mp::startup-idle-and-top-level-loops) and then try and save an image
> (from a forked server or otherwise) I get an error:-
>     Only the *initial-process* can shutdown multi-processing
> If I don't do the (mp::startup-idle-and-top-level-loops) then I _can_
> dump an image (haven't tried forking yet) but the performance is really
> bad. Is there anything else I need to do in the forked child? Can it
> switch back to the initial-process or something?

That sounds like a good use for interrupt-process, which causes a
thread to call a function.

> In SBCL with native thread support the docs say (of saving an image):-
>       It will not work if multiple threads are in use.
> and it appears to be right!! How do I temporarily stop all the other
> threads and will this then allow me to dump the image from the forked
> child?

Something like

  (mapcar #'destroy-thread (remove *current-thread* (list-all-threads)))

would probably do it, but you should definately follow up to the
mailing lists for this type of thing.

> (The performance in SBCL with native threads is a lot better
> incidentally)

Eh, neither of them work on real platforms like Darwin or Solaris :-)

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: David
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <1127948676.315926.120280@z14g2000cwz.googlegroups.com>
Yay - I've got it working!

I was just about to try using interrupt-process to have the initial
process do the image save when I started up swank, connected through
slime and then checked the current process against the initial only to
find that they were the same. Before, I had been typing commands
straight into the top level loop rather than using slime.

Anyway, the following function now dumps an image of the running
server, from which it can be started up again:-

(defun save-server-image ()
  (if (= (unix:unix-fork)
	  0)
      ;; This is the child process...
      (progn
	(shutdown)
	(dolist (h lisp::*descriptor-handlers*)
	  (when (> (lisp::handler-descriptor h) 2)
	    (sys:remove-fd-handler h)))
	(extensions:save-lisp "running-core" :purify nil))))

Thanks for all the help. I might look into doing the same in SBCL
later, but for now I'll probably stick with CMUCL since it seems to be
working fine.

-- David
From: Paolo Amoroso
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <8764slupnb.fsf@plato.moon.paoloamoroso.it>
"David" <······@blueyonder.co.uk> writes:

> In cmucl when I start the server up and then do
> (mp::startup-idle-and-top-level-loops) and then try and save an image
> (from a forked server or otherwise) I get an error:-
>     Only the *initial-process* can shutdown multi-processing
> If I don't do the (mp::startup-idle-and-top-level-loops) then I _can_
> dump an image (haven't tried forking yet) but the performance is really
> bad. Is there anything else I need to do in the forked child? Can it

With CMUCL, try this:

  (in-package :your-app)

  (defun start-your-app ()
    (catch 'lisp::%end-of-the-world
      (mp::init-multi-processing)
      (mp:make-process #'your-app-main-entry-point-function :name "Your app")
      (mp::idle-process-loop)))

Then do:

  (save-lisp "your-app.core" :init-function #'your-app:start-your-app)

I was suggested this tip in a CMUCL mailing list.


Paolo
-- 
Why Lisp? http://wiki.alu.org/RtL%20Highlight%20Film
Recommended Common Lisp libraries/tools:
- ASDF/ASDF-INSTALL: system building/installation
- CL-PPCRE: regular expressions
- CFFI: Foreign Function Interface
From: Thomas F. Burdick
Subject: Re: saving image with cmucl (for portable allegroserve app)
Date: 
Message-ID: <xcvll1igw5r.fsf@conquest.OCF.Berkeley.EDU>
"David" <······@blueyonder.co.uk> writes:

> OK, thanks. I'll try that way of removing all the handlers later.
> 
> I do periodically check that the system loads up from source files on
> my local machine (I usually have connections to these 2 separate
> systems from emacs), which I need to do anyway since I don't want to
> have to shut down the 'live' one if I update stuff.

In all likelyhood, developing with a test server, then patching the
still-running production server is fine.  However, who says you have
to shut it down just to bring in a new image?  You just have to think
more deviously :-)

Fork your server, and in the child put the descriptor number for the
server socket somewhere you can find it again (eg, the environment, or
a temp file).  Exec and become a fresh new Lisp, and load the new
server code from files.  Connect to any databases and what-not.  Tell
the old server to stop accepting new connections (eg, using a pipe
that you created before the fork), and start accepting the new
connections yourself.  When the old server has finished serving its
pending clients, it quietly exits.  Ta-da, you hot-swapped your server!

> I'm still trying to decide whether there is any point at all in trying
> to dump an image from a running server or whether it's better to make a
> lisp script which loads everything and dumps an image, and then another
> lisp script which starts the server up when run from that image. That
> probably makes more sense I suppose.

You can't dump an image of the running server (it doesn't make literal
sense, and Common Lisp comes from the (historical) half of the Lisp
world that eschews DWIM).  So you'll need at least a start-server
function, and possibly a stop-server function as well, if you want to
dump images from the server image.

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'