| private |
| clearHandlers
|
self mutex critical:
[handlersByKey _ Dictionary new.
keysByHandler _ Dictionary new].
|
| handleDefaultRequest: aRequest
|
self subclassResponsibility
|
| handleExpiredRequest: aRequest
|
| url |
url _ WAUrl new.
url addToPath: aRequest url.
aRequest isGet ifTrue:
[aRequest fields keysAndValuesDo:
[:k :v |
(self isSeasideField: k) ifFalse: [url addParameter: k value: v]]].
^ WAResponse
refreshWithMessage: 'That page has expired.'
location: url asString
delay: 3
|
| handleKeyRequest: aRequest
|
|key handler|
key _ [WAExternalID fromString: (aRequest at: self handlerField)] on: Error do: [:e | nil].
handler _ handlersByKey at: key ifAbsent: [nil].
^ (handler notNil and: [handler isActive])
ifTrue: [handler handleRequest: aRequest]
ifFalse: [self handleExpiredRequest: aRequest]
|
| handlerField
|
^ '_s'
|
| initialize
|
self clearHandlers.
|
| isSeasideField: aString
|
^ aString first = $_
|
| keyOrNilForHandler: anObject
|
^ self mutex critical: [keysByHandler at: anObject ifAbsent: [nil]]
|
| mutex
|
^ mutex ifNil: [mutex _ Semaphore forMutualExclusion]
|
| registerRequestHandler: anObject
|
|key|
key _ WAExternalID new: 16.
self shouldCollectHandlers ifTrue: [self unregisterExpiredHandlers].
self mutex critical:
[handlersByKey at: key put: anObject.
keysByHandler at: anObject put: key].
^ key
|
| shouldCollectHandlers
|
^ 10 atRandom = 1
|
| unregisterExpiredHandlers
|
"This method is a little ugly, but using #associationsDo: to build a new
dictionary is 200 times faster than iterating over them with #removeKey:
or even using #keysAndValuesRemove:"
| expired newHandlersByKey newKeysByHandler |
self mutex critical:
[expired _ OrderedCollection new.
newHandlersByKey _ Dictionary new.
handlersByKey associationsDo:
[:assoc |
assoc value isActive
ifTrue: [newHandlersByKey add: assoc]
ifFalse: [expired add: assoc value]].
newKeysByHandler _ Dictionary new.
keysByHandler associationsDo: [:assoc | assoc key isActive ifTrue: [newKeysByHandler add: assoc]].
handlersByKey _ newHandlersByKey.
keysByHandler _ newKeysByHandler].
"Send #unregistered to each in expired"
expired do: [:ea | [ea unregistered] fork]
|