Workaround:
Make sure that all servers in the Federation uses the same definition for
subclasses of RcIdentityBag, using the same named instance variables in
the same order. Also, do not use replication specs to modify instance
variable mapping between servers.
If you *must* support different subclass definitions and/or replication
specs on RcIdentityBag subclasses, you can file-in the following code as
instructed:
1. Login a topaz session as SystemUser.
2. File-in the following code and commit:
!----------------------------------------------------------------------------
!
! Fix for GemEnterprise bug 33963 effecting
! replication of subclasses of RcIdentityBags
!
category: 'Federation - Private'
method: RcIdentityBag
_fedTraversalCallback
"Return the contents of the receiver."
| arr subcomp count |
" must write each subcomponent to get conflict with concurrent adder/remover
" 1 to: components size do: [ :i |
(subcomp := components at: i) ~~ nil
ifTrue: [ subcomp _putInWriteSet ]
].
" write the component array to get conflict " components size: components
size.
arr := Array new. self _addAllTo: arr.
" put public named inst vars on the end (an optimization when unpacking)
" count := 0. self class _replicateFirstPublicInstVar to: self class instSize
do: [ :i |
arr add: (self instVarAt: i).
count := count + 1.
].
" fix 33963: last element in arr is the number of public named inst vars
" arr add: count.
GemStoneFederation _sessionState ignoredObjects add: arr.
^ arr
%
category: 'Federation - Private'
method: RcIdentityBag
_updateVaryingFrom: buffer
"Update the varying portion of the receiver from the given traversal buffer.
The traversal callback should put an identity bag in the value buffer."
| localObj remoteOop namedSize varyingSize numPrivate index repSpec ivMap
|
buffer numberOfValueBuffOops ~~ 1
ifTrue: [ self _halt: 'RcIdentityBag > _updateVaryingFrom: wrong value
buffer' ].
remoteOop := buffer valueBufferRemoteOop. localObj := buffer localObjectForValueBufferOop:
buffer remoteObjectSpace
otherwise: _remoteNil. buffer advanceValueBufferOop.
localObj == _remoteNil
ifTrue: [ " forward reference "
^ buffer addForwardReference: self ivOffset: -1 remoteOop: remoteOop
].
numPrivate := self class _replicateFirstPublicInstVar - 1. namedSize :=
self class instSize - self class _replicateFirstPublicInstVar + 1.
" fix 33963: add replication spec support " ( ( repSpec := buffer remoteObjectSpace
replicationSpecForLocalClass: self class ) == nil )
ifTrue: [ ivMap := nil ]
ifFalse: [ ivMap := repSpec _getInstVarMap ].
" fix 33963: modify varyingSize calculation to use last item in localObj
" varyingSize := ( localObj size ) - ( localObj at: ( localObj size ) )
- 1.
1 to: namedSize do: [ :i |
" fix 33963: modify replication logic to use replication specs "
( ivMap isNil )
ifTrue: [ self _replicateInstVarAt: numPrivate + i put: (localObj at:
varyingSize + i) ]
ifFalse: [ self _replicateInstVarAt: numPrivate + i put:
(localObj at: ( varyingSize + (ivMap at: numPrivate + i) - numPrivate
)) ].
].
localObj size: varyingSize.
self addAll: localObj. buffer remoteObjectSpace _unreplicate: localObj
remoteOop: remoteOop.
%
!
!----------------------------------------------------------------------------