Remote Runner: Debugging and performance

In the event that tasks fail or perform badly information is returned with the task results to assist in tracking down the issue.

If a task raises an exception wihle being executed, e.g.:

GtRemoteRunner default submitJob:
	(GtRrJob script: 'self error: ''task error''')
  

the error will be reported and a stack trace, similar to the one written to PharoDebug.log, will be included:

taskWithErrorTrace
	"Answer a task that raised an error during execution"
	<gtExample>
	| errorMessage task |

	errorMessage := 'error during task execution'.
	task := GtRrScriptTask script: 'self error: ', errorMessage printString.
	self runInImageTask: task.

	self assert: task result isNil
		description: 'Task has unexpected result'.
	self assert: task executionData errorDetails errorMessage
		equals: errorMessage.
	^ task.
    

The Trace view includes a button to parse the detailed stack trace so a summary of the stack and individual frames can be inspected:

pharoDebugLogInspector
	"Answer a GtPharoDebugLogInspector for a task with errors"
	<gtExample>

	^ (GtPharoDebugLogInspector new string: 
		self taskWithErrorTrace executionData errorDetails trace) 
			parseLogEntries first.
    

For checks (examples and tests): errors that occur as part of running the check are reported for individual checks rather than the task as a whole.

While the stack trace and other logging provided by the workers is useful, sometimes custom logs or other information may be useful for debugging. To handle this tasks have pre- and post- actions.

An action is a subclass of GtRrPrePostTaskAction Object << #GtRrPrePostTaskAction slots: {}; tag: 'PrePostTaskActions'; package: 'RemoteRunner' .

See GtRrMemoryLoggerPrePostTaskAction GtRrPrePostTaskAction << #GtRrMemoryLoggerPrePostTaskAction slots: { #logger }; tag: 'PrePostTaskActions'; package: 'RemoteRunner' as an example of collecting custom log information with the MethodStackSignal ThisContextSignal << #MethodStackSignal slots: {}; package: 'Beacon-ExtraSignals' .

The list of actions to be performed is set in the task:

taskWithPrePostAction
	"Answer a task that has a pre- and post- action set"
	<gtExample>
	| task |

	task := GtRrScriptTask script: 'MethodStackSignal emit'.
	task prePostTaskActions: #(GtRrMemoryLoggerPrePostTaskAction).
	^ task.
    

Once the task has been executed the logger is available from the tasks execution data:

taskWithCustomMemoryLogger
	"Answer the MemoryLogger collected as part of a task prePostAction"
	<gtExample>
	| task logger |

	task := self taskWithPrePostAction.
	self runInImageTask: task.

	logger := STON fromString: (task executionData additionalData at: #logger).
	self assert: logger recordings size equals: 1.
	^ logger.