@@ -22,19 +22,48 @@ namespace Synapse.Runner.Services.Executors;
22
22
/// <param name="executorFactory">The service used to create <see cref="ITaskExecutor"/>s</param>
23
23
/// <param name="context">The current <see cref="ITaskExecutionContext"/></param>
24
24
/// <param name="serializer">The service used to serialize/deserialize objects to/from JSON</param>
25
- public class ScriptProcessExecutor ( IServiceProvider serviceProvider , ILogger < ScriptProcessExecutor > logger , ITaskExecutionContextFactory executionContextFactory , ITaskExecutorFactory executorFactory , ITaskExecutionContext < RunTaskDefinition > context , IJsonSerializer serializer )
25
+ /// <param name="externalResourceProvider">The service used to resolve external resources</param>
26
+ /// <param name="scriptExecutorProvider">The service used to provide <see cref="IScriptExecutor"/>s</param>
27
+ public class ScriptProcessExecutor ( IServiceProvider serviceProvider , ILogger < ScriptProcessExecutor > logger , ITaskExecutionContextFactory executionContextFactory , ITaskExecutorFactory executorFactory ,
28
+ ITaskExecutionContext < RunTaskDefinition > context , IJsonSerializer serializer , IExternalResourceProvider externalResourceProvider , IScriptExecutorProvider scriptExecutorProvider )
26
29
: TaskExecutor < RunTaskDefinition > ( serviceProvider , logger , executionContextFactory , executorFactory , context , serializer )
27
30
{
28
31
32
+ /// <summary>
33
+ /// Gets the service used to resolve external resources
34
+ /// </summary>
35
+ protected IExternalResourceProvider ExternalResourceProvider { get ; } = externalResourceProvider ;
36
+
37
+ /// <summary>
38
+ /// Gets the service used to provide <see cref="IScriptExecutor"/>s
39
+ /// </summary>
40
+ protected IScriptExecutorProvider ScriptExecutorProvider { get ; } = scriptExecutorProvider ;
41
+
29
42
/// <summary>
30
43
/// Gets the definition of the script process to run
31
44
/// </summary>
32
45
protected ScriptProcessDefinition ProcessDefinition => this . Task . Definition . Run . Script ! ;
33
46
34
47
/// <inheritdoc/>
35
- protected override Task DoExecuteAsync ( CancellationToken cancellationToken )
48
+ protected override async Task DoExecuteAsync ( CancellationToken cancellationToken )
36
49
{
37
- return System . Threading . Tasks . Task . CompletedTask ; //todo: implement
50
+ var executor = this . ScriptExecutorProvider . GetExecutor ( this . ProcessDefinition . Language ) ?? throw new NullReferenceException ( $ "Failed to find a script executor for the specified language '{ this . ProcessDefinition . Language } '") ;
51
+ var script = this . ProcessDefinition . Code ;
52
+ if ( string . IsNullOrWhiteSpace ( script ) )
53
+ {
54
+ if ( this . ProcessDefinition . Source == null ) throw new NullReferenceException ( "The script's code or resource must be set" ) ;
55
+ using var stream = await this . ExternalResourceProvider . ReadAsync ( this . Task . Workflow . Definition , this . ProcessDefinition . Source , cancellationToken ) . ConfigureAwait ( false ) ;
56
+ using var streamReader = new StreamReader ( stream ) ;
57
+ script = await streamReader . ReadToEndAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
58
+ }
59
+ using var process = await executor . ExecuteAsync ( script , null , this . ProcessDefinition . Environment , cancellationToken ) . ConfigureAwait ( false ) ;
60
+ await process . WaitForExitAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
61
+ var stdOut = await process . StandardOutput . ReadToEndAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
62
+ var stdErr = await process . StandardError . ReadToEndAsync ( cancellationToken ) . ConfigureAwait ( false ) ;
63
+ //todo: urgent: fix the script process so that we provide:
64
+ //1. (evaluated) arguments
65
+ //2. (evaluated) environment variables
66
+ //3. a way to decide, like for shell, where to read the output from: stdOut, file? or (exit) code
38
67
}
39
68
40
69
}
0 commit comments