Skip to content

Commit

Permalink
Return an explicit evaluation result when getting the result of the r…
Browse files Browse the repository at this point in the history
…emote execution [feenkcom/gtoolkit#3942]
  • Loading branch information
chisandrei committed Aug 21, 2024
1 parent 24dca41 commit e2aa4e1
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 44 deletions.
61 changes: 41 additions & 20 deletions src/GToolkit-GemStone-Lepiter/GtGemStoneSnippetPromise.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ GtGemStoneSnippetPromise >> coderEvaluationContext: anObject [
coderEvaluationContext := anObject
]

{ #category : #utils }
GtGemStoneSnippetPromise >> createEvaluationResultFromData: aDictionaryOrObject [
"Instantiate an evaluation result object from the given object."

^ GtGemstoneEvaluationResult
createEvaluationResultFromData: aDictionaryOrObject
]

{ #category : #accessing }
GtGemStoneSnippetPromise >> gemStoneSession [
^ gtRsrEvaluatorPromise gtSession
Expand All @@ -50,8 +58,8 @@ GtGemStoneSnippetPromise >> hasResult [

{ #category : #initialization }
GtGemStoneSnippetPromise >> initialize [

super initialize.

value := self.
mutex := Mutex new.
]
Expand All @@ -69,6 +77,22 @@ GtGemStoneSnippetPromise >> isResolved [
value ~~ self ]
]

{ #category : #private }
GtGemStoneSnippetPromise >> resolveWithComputedResult: computedResult [
computedResult associationsDo: [ :binding |
(snippetCoderModel pharoBindings bindingOf: binding key asSymbol)
value: (binding value asGtBareProxyObject) ].

value := (computedResult
at: 'snippetResult'
ifPresent: [ :obj |
coderEvaluationContext serializationStrategy
ifNil: [ obj ]
ifNotNil: [ :strategy | obj
proxyPerform: #yourself serializationStrategy: strategy ] ]
ifAbsent: [ self error: 'no result' ]) asGtBareProxyObject.
]

{ #category : #accessing }
GtGemStoneSnippetPromise >> resolvedValue [
self assert: [ value ~~ self ].
Expand Down Expand Up @@ -108,26 +132,23 @@ GtGemStoneSnippetPromise >> value [

{ #category : #private }
GtGemStoneSnippetPromise >> wait [
| result |
| rawEvaluationResultData evaluationResult computedResult |

executionContext := gtRsrEvaluatorPromise value.
result := executionContext wait.

"We get here in case we terminate the remote process running the async computation and signal the semaphore on which the computation runs. A different way to implement this would be to do a low-level call and get back a result object indicating that the process was terminated. It also works here to check against nil, as we expect to get back a dictionary. If the computation could return nil, this would not work."
result ifNil: [
value := nil.
^ self ].
rawEvaluationResultData := executionContext wait.

result associationsDo: [ :binding |
(snippetCoderModel pharoBindings bindingOf: binding key asSymbol)
value: (binding value asGtBareProxyObject) ].

value := (result
at: 'snippetResult'
ifPresent: [ :obj |
coderEvaluationContext serializationStrategy
ifNil: [ obj ]
ifNotNil: [ :strategy | obj
proxyPerform: #yourself serializationStrategy: strategy ] ]
ifAbsent: [ self error: 'no result' ]) asGtBareProxyObject.
evaluationResult := self createEvaluationResultFromData: rawEvaluationResultData.
self gemStoneSession ifNotNil: [ :aGemStoneSession |
evaluationResult gtPharoProxyInitializeWithSession: aGemStoneSession ].

evaluationResult hasEvaluationException ifTrue: [
evaluationResult := evaluationResult signalGemStoneDebugger.
self gemStoneSession ifNotNil: [ :aGemStoneSession |
evaluationResult gtPharoProxyInitializeWithSession: aGemStoneSession ]. ].

computedResult := evaluationResult computedResult.
computedResult := gtRsrEvaluatorPromise
basicDeserializeResult: evaluationResult computedResult.

self resolveWithComputedResult: computedResult
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Extension { #name : #GtGemstoneEvaluationWithExceptionResult }

{ #category : #'*GToolkit-GemStone-Pharo' }
GtGemstoneEvaluationWithExceptionResult >> signalGemStoneDebugger [
<gemstoneDebuggerSignal>
| exception |

exception := GtRsrEvaluationException new
debuggerProxy: self evaluationContext.
exception signal.

^ exception hasDebugResult
ifTrue: [ GtGemstoneEvaluationWithComputedResult new
computedResult: exception debugResult ]
ifFalse: [ self ]
]
39 changes: 17 additions & 22 deletions src/GToolkit-GemStone-Pharo/GtRsrEvaluatorPromise.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ GtRsrEvaluatorPromise class >> rsrPromise: aPromise serializationStrategy: aSymb
sourceEvaluation: aGtRsrEvaluation
]

{ #category : #accessing }
GtRsrEvaluatorPromise >> basicDeserializeResult: aResult [
^ (self class environment
at: serializationStrategy) new
deserialize: aResult.
]

{ #category : #testing }
GtRsrEvaluatorPromise >> canHandleSpecificDebugger [

Expand All @@ -30,20 +37,10 @@ GtRsrEvaluatorPromise >> canHandleSpecificDebugger [

{ #category : #private }
GtRsrEvaluatorPromise >> createEvaluationResultFromData: aDictionaryOrObject [
"Instantiate an evaluation result object from the given object.
We need to handle the case of the previous way of returning data."

^ (GtGemstoneEvaluationResult isSerializedData: aDictionaryOrObject)
ifTrue: [
GtGemstoneEvaluationResult fromDictionary: aDictionaryOrObject ]
ifFalse: [
rsrPromise value class = GtpoGtGemStoneEvaluationContext
ifTrue: [
GtGemstoneEvaluationWithExceptionResult new
evaluationContext: aDictionaryOrObject ]
ifFalse: [
GtGemstoneEvaluationWithComputedResult new
computedResult:aDictionaryOrObject ] ]
"Instantiate an evaluation result object from the given object."

^ GtGemstoneEvaluationResult
createEvaluationResultFromData: aDictionaryOrObject
]

{ #category : #accessing }
Expand All @@ -54,9 +51,7 @@ GtRsrEvaluatorPromise >> deserializeResult: aResult [
aGtSession logEmitter
emitEvaluationDeserializeResultStartFor: sourceEvaluation ].

deserializedResult := (self class environment
at: serializationStrategy) new
deserialize: aResult.
deserializedResult := self basicDeserializeResult: aResult.

gtSession ifNotNil: [ :aGtSession |
aGtSession logEmitter
Expand Down Expand Up @@ -176,18 +171,18 @@ GtRsrEvaluatorPromise >> wait [
rawEvaluationResultData := rsrPromise wait ].

evaluationResult := self createEvaluationResultFromData: rawEvaluationResultData.
gtSession ifNotNil: [
evaluationResult gtPharoProxyInitializeWithSession: gtSession ].
gtSession ifNotNil: [ :aGemStoneSession |
evaluationResult gtPharoProxyInitializeWithSession: aGemStoneSession ].

"Temporarily handle the old post-mortem debugger notification"
rawEvaluationResultData class = GtpoGtRsrEvaluationExceptionInformation
ifTrue: [ self error: 'Evaluation error, see result' ].

self isGtEvaluationException ifTrue: [
evaluationResult := self signalGemStoneDebugger ].
evaluationResult := self signalGemStoneDebugger.
gtSession ifNotNil: [ :aGemStoneSession |
evaluationResult gtPharoProxyInitializeWithSession: aGemStoneSession ]. ].

gtSession ifNotNil: [
evaluationResult gtPharoProxyInitializeWithSession: gtSession ].
computedResult := serializationStrategy
ifNil: [ evaluationResult computedResult ]
ifNotNil: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,13 @@ GtRsrEvaluatorServiceClient >> evaluateAsyncScript: aGtRsrScriptEvaluation [
bindings: resolvedBindings
serializationStrategy: aGtRsrScriptEvaluation serialisationStrategy.

"When making an async call we need to use the legacy serialisation strategy,
as that one is used to get back the data about the remote execution. We could
later on explicitly pass a serialisation strategy to be used for the initial
call that starts the async execution."
GtRsrEvaluatorPromise
rsrPromise: rsrPromise
serializationStrategy: aGtRsrScriptEvaluation serialisationStrategy
serializationStrategy: #GtRsrLegacySerializationStrategy
gtSession: gtSession
autoCommit: aGtRsrScriptEvaluation autoCommit
sourceEvaluation: aGtRsrScriptEvaluation ]
Expand Down
22 changes: 22 additions & 0 deletions src/GToolkit-GemStone/GtGemstoneEvaluationResult.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@ Class {
#category : #'GToolkit-GemStone'
}

{ #category : #'instance creation' }
GtGemstoneEvaluationResult class >> createEvaluationResultFromData: aDictionaryOrObject [
"Instantiate an evaluation result object from the given object.
We need to handle the case of the previous way of returning data."

^ (self isSerializedData: aDictionaryOrObject)
ifTrue: [ self fromDictionary: aDictionaryOrObject ]
ifFalse: [
aDictionaryOrObject class = GtpoGtGemStoneEvaluationContext
ifTrue: [
GtGemstoneEvaluationWithExceptionResult new
evaluationContext: aDictionaryOrObject ]
ifFalse: [
GtGemstoneEvaluationWithComputedResult new
computedResult:aDictionaryOrObject ] ]
]

{ #category : #'instance creation' }
GtGemstoneEvaluationResult class >> fromJSONDictionary: aDictionary [
^ self new
Expand Down Expand Up @@ -32,6 +49,11 @@ GtGemstoneEvaluationResult >> computedResult [
^ self subclassResponsibility
]

{ #category : #testing }
GtGemstoneEvaluationResult >> hasEvaluationException [
^ false
]

{ #category : #'initialization ' }
GtGemstoneEvaluationResult >> initializeFromJSONDictionary: aDictionary [
]
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@ Class {
#category : #'GToolkit-GemStone'
}

{ #category : #'as yet unclassified' }
{ #category : #testing }
GtGemstoneEvaluationWithExceptionResult >> canHandleSpecificDebugger [
^ true
]

{ #category : #accessing }
GtGemstoneEvaluationWithExceptionResult >> computedResult [
^ self evaluationContext
]
Expand All @@ -27,6 +32,11 @@ GtGemstoneEvaluationWithExceptionResult >> gtPharoProxyInitializeWithSession: aG
evaluationContext gtPharoProxyInitializeWithSession: aGemStoneSession
]

{ #category : #testing }
GtGemstoneEvaluationWithExceptionResult >> hasEvaluationException [
^ true
]

{ #category : #'initialization ' }
GtGemstoneEvaluationWithExceptionResult >> initializeFromJSONDictionary: aDictionary [
super initializeFromJSONDictionary: aDictionary.
Expand Down

0 comments on commit e2aa4e1

Please sign in to comment.