Bug 40874

Critical

GemBuilder for Smalltalk/VW

7.3.3, 7.3.2, 7.3.1, 7.3, 7.2.2, 7.2.1, 7.2

With GS64 only

7.4

Missing data in replicated objects after server error

When server objects that were replicated to the client are modified on
the server, updates to the replicated objects are sent to the client for
each server operation.  If an error occurs during a server operation, when
there were modifications on the server to replicated objects, there may
be incomplete updates under some circumstances. The problematic cases involve
hashed collections, circular reference paths, and instances of classes
in which the class is not on the client.  In these cases, valid object
references may be nil on the client.  If the replicates are modified, it
may result in data loss.

This bug is in the Single-trip protocol, which is used with the GemStone/S
64 Bit server.  This bug does not affect systems using 32-bit GemStone/S.

Workaround

File the following into the VW image:


<?xml version="1.0"?>

<st-source>

<methods>
<class-id>GemStone.Gbs.GbxServerInteraction</class-id> <category>private - executing</category>

<body package="GbsServerInterface" selector="fetchReplicationClamp">fetchReplicationClamp
	"If the replication clamp has not been explicitly set,
	find or create and answer the replication clamp for this interaction.
	If the replication clamp must be created, this will involve other server interactions.
	If the replication clamp must be created, creates another ServerInteraction and executes it
	to create the clamp. Therefore, the sender should *NOT* hold my sessionProtect. The session
	semaphore is not needed to create a class connector, so the replication clamp could be flushed
	at any moment even if we did hold sessionProtect, so there would be no advantage "
	"Even if we're not replicating results, we need a clamp to handle traversal of altered immediate-faulting objects."

	replicationClampDelegate ~~ nil ifTrue: [^replicationClampDelegate].
	^replicationSpecSelector ~~ nil
		ifTrue: [session replicationClampForSpecSet: replicationSpecSelector]
		ifFalse: [session oopNil]</body>

<body package="GbsServerInterface" selector="replicateAlteredObjectsAfterError:">replicateAlteredObjectsAfterError: error
	"Used after an error interrupted execution. Note that an 'error' includes things like
	client forwarder sends and breakpoints.

	Normally, answer the given error. However, if we run into an error replicating the altered objects,
	that error is probably worse than the original error, so answer the new error."

	| serverTraversal result |
	serverTraversal := serverInterface newServerTraversal.
	"stopForBreakpoints false to avoid asynch events at this point."
	"Only traversing the altered objects, no actual result, so rootDelegate nil."
	"Explicitly use my replication clamp. If the session's replication clamp has been flushed
	and we tried to recompute it at this point we'd get the altered objects with a nil
	replication clamp and choke on any objects that should have been traversed by callback."
	"Similarly, cannot cache GsInstVarNames at this point, so shouldSynchronize must be false."
	result := serverTraversal
				shouldReplicateResult: false;
				shouldSynchronize: false;
				replicationClampDelegate: replicationClampDelegate;
				stopForBreakpoints: false;
				rootDelegate: session oopNil;
				execute.
	"Shouldn't normally error here, but need to check in case of things like
	session termination, or server out of memory."
	^result gbxIsGSError ifTrue: [result] ifFalse: [error]</body>
</methods>

</st-source>


Last updated: 9/3/13