Skip to content

Commit

Permalink
Simplify interface to use volatile hosts
Browse files Browse the repository at this point in the history
Reduce dependencies on specifics of CSharp scripting. Get close to expected more stable interface: Do not support the execution of a different script for each request to the volatile host.
  • Loading branch information
Viir committed Feb 11, 2020
1 parent c9c19f8 commit 8b4b22f
Show file tree
Hide file tree
Showing 13 changed files with 416 additions and 282 deletions.
Expand Up @@ -73,11 +73,11 @@ public class HttpResponse
public HttpHeader[] headersToAdd;
}

public class Result<Err, Ok>
public class Result<ErrT, OkT>
{
public Err err;
public ErrT Err;

public Ok ok;
public OkT Ok;
}

public class ResultFromTaskWithId
Expand All @@ -89,23 +89,28 @@ public class ResultFromTaskWithId

public class TaskResult
{
public Result<object, CreateVolatileHostComplete> createVolatileHostResponse;
public Result<CreateVolatileHostErrorStructure, CreateVolatileHostComplete> CreateVolatileHostResponse;

public Result<RunInVolatileHostError, RunInVolatileHostComplete> runInVolatileHostResponse;
public Result<RequestToVolatileHostError, RequestToVolatileHostComplete> RequestToVolatileHostResponse;

public object completeWithoutResult;
public object CompleteWithoutResult;

public class CreateVolatileHostErrorStructure
{
public string exceptionToString;
}

public class CreateVolatileHostComplete
{
public string hostId;
}

public class RunInVolatileHostError
public class RequestToVolatileHostError
{
public object hostNotFound;
public object HostNotFound;
}

public class RunInVolatileHostComplete
public class RequestToVolatileHostComplete
{
public string exceptionToString;

Expand All @@ -124,20 +129,25 @@ public class StartTask

public class Task
{
public object createVolatileHost;
public CreateVolatileHostStructure CreateVolatileHost;

public RunInVolatileHost runInVolatileHost;
public RequestToVolatileHostStructure RequestToVolatileHost;

public ReleaseVolatileHost releaseVolatileHost;
public ReleaseVolatileHostStructure ReleaseVolatileHost;

public class RunInVolatileHost
public class CreateVolatileHostStructure
{
public string script;
}

public class RequestToVolatileHostStructure
{
public string hostId;

public string script;
public string request;
}

public class ReleaseVolatileHost
public class ReleaseVolatileHostStructure
{
public string hostId;
}
Expand Down
Expand Up @@ -11,7 +11,7 @@

namespace Kalmit
{
public class CSharpScriptContext
public class VolatileHost
{
readonly object @lock = new object();

Expand All @@ -21,17 +21,24 @@ public class CSharpScriptContext

Func<byte[], byte[]> getFileFromHashSHA256;

public CSharpScriptContext(Func<byte[], byte[]> getFileFromHashSHA256)
public VolatileHost(
Func<byte[], byte[]> getFileFromHashSHA256,
string csharpScript)
{
this.getFileFromHashSHA256 = getFileFromHashSHA256;

metadataResolver = new MetadataResolver(getFileFromHashSHA256);

var runSetupScriptResult = RunScript(csharpScript);

if (runSetupScriptResult.Exception != null)
throw new Exception("Failed to setup the volatile host:" + runSetupScriptResult.Exception.ToString());
}

/// <summary>
/// Based on example from https://github.com/dotnet/roslyn/wiki/Scripting-API-Samples#-continue-script-execution-from-a-previous-state
/// </summary>
public RunResult RunScript(string script)
private RunResult RunScript(string script)
{
lock (@lock)
{
Expand Down Expand Up @@ -68,6 +75,16 @@ public RunResult RunScript(string script)
}
}

public RunResult ProcessRequest(string request)
{
return RunScript(requestExpression(request));
}

static string requestExpression(string request)
{
return "InterfaceToHost_Request(\"" + request.Replace(@"\", @"\\").Replace("\"", "\\\"") + "\")";
}

class MetadataResolver : MetadataReferenceResolver
{
readonly object @lock = new object();
Expand Down
68 changes: 43 additions & 25 deletions implement/PersistentProcess/PersistentProcess.WebHost/Startup.cs
Expand Up @@ -159,32 +159,32 @@ static PersistentProcessWithHistoryOnFileFromElm019Code BuildPersistentProcess(I

var createVolatileHostAttempts = 0;

var volatileHosts = new ConcurrentDictionary<string, CSharpScriptContext>();
var volatileHosts = new ConcurrentDictionary<string, VolatileHost>();

InterfaceToHost.Result<InterfaceToHost.TaskResult.RunInVolatileHostError, InterfaceToHost.TaskResult.RunInVolatileHostComplete>
performProcessTaskRunInVolatileHost(
InterfaceToHost.Task.RunInVolatileHost runInVolatileHost)
InterfaceToHost.Result<InterfaceToHost.TaskResult.RequestToVolatileHostError, InterfaceToHost.TaskResult.RequestToVolatileHostComplete>
performProcessTaskRequestToVolatileHost(
InterfaceToHost.Task.RequestToVolatileHostStructure requestToVolatileHost)
{
if (!volatileHosts.TryGetValue(runInVolatileHost.hostId, out var volatileHost))
if (!volatileHosts.TryGetValue(requestToVolatileHost.hostId, out var volatileHost))
{
return new InterfaceToHost.Result<InterfaceToHost.TaskResult.RunInVolatileHostError, InterfaceToHost.TaskResult.RunInVolatileHostComplete>
return new InterfaceToHost.Result<InterfaceToHost.TaskResult.RequestToVolatileHostError, InterfaceToHost.TaskResult.RequestToVolatileHostComplete>
{
err = new InterfaceToHost.TaskResult.RunInVolatileHostError
Err = new InterfaceToHost.TaskResult.RequestToVolatileHostError
{
hostNotFound = new object(),
HostNotFound = new object(),
}
};
}

var stopwatch = System.Diagnostics.Stopwatch.StartNew();

var fromVolatileHostResult = volatileHost.RunScript(runInVolatileHost.script);
var fromVolatileHostResult = volatileHost.ProcessRequest(requestToVolatileHost.request);

stopwatch.Stop();

return new InterfaceToHost.Result<InterfaceToHost.TaskResult.RunInVolatileHostError, InterfaceToHost.TaskResult.RunInVolatileHostComplete>
return new InterfaceToHost.Result<InterfaceToHost.TaskResult.RequestToVolatileHostError, InterfaceToHost.TaskResult.RequestToVolatileHostComplete>
{
ok = new InterfaceToHost.TaskResult.RunInVolatileHostComplete
Ok = new InterfaceToHost.TaskResult.RequestToVolatileHostComplete
{
exceptionToString = fromVolatileHostResult.Exception?.ToString(),
returnValueToString = fromVolatileHostResult.ReturnValue?.ToString(),
Expand All @@ -195,39 +195,57 @@ static PersistentProcessWithHistoryOnFileFromElm019Code BuildPersistentProcess(I

InterfaceToHost.TaskResult performProcessTask(InterfaceToHost.Task task)
{
if (task?.createVolatileHost != null)
if (task?.CreateVolatileHost != null)
{
var volatileHostId = System.Threading.Interlocked.Increment(ref createVolatileHostAttempts).ToString();
try
{
var volatileHost = new VolatileHost(BlobLibrary.GetBlobWithSHA256, task?.CreateVolatileHost.script);

volatileHosts[volatileHostId] = new CSharpScriptContext(BlobLibrary.GetBlobWithSHA256);
var volatileHostId = System.Threading.Interlocked.Increment(ref createVolatileHostAttempts).ToString();

return new InterfaceToHost.TaskResult
volatileHosts[volatileHostId] = volatileHost;

return new InterfaceToHost.TaskResult
{
CreateVolatileHostResponse = new InterfaceToHost.Result<InterfaceToHost.TaskResult.CreateVolatileHostErrorStructure, InterfaceToHost.TaskResult.CreateVolatileHostComplete>
{
Ok = new InterfaceToHost.TaskResult.CreateVolatileHostComplete
{
hostId = volatileHostId,
},
},
};
}
catch (Exception createVolatileHostException)
{
createVolatileHostResponse = new InterfaceToHost.Result<object, InterfaceToHost.TaskResult.CreateVolatileHostComplete>
return new InterfaceToHost.TaskResult
{
ok = new InterfaceToHost.TaskResult.CreateVolatileHostComplete
CreateVolatileHostResponse = new InterfaceToHost.Result<InterfaceToHost.TaskResult.CreateVolatileHostErrorStructure, InterfaceToHost.TaskResult.CreateVolatileHostComplete>
{
hostId = volatileHostId,
Err = new InterfaceToHost.TaskResult.CreateVolatileHostErrorStructure
{
exceptionToString = createVolatileHostException.ToString(),
},
},
},
};
};
}
}

if (task?.releaseVolatileHost != null)
if (task?.ReleaseVolatileHost != null)
{
volatileHosts.TryRemove(task?.releaseVolatileHost.hostId, out var volatileHost);
volatileHosts.TryRemove(task?.ReleaseVolatileHost.hostId, out var volatileHost);

return new InterfaceToHost.TaskResult
{
completeWithoutResult = new object(),
CompleteWithoutResult = new object(),
};
}

if (task?.runInVolatileHost != null)
if (task?.RequestToVolatileHost != null)
{
return new InterfaceToHost.TaskResult
{
runInVolatileHostResponse = performProcessTaskRunInVolatileHost(task?.runInVolatileHost),
RequestToVolatileHostResponse = performProcessTaskRequestToVolatileHost(task?.RequestToVolatileHost),
};
}

Expand Down

0 comments on commit 8b4b22f

Please sign in to comment.