[Top][All Lists]
[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:
- [Help-smalltalk] How to restart an image running a server?,
Mike Anderson <=