KomServices

ApplicationService
I am an abstract superclass. Subclass me to create your own service classes whose instances can be started and stopped. Subclasses should override the #runWhile: method to do something useful.
An instance of an ApplicationService will have a Process associated with it while it is running.
An ApplicationService can be in one of three states that are determined by the process and condiction instance variables:
running: condition == #run & process notNil
stopping: condition ~~ #run & process notNil
stopped: process isNil
Instance Variables:
name <String | nil> - An optional name for the given service
process <Process | nil> - The Process instance for a running service
condition <#run | #stop> - Indicates whether the associated process should continue to run or whether it should stop running
dynamicBindings <DynamicBindings | nil> - A set of dynamic bindings that are active for the associated process; if used instead of global variables, then multiple services can run simultaneously and be bound to different sets of "globals"; see the class comments for DynamicBindings for more details
priority <Number> - The priority at which the associated process will run
addService:
addStopSignal
allServices
bindings
bindings:
cancelStopRequest
If the service is currently in a state of stopping, this method
will return the service to a state of running
checkRequiredBindings
defaultName
defaultPriority
initialize
Subclasses should redefine this method to perform initializations on instance creation
initializeBindings
Subclasses may wish to establish an isolated set of dynamic
bindings by overriding this method. A subclass may also want
to go ahead and set some dynamic variables. For example:
dynamicBindings := DynamicBindings root newChild.
dynamicBindings at: #example put: 'a value'.
In this example, the service is assigned a new set of dynamic bindings
that inherits the bindings of root set of bindings and the variable #example
is assigned a value. Code that is running in the context of this service can
then access this variable using the expressions:
#example binding
#example binding: aNewValue
isRunning
isSleeping
isStopped
isStopping
kill
Forcibly kill the service regardless of whether it is in a state where it is
safe to do so. Use stop unless the service is not responding.
name
Answer a name for the receiver. This is used generically in the title of certain inspectors, such as the referred-to inspector, and specificially by various subsystems. By default, we let the object just print itself out..
name:
newNamed:
prepareForShutdown
The system is about to shutdown
prepareForStartup
The system just started up
printOn:
Append to the argument, aStream, a sequence of characters that
identifies the receiver.
priority
priority:
process
processTerminated
Private. Nils out the process inst var (indication that the service is
stopped and signals any processes that are waiting on the service to
stop.
register
releaseProcessesWaitingForStop
Private. Signals any processes that are waiting on the service to stop.
removeService:
requiredBindings
Subclasses may wish to override this method to provide a list of objects
that the service requires to be registered in its dynamic bindings. When
attempting to start a service that has required bindings, if any of the
required bindings are missing, an exception will be signaled and the
service will not start.
runWhile:
subclasses should perform whatever service they provide
in a loop that doesn't return until aBlock evaluates to true
serviceNamed:
serviceNamed:ifAbsent:
services
servicesNamed:
shutDown
sleepFor:
If your service sleeps, use this method as it will indicate that it is
safe to immediately terminate the process while it is sleeping.
sleepMethod
start
startUp
stop
Gracefully request the service to stop. This method returns immediately. If
you wish to wait until the service has stopped, follow this method with #waitForStop
or #waitForStopUntil:.
stopSignal
<Semaphore | nil> Indicates whether the associated process should
be in the process of shutting down. The semaphore will be signaled
for all waiting process when the service thinks it has stopped (note,
you should not rely solely on the semaphore signal to determine that
the service is actually stopped, instead, wait then ask the service
#isStopped).
unregister
verifyOkToStart
waitForStop
Wait until the service is stopped
waitForStopUntil:
Wait until the service is stopped or the deadline is reached
withBindingsDo:
TcpListener
I listen for TCP connections on a given port number.
Instance variables:
portNumber - the number of the port on which to listen for incoming connections
handler - an object that is sent the #value: message whenever an incoming connection is established; the argument to this message is a connected socket
socketsToDestroy - a list of sockets that need to be destroyed (usually a listening socket that is no longer needed)
Usage:
In the following example, a TcpListener is established on port 8123. After evaluating the following example, if you open a transcript window and point a web browser to port 8123 of this machine (ie. http://localhost:8123/), you should see several http requests appear in the transcript.
| count listener |
count _ 0.
listener _ TcpListener
on: 8123
handler:
[ :socket |
count _ count + 1.
Transcript show: socket getData.
socket closeAndDestroy].
listener forkAndListenWhile: [count < 5].
For an additional example of using TcpListener, see TcpService.
acceptTimeout
acceptTimeout:
address
address:
backlogSize
backlogSize:
bind:withBacklogSize:
destroySockets
forkAndListenWhile:
initialize
Subclasses should redefine this method to perform initializations on instance creation
initializeOnPort:address:handler:
initializeOnPort:handler:
listen
This is the listening loop. It runs forever accepting
inbound sockect connections.
listenWhile:
This is the listening loop. It runs while aBlock evaluates
to true. When the loop terminates or when the process running
the loop is terminated, any listening sockets will be destroyed.
listenerDestroyDelay
listenerDestroyDelay:
newListener:
Create a new socket that listens on our port. The backlog is how many simultaneous
connections to accept at the same time
on:address:handler:
on:handler:
portNumber
printOn:
Append to the argument, aStream, a sequence of characters that
identifies the receiver.
pvtListenLoop:
pvtNewListener:
Create a new socket that listens on our port. The backlog is how many simultaneous
connections to accept at the same time
pvtOldListenLoop:
see comment on ConnectionQueue>>oldStyleListenLoop
socketClass
socketsToDestroy
TcpService
I am a KomHttpServer service that listens for inbound TCP connections on a given port.
Instance Variables:
portNumber - the TCP port number on which to listen for inbound connections
Usage:
Subclasses should override the #serve: method to process incoming TCP connections (a connected socket is passed as the sole argument to this method). Starting and stopping instances of this class will start and stop listening on the given port number.
address
address:
assignPort
initialize
Subclasses should redefine this method to perform initializations on instance creation
initializeOnPort:address:priority:
initializeOnPort:priority:
on:
on:named:
portNumber
portNumber:
prepareForStartup
The squeak system just started up
printOn:
Append to the argument, aStream, a sequence of characters that
identifies the receiver.
runWhile:
subclasses should perform whatever service they provide
in a loop that doesn't return until aBlock evaluates to true
serve:
Subclasses should override this method to provide socket based
communications services. Each new socket connection is handed to
this method.
serviceOnPort:
serviceOnPort:ifAbsent:
services
start
startOn:
startOn:named:
unassignPort
value:
This method is invoked by the TcpListener
verifyPortAvailability: