How to - managing remote bindings in a GemStone snippets

GemStone snippets can define and use variable bindings. The values for these bindigs can be sent when executing code remotely, and also send to the remote side.

The main logic for handling remote bindings is handled by GtGemStoneSnippetRemoteExecutionBuilder Object subclass: #GtGemStoneSnippetRemoteExecutionBuilder instanceVariableNames: 'sourceString localBindings remoteBindings visitor sourceAst gemstoneSession classSlotNames' classVariableNames: '' package: 'GToolkit-GemStone-Lepiter-Coder' . This builder takes as input a set of local bindings and the code to be executed, and computes the set of bingings that need to sent to the remote side (GtGemStoneSnippetRemoteExecutionBuilder>>#remoteBindings remoteBindings remoteBindings ifNil: [ self extractRemoteBindings]. ^ remoteBindings ), and the source code that should be executed remotely (GtGemStoneSnippetRemoteExecutionBuilder>>#generateRemoteScript generateRemoteScript | trimmedString targetSource lastStatement leftBar extraTemporaries | remoteBindings ifNil: [ self extractRemoteBindings ]. trimmedString := sourceString trimRight. targetSource := SmaCCString on: trimmedString. trimmedString last = $. ifFalse: [ targetSource append: '.' ]. lastStatement := sourceAst statements last. leftBar := sourceAst leftBar ifNotNil: [ sourceAst leftBar startPosition ]. extraTemporaries := self remoteCodeExtraTemporaryNames. "Construct the script to be evaluated on the remote (GemStone server): 1. Add any undeclared variables names to the script's list of temporaries" self insert: extraTemporaries asTemporariesIn: targetSource leftBarPosition: leftBar. "2. Assign the final statement to snippetResult" targetSource insert: 'snippetResult := ' at: lastStatement startPosition. "3. Answer a dictionary containing the returned variables" targetSource append: (self returnExpressionWithNames: self variableNamesToReturn). ^ targetSource asString. ) . Remote bindings are modeled as instanced of type GtGemStoneWorkspaceVariable WorkspaceVariable subclass: #GtGemStoneWorkspaceVariable instanceVariableNames: 'gemstoneSession errorDisplayPosition' classVariableNames: '' package: 'GToolkit-GemStone-Lepiter-Coder' .

Example

As an example we can consider the following code:

From it when extracting binding if a, b and e have a value they are sent as remote binding.

Code snippets

These are code snippets for programatically creating a builder and interacting with it

Snippet with variable written first

As a first step we need to define a builder and set the local bindings

localBindings := GtSharedVariablesBindings new.
  
(localBindings bindingOf: #a) value: 42.
  
builder := GtGemStoneSnippetRemoteExecutionBuilder new 
	localBindings: localBindings;
	sourceString: '
a := 1
a + 1'.
  

Once the builder is set we can get the remote bindings and the remote script

builder remoteBindings.
  
builder generateRemoteScript
  

Snippet with multiple variables

localBindings := GtSharedVariablesBindings new.
  

Set valid bindings

(localBindings bindingOf: #a) value: 42.
(localBindings bindingOf: #b) value: 43.
(localBindings bindingOf: #c) value: 44.
  

Set two invalid bindings

(localBindings bindingOf: #a) value: 42.
(localBindings bindingOf: #b) value: GspoString new.
(localBindings bindingOf: #c) value: GspoString new.
  
builder := GtGemStoneSnippetRemoteExecutionBuilder new 
	localBindings: localBindings;
	sourceString: '
a + c + d
'.
  
builder remoteBindings.
  
builder generateRemoteScript