help-smalltalk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-smalltalk] How to restart an image running a server?


From: Mike Anderson
Subject: [Help-smalltalk] How to restart an image running a server?
Date: Tue, 03 Oct 2006 21:42:56 +0000
User-agent: Mozilla Thunderbird 1.0.5 (X11/20050711)

Hello All,

I have an HTTP server, and I want to be able to snapshot the image and
have the server come up again when the image is restarted. I have this
partially working, but aspects of it are puzzling me greatly and I'm
hoping that someone can shed some light on it.

I have created a proxy class ExternalResource which wraps all calls to
the NetServers's Socket (held in the inst var. resource). After image
restart I want to nil resource, and then use createBlock to lazily
recreate it.

Object subclass: #ExternalResource
        instanceVariableNames: 'resource createBlock'
        classVariableNames: 'ExternalProcesses'
        ...

ExternalResource >> ensureValid
        resource isNil ifTrue: [ resource := createBlock value ].
        ^resource

ExternalResource >> anyMethodOfSocket
        "Example of wrapper methods."
        ^self ensureValid anyMethodOfSocket

ExternalResource class update: aspect
        aspect == #returnFromSnapshot ifTrue:
            [ self withAllSubclassesDo:
                [ :class | class allInstancesDo:
                    [ :obj | obj invalidate "resource := nil" ] ] ].

However, I find that that doesn't work - I get a backtrace
(backtrace1.log) on restart and the server is not available.

I changed the code so that it suspends the process accessing the socket
before it loops through doing the invalidate code above. Following this,
the server comes back up. I get one backtrace (backtrace2.log), which I
think is the result of the process that was in the middle of serving the
request that caused the snapshot, but otherwise all is well.

ExternalResource >> anyMethodOfSocket
        "Example of wrapper methods."
        ExternalProcesses add: Processor activeProcess.
        [ ^self ensureValid anyMethodOfSocket ]
                ensure:
                [ ExternalProcesses remove: Processor activeProcess. ].

ExternalResource class >> update: aspect
        | ps |
        #returnFromSnapshot = aspect ifFalse: [ ^self ].
        (ps := ExternalProcesses asSet)
                remove: Processor activeProcess ifAbsent: [].
        ps do: [ :each | each suspend ].
        self withAllSubclassesDo:
                [ :class | class allInstancesDo:
                        [ :obj | obj invalidate ] ].
        ps do: [ :each | each resume ].

Pleased with this, I thought it would be neater to suspend the process
*before* the snapshot, to guarantee the sequence of events. However, I
now get a backtrace when I snapshot the image (backtrace3a.log), even
though the server seems to continue running fine. If I restart this
image, I again get a backtrace immediately (backtrace3b.log), but again,
the server seems to be running fine.

ExternalResource class >> update: aspect
        | ps |
        (#(#aboutToSnapshot #finishedSnapshot #returnFromSnapshot)
                includes: aspect) ifFalse: [ ^self ].
        (ps := ExternalProcesses asSet)
                remove: Processor activeProcess ifAbsent: [].
        aspect = #aboutToSnapshot ifTrue:
                [ ps do: [ :each | each suspend ].
                ^self ].
        aspect == #returnFromSnapshot ifTrue:
                [ self withAllSubclassesDo:
                        [ :class | class allInstancesDo:
                                [ :obj | obj invalidate ] ] ].
        ps do: [ :each | each resume ].

I hope I've posted enough code for all this to make sense. There's quite
a lot of code in total, and I don't know how to bundle it up
conveniently, so I've tried to summarize the key methods.

The things confusing me are:

Why do I need to suspend the process at all? Presumably this means that
the process sending update: #returnFromSnapshot is not a privileged
process and other processes are able to get processor time?

Why does my 'neater' version give me a backtrace when I snapshot? Is
there something about suspending that process that is a no-no?

I'd really like to get to the bottom of this.

Mike


 2006-10-03T21:24:54+00:00 <= nil ?
Object: nil error: did not understand #do:
UndefinedObject(Object)>>#primError:
MessageNotUnderstood(Exception)>>#defaultAction
optimized [] in Exception class>>#coreException
MessageNotUnderstood(Signal)>>#activateHandler:
CoreException>>#activateOuterHandlerFor:
MessageNotUnderstood(Signal)>>#pass
optimized [] in NetClients.NetSession>>#run
MessageNotUnderstood(Signal)>>#activateHandler:
MessageNotUnderstood(Exception)>>#signal
UndefinedObject(Object)>>#doesNotUnderstand:
DLD class>>#primDefineExternFunc:
DLD class>>#defineExternFunc:
CFunctionDescriptor class>>#addressOf:
CFunctionDescriptor>>#isValid
CFunctionDescriptor>>#callFrom:into:
TCP.TCPSocketImpl class(TCP.AbstractSocketImpl class)>>#soError
TCP.TCPSocketImpl(TCP.AbstractSocketImpl)>>#soError
optimized [] in TCP.AbstractSocketImpl>>#ensureWriteable
BlockClosure>>#ensure:
optimized [] in TCP.AbstractSocketImpl>>#ensureWriteable
TCP.TCPSocketImpl(TCP.AbstractSocketImpl)>>#fileOp:with:ifFail:
TCP.TCPSocketImpl(TCP.AbstractSocketImpl)>>#ensureWriteable
optimized [] in TCP.Socket>>#newWriteBuffer:
TCP.WriteBuffer>>#flush
TCP.Socket>>#flush
NetClients.CrLfStream>>#nextPut:
NetClients.CrLfStream(Stream)>>#nl
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#nl
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#sendResponseType
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#sendHeader
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#respondTo:
Hector.ReadEvalPrintServlet>>#respondTo:
[] in Hector.HectorServlet>>#respondTo:
True>>#ifTrue:
Hector.HectorServlet>>#respondTo:
NetClients.WikiWorks.CompositeServlet>>#respondTo:
NetClients.WikiWorks.WebServer>>#respondTo:
[] in NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
Time class>>#millisecondsToRun:
[] in NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
BlockClosure>>#on:do:
NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
optimized [] in NetClients.NetThread>>#startNewProcess
[] in Process>>#onBlock:at:suspend:
BlockClosure>>#on:do:
[] in Process>>#onBlock:at:suspend:
BlockContext class>>#fromClosure:parent:
ProcessorScheduler>>#terminateActive
ContextPart class>>#unwind:
ContextPart class>>#unwind
UndefinedObject(Object)>>#primError:
MessageNotUnderstood(Exception)>>#defaultAction
optimized [] in Exception class>>#coreException
MessageNotUnderstood(Signal)>>#activateHandler:
CoreException>>#activateOuterHandlerFor:
MessageNotUnderstood(Signal)>>#pass
optimized [] in NetClients.NetSession>>#run
MessageNotUnderstood(Signal)>>#activateHandler:
MessageNotUnderstood(Exception)>>#signal
UndefinedObject(Object)>>#doesNotUnderstand:
DLD class>>#primDefineExternFunc:
DLD class>>#defineExternFunc:
CFunctionDescriptor class>>#addressOf:
CFunctionDescriptor>>#isValid
CFunctionDescriptor>>#callFrom:into:
TCP.TCPSocketImpl class(TCP.AbstractSocketImpl class)>>#soError
TCP.TCPSocketImpl(TCP.AbstractSocketImpl)>>#soError
optimized [] in TCP.AbstractSocketImpl>>#ensureWriteable
BlockClosure>>#ensure:
optimized [] in TCP.AbstractSocketImpl>>#ensureWriteable
TCP.TCPSocketImpl(TCP.AbstractSocketImpl)>>#fileOp:with:ifFail:
TCP.TCPSocketImpl(TCP.AbstractSocketImpl)>>#ensureWriteable
optimized [] in TCP.Socket>>#newWriteBuffer:
TCP.WriteBuffer>>#flush
TCP.Socket>>#flush
NetClients.CrLfStream>>#nextPut:
NetClients.CrLfStream(Stream)>>#nl
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#nl
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#sendResponseType
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#sendHeader
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#respondTo:
Hector.ReadEvalPrintServlet>>#respondTo:
[] in Hector.HectorServlet>>#respondTo:
True>>#ifTrue:
Hector.HectorServlet>>#respondTo:
NetClients.WikiWorks.CompositeServlet>>#respondTo:
NetClients.WikiWorks.WebServer>>#respondTo:
[] in NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
Time class>>#millisecondsToRun:
[] in NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
BlockClosure>>#on:do:
NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
optimized [] in NetClients.NetThread>>#startNewProcess
[] in Process>>#onBlock:at:suspend:
BlockClosure>>#on:do:
[] in Process>>#onBlock:at:suspend:
BlockContext class>>#fromClosure:parent:
(ip 6)ProcessorScheduler>>#yield
(ip 12)[] in Delay class>>#initialize
(ip 16)[] in Process>>#onBlock:at:suspend:
(ip 10)BlockClosure>>#on:do:
(ip 14)[] in Process>>#onBlock:at:suspend:
(ip 14)BlockContext class>>#fromClosure:parent:
Processing package file: hector.xml
Hector Processing package file: hector.xml
Hector Processing package file: /home/mike/smalltalk/packages/packages.xml
MUtility ExternalResources NaiveXML PackageUtils PackageInstaller CLibraries 
XLib Imlib2 Cairo Applets DBI DBD-libmysqlclient DBD-libpq Loading package 
ExternalResources
Loading package Hector
Loading package NaiveXML
 2006-10-03T21:15:55+00:00 <=  2006-10-03T21:15:37+00:00 ?
7 GET OrderedCollection ('Hector' 'ReadEvalPrint' )
 2006-08-28T14:42:22+00:00 <=  2006-08-28T14:42:22+00:00 ?
4 GET OrderedCollection ('res' 'hector.css' )
 2006-06-10T18:40:04+00:00 <=  2006-06-10T18:40:04+00:00 ?
4 GET OrderedCollection ('res' 'sarissa' 'sarissa.js' )
 2006-08-31T00:38:54+00:00 <=  2006-08-31T00:38:54+00:00 ?
3 GET OrderedCollection ('res' 'hector.js' )
Object: nil error: did not understand #isPeerAlive
UndefinedObject(Object)>>#primError:
MessageNotUnderstood(Exception)>>#defaultAction
optimized [] in Exception class>>#coreException
MessageNotUnderstood(Signal)>>#activateHandler:
MessageNotUnderstood(Exception)>>#signal
UndefinedObject(Object)>>#doesNotUnderstand:
optimized [] in NetClients.NetSession>>#run
MessageNotUnderstood(Signal)>>#activateHandler:
MessageNotUnderstood(Exception)>>#signal
UndefinedObject(Object)>>#doesNotUnderstand:
NetClients.WikiWorks.WebRequest>>#stream:
NetClients.WikiWorks.WebRequest>>#initConnection:
NetClients.WikiWorks.WebRequest class>>#for:
NetClients.WikiWorks.WebSession>>#next
[] in NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
BlockClosure>>#on:do:
NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
optimized [] in NetClients.NetThread>>#startNewProcess
[] in Process>>#onBlock:at:suspend:
BlockClosure>>#on:do:
[] in Process>>#onBlock:at:suspend:
BlockContext class>>#fromClosure:parent:
ProcessorScheduler>>#terminateActive
ContextPart class>>#unwind:
ContextPart class>>#unwind
UndefinedObject(Object)>>#primError:
MessageNotUnderstood(Exception)>>#defaultAction
optimized [] in Exception class>>#coreException
MessageNotUnderstood(Signal)>>#activateHandler:
MessageNotUnderstood(Exception)>>#signal
UndefinedObject(Object)>>#doesNotUnderstand:
optimized [] in NetClients.NetSession>>#run
MessageNotUnderstood(Signal)>>#activateHandler:
MessageNotUnderstood(Exception)>>#signal
UndefinedObject(Object)>>#doesNotUnderstand:
NetClients.WikiWorks.WebRequest>>#stream:
NetClients.WikiWorks.WebRequest>>#initConnection:
NetClients.WikiWorks.WebRequest class>>#for:
NetClients.WikiWorks.WebSession>>#next
[] in NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
BlockClosure>>#on:do:
NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
optimized [] in NetClients.NetThread>>#startNewProcess
[] in Process>>#onBlock:at:suspend:
BlockClosure>>#on:do:
[] in Process>>#onBlock:at:suspend:
BlockContext class>>#fromClosure:parent:
 2006-10-03T21:16:00+00:00 <= nil ?
129 POST OrderedCollection ('Hector' 'ReadEvalPrint' )
(ip 6)ProcessorScheduler>>#yield
(ip 12)[] in Delay class>>#initialize
(ip 16)[] in Process>>#onBlock:at:suspend:
(ip 10)BlockClosure>>#on:do:
(ip 14)[] in Process>>#onBlock:at:suspend:
(ip 14)BlockContext class>>#fromClosure:parent:
Object: nil error: did not understand #isPeerAlive
UndefinedObject(Object)>>#primError:
MessageNotUnderstood(Exception)>>#defaultAction
optimized [] in Exception class>>#coreException
MessageNotUnderstood(Signal)>>#activateHandler:
MessageNotUnderstood(Exception)>>#signal
UndefinedObject(Object)>>#doesNotUnderstand:
optimized [] in NetClients.NetSession>>#run
MessageNotUnderstood(Signal)>>#activateHandler:
MessageNotUnderstood(Exception)>>#signal
UndefinedObject(Object)>>#doesNotUnderstand:
NetClients.WikiWorks.WebRequest>>#stream:
NetClients.WikiWorks.WebRequest>>#initConnection:
NetClients.WikiWorks.WebRequest class>>#for:
NetClients.WikiWorks.WebSession>>#next
[] in NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
BlockClosure>>#on:do:
NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
optimized [] in NetClients.NetThread>>#startNewProcess
[] in Process>>#onBlock:at:suspend:
BlockClosure>>#on:do:
[] in Process>>#onBlock:at:suspend:
BlockContext class>>#fromClosure:parent:
ProcessorScheduler>>#terminateActive
ContextPart class>>#unwind:
ContextPart class>>#unwind
UndefinedObject(Object)>>#primError:
MessageNotUnderstood(Exception)>>#defaultAction
optimized [] in Exception class>>#coreException
MessageNotUnderstood(Signal)>>#activateHandler:
MessageNotUnderstood(Exception)>>#signal
UndefinedObject(Object)>>#doesNotUnderstand:
optimized [] in NetClients.NetSession>>#run
MessageNotUnderstood(Signal)>>#activateHandler:
MessageNotUnderstood(Exception)>>#signal
UndefinedObject(Object)>>#doesNotUnderstand:
NetClients.WikiWorks.WebRequest>>#stream:
NetClients.WikiWorks.WebRequest>>#initConnection:
NetClients.WikiWorks.WebRequest class>>#for:
NetClients.WikiWorks.WebSession>>#next
[] in NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
BlockClosure>>#on:do:
NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
optimized [] in NetClients.NetThread>>#startNewProcess
[] in Process>>#onBlock:at:suspend:
BlockClosure>>#on:do:
[] in Process>>#onBlock:at:suspend:
BlockContext class>>#fromClosure:parent:
 2006-10-03T21:18:51+00:00 <= nil ?
-2938 POST OrderedCollection ('Hector' 'ReadEvalPrint' )
(ip 6)ProcessorScheduler>>#yield
(ip 12)[] in Delay class>>#initialize
(ip 16)[] in Process>>#onBlock:at:suspend:
(ip 10)BlockClosure>>#on:do:
(ip 14)[] in Process>>#onBlock:at:suspend:
(ip 14)BlockContext class>>#fromClosure:parent:
 2006-10-03T21:01:26+00:00 <= nil ?
Object: nil error: did not understand #do:
UndefinedObject(Object)>>#primError:
MessageNotUnderstood(Exception)>>#defaultAction
optimized [] in Exception class>>#coreException
MessageNotUnderstood(Signal)>>#activateHandler:
CoreException>>#activateOuterHandlerFor:
MessageNotUnderstood(Signal)>>#pass
optimized [] in NetClients.NetSession>>#run
MessageNotUnderstood(Signal)>>#activateHandler:
MessageNotUnderstood(Exception)>>#signal
UndefinedObject(Object)>>#doesNotUnderstand:
DLD class>>#primDefineExternFunc:
DLD class>>#defineExternFunc:
CFunctionDescriptor class>>#addressOf:
CFunctionDescriptor>>#isValid
CFunctionDescriptor>>#callFrom:into:
TCP.TCPSocketImpl class(TCP.AbstractSocketImpl class)>>#soError
TCP.TCPSocketImpl(TCP.AbstractSocketImpl)>>#soError
optimized [] in TCP.AbstractSocketImpl>>#ensureWriteable
BlockClosure>>#ensure:
optimized [] in TCP.AbstractSocketImpl>>#ensureWriteable
TCP.TCPSocketImpl(TCP.AbstractSocketImpl)>>#fileOp:with:ifFail:
TCP.TCPSocketImpl(TCP.AbstractSocketImpl)>>#ensureWriteable
optimized [] in TCP.Socket>>#newWriteBuffer:
TCP.WriteBuffer>>#flush
TCP.Socket>>#flush
NetClients.CrLfStream>>#nextPut:
NetClients.CrLfStream(Stream)>>#nl
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#nl
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#sendResponseType
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#sendHeader
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#respondTo:
Hector.ReadEvalPrintServlet>>#respondTo:
[] in Hector.HectorServlet>>#respondTo:
True>>#ifTrue:
Hector.HectorServlet>>#respondTo:
NetClients.WikiWorks.CompositeServlet>>#respondTo:
NetClients.WikiWorks.WebServer>>#respondTo:
[] in NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
Time class>>#millisecondsToRun:
[] in NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
BlockClosure>>#on:do:
NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
optimized [] in NetClients.NetThread>>#startNewProcess
[] in Process>>#onBlock:at:suspend:
BlockClosure>>#on:do:
[] in Process>>#onBlock:at:suspend:
BlockContext class>>#fromClosure:parent:
ProcessorScheduler>>#terminateActive
ContextPart class>>#unwind:
ContextPart class>>#unwind
UndefinedObject(Object)>>#primError:
MessageNotUnderstood(Exception)>>#defaultAction
optimized [] in Exception class>>#coreException
MessageNotUnderstood(Signal)>>#activateHandler:
CoreException>>#activateOuterHandlerFor:
MessageNotUnderstood(Signal)>>#pass
optimized [] in NetClients.NetSession>>#run
MessageNotUnderstood(Signal)>>#activateHandler:
MessageNotUnderstood(Exception)>>#signal
UndefinedObject(Object)>>#doesNotUnderstand:
DLD class>>#primDefineExternFunc:
DLD class>>#defineExternFunc:
CFunctionDescriptor class>>#addressOf:
CFunctionDescriptor>>#isValid
CFunctionDescriptor>>#callFrom:into:
TCP.TCPSocketImpl class(TCP.AbstractSocketImpl class)>>#soError
TCP.TCPSocketImpl(TCP.AbstractSocketImpl)>>#soError
optimized [] in TCP.AbstractSocketImpl>>#ensureWriteable
BlockClosure>>#ensure:
optimized [] in TCP.AbstractSocketImpl>>#ensureWriteable
TCP.TCPSocketImpl(TCP.AbstractSocketImpl)>>#fileOp:with:ifFail:
TCP.TCPSocketImpl(TCP.AbstractSocketImpl)>>#ensureWriteable
optimized [] in TCP.Socket>>#newWriteBuffer:
TCP.WriteBuffer>>#flush
TCP.Socket>>#flush
NetClients.CrLfStream>>#nextPut:
NetClients.CrLfStream(Stream)>>#nl
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#nl
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#sendResponseType
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#sendHeader
Hector.RepResultResponse(NetClients.WikiWorks.WebResponse)>>#respondTo:
Hector.ReadEvalPrintServlet>>#respondTo:
[] in Hector.HectorServlet>>#respondTo:
True>>#ifTrue:
Hector.HectorServlet>>#respondTo:
NetClients.WikiWorks.CompositeServlet>>#respondTo:
NetClients.WikiWorks.WebServer>>#respondTo:
[] in NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
Time class>>#millisecondsToRun:
[] in NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
BlockClosure>>#on:do:
NetClients.WikiWorks.WebSession(NetClients.NetSession)>>#run
optimized [] in NetClients.NetThread>>#startNewProcess
[] in Process>>#onBlock:at:suspend:
BlockClosure>>#on:do:
[] in Process>>#onBlock:at:suspend:
BlockContext class>>#fromClosure:parent:
run-hector.st:3: Interrupt
(ip 6)ProcessorScheduler>>#yield
(ip 12)[] in Delay class>>#initialize
(ip 16)[] in Process>>#onBlock:at:suspend:
(ip 10)BlockClosure>>#on:do:
(ip 14)[] in Process>>#onBlock:at:suspend:
(ip 14)BlockContext class>>#fromClosure:parent:

reply via email to

[Prev in Thread] Current Thread [Next in Thread]