Improving the performance of the GemStone inspector

To inspect objects in GemStone we create a remote instance of GtRemotePhlowViewedObject Object subclass: #GtRemotePhlowViewedObject instanceVariableNames: 'object actionSpecificationsBySelector viewSpecificationsBySelector' classVariableNames: '' package: 'GToolkit-RemotePhlow-InspectorCore' that knows how to return views and actions and work with a proxy to this instance of type GtpoGtRemotePhlowViewedObject GtRsrProxyServiceClient subclass: #GtpoGtRemotePhlowViewedObject instanceVariableNames: '' classVariableNames: '' package: 'GToolkit-GemStone-Pharo-Proxies' .

To reduce the number of remote call during inspection of proxy objects (GtRsrProxyServiceClient GtRsrProxyService subclass: #GtRsrProxyServiceClient uses: TGtRemoteProxySpecificViews + TGtRemoteProxySpecificActions + TGtRemoteProxyInspectorWrappedObjectAttachment + TGtRemoteProxyViewsAttachment + TGtRemoteProxyActionsAttachment instanceVariableNames: 'gtSession' classVariableNames: 'ObjectMap' package: 'GToolkit-GemStone-Pharo-Client' ), GtRsrProxyServiceClient>>#getLocalProxyInspector getLocalProxyInspector ^ self evaluateProxyInspector: 'self' returns an inspector proxy instance with all data needed by the local inspector already cached in that instance.

Not currently implemented, but ideally the inspector should work with an inspector proxy.

This page goes into more details about how data is cache inside the proxy.

Custom serialisation strategy

To inspect an object we need some basic information, like its display string, views and actions. Normal proxy objects provide this informaton like any other objects.

To get all the information needed in one call, GtRsrInspectorProxySerializationStrategy Object subclass: #GtRsrInspectorProxySerializationStrategy instanceVariableNames: '' classVariableNames: '' package: 'GToolkit-RemotePhlow-InspectorCore' is a serialisation strategy that can return for a remote object a GtpoGtRemotePhlowViewedObject GtRsrProxyServiceClient subclass: #GtpoGtRemotePhlowViewedObject instanceVariableNames: '' classVariableNames: '' package: 'GToolkit-GemStone-Pharo-Proxies' inspector proxy initialized with all data related to views and actions, so that getting this data from the inspector proxy does not require extra remote calls. This strategy is used by the session call GtGemStoneSession>>#evaluateProxyInspector: evaluateProxyInspector: remoteScript ^ (self scriptEvaluation script: remoteScript; returnProxyInspector; autoCommit: autoCommit; yourself) evaluateAndWait

session := GtGemStoneSessionRegistry default defaultSession
  
localProxyInspector := session evaluateProxyInspector:  'Object new'
  
localProxyInspector := session 
	evaluateProxyInspector: 'GtRemotePhlowDeclarativeTestInspectable new'
  

We can also get the same data from a proxy object using GtRsrProxyServiceClient>>#evaluateProxyInspector: evaluateProxyInspector: aString "Evaluate the supplied string with `self` bound to the receiver" ^ self gtSession evaluateProxyInspector: aString for: self bindings: Dictionary new. .

objectProxy := session evaluateAndWait:  'Object new'
  
objectProxy := session 
	evaluateAndWait: 'GtRemotePhlowDeclarativeTestInspectable new'
  
localProxyInspector := objectProxy getLocalProxyInspector 
  

Once we have this initialized inspector proxy, getting views from it will not result in any remote calls.

localProxyInspector declarativeViews 
  
localProxyInspector printString
  

Implementation aspects

The serialisation strategy works by returning the inspector proxy and the data needed to serialize it in a single call. A different serialisation strategy GtRsrInspectorProxyDataSerializationStrategy GtRsrInspectorProxySerializationStrategy subclass: #GtRsrInspectorProxyDataSerializationStrategy instanceVariableNames: '' classVariableNames: '' package: 'GToolkit-RemotePhlow-InspectorCore' returns only the data from which the inspector proxy is initialized.

inspectorProxyData := session 
	evaluateProxyInspectorRawData:  'Object new'
  
inspectorProxyData := session 
	evaluateProxyInspectorRawData:  'GtRemotePhlowDeclarativeTestInspectable new'
  

Once we have the inspector proxy data, we can get an inspector proxy initialized with all relevant data

localProxyInspector := (inspectorProxyData at: 'proxyObject')
	initializeFromProxyData: (inspectorProxyData at: 'proxyData');
	yourself
  

We can also directly get this initialized proxy inspector from any normal proxy using GtRsrProxyServiceClient>>#getLocalProxyInspector getLocalProxyInspector ^ self evaluateProxyInspector: 'self' .

objectProxy getLocalProxyInspectorRawData
  

Util scripts

viewedObject := GtRemotePhlowViewedObject object: 
	GtRemotePhlowDeclarativeTestInspectable new
  
viewedObject getViewsDeclarationsWithPhlowDataSource
  
Object new
  
GtRemotePhlowDeclarativeTestInspectable new