public void Execute(Action <IActorRuntime, ITestingRuntime> action, IScheduler scheduler) { runtime = new TestingActorRuntime(scheduler); // TODO: Remove this somehow. TaskHelper.runtime = runtime; var task = new Task(() => { TestingActorRuntime.ActorBody <object>( () => { action(runtime, runtime); return(null); }, runtime, true); }, CancellationToken.None, TaskCreationOptions.RunContinuationsAsynchronously); runtime.RegisterMainTask(task); task.Start(taskScheduler); task.Wait(); runtime.WaitForAllActorsToTerminate(); }
public ActorInfo( ActorId id, string name, Task task, CancellationTokenSource cts, TestingActorRuntime runtime) { this.id = id; this.task = task; this.name = name; this.cts = cts; Mailbox = new Mailbox <object>(this, runtime); terminateWaiters = new HashSet <ActorInfo>(); exceptions = new List <Exception>(); }
public Mailbox(ActorInfo ownerActorInfo, TestingActorRuntime runtime) { this.ownerActorInfo = ownerActorInfo; this.runtime = runtime; mailbox = new List <T>(); }
public static T ActorBody <T>( Func <T> func, TestingActorRuntime runtime, bool mainThread, ActorInfo info = null) { if (info == null) { info = runtime.GetCurrentActorInfo(); } lock (info.mutex) { Safety.Assert(info.active); info.currentOp = OpType.START; if (!mainThread) { info.active = false; Monitor.PulseAll(info.mutex); while (!info.active) { Monitor.Wait(info.mutex); } } } try { return(func()); } catch (OperationCanceledException ex) { lock (info.mutex) { if (info.cts.Token == ex.CancellationToken && info.cts.IsCancellationRequested) { info.cancelled = true; } info.exceptions.Add(ex); } throw; } catch (ActorTerminatedException ex) { if (mainThread && runtime.error == null) { runtime.error = new Exception("Main actor did not terminate.", ex); } } catch (Exception ex) { runtime.error = ex; runtime.terminated = true; runtime.ActivateAllActors(); } finally { try { if (!runtime.terminated) { runtime.Schedule(OpType.END, info); lock (info.mutex) { info.enabled = false; info.terminated = true; foreach (var waiter in info.terminateWaiters) { waiter.enabled = true; } info.terminateWaiters.Clear(); } runtime.Schedule(OpType.END, info); } } catch (ActorTerminatedException) { } finally { lock (info.mutex) { info.terminated = true; } } } return(default(T)); }