1 module tagion.testbench.actor.taskfailure; 2 3 import tagion.testbench.actor.util; 4 5 // Default import list for bdd 6 import core.time; 7 import std.format : format; 8 import std.stdio; 9 import std.typecons : Tuple; 10 import tagion.actor.actor; 11 import tagion.actor.exceptions; 12 import tagion.basic.tagionexceptions; 13 import tagion.behaviour; 14 import tagion.hibon.Document; 15 import tagion.testbench.tools.Environment; 16 import tagion.utils.pretend_safe_concurrency; 17 18 enum feature = Feature( 19 "Actor TaskFailure", 20 ["While there is no handling of that type of taskfailure resend it up to the owner."]); 21 22 alias FeatureContext = Tuple!( 23 SendATaskFailureToAnActor, "SendATaskFailureToAnActor", 24 FeatureGroup*, "result" 25 ); 26 27 enum actor_task = "actor_task"; 28 29 @safe 30 struct MyActor { 31 void task() nothrow { 32 run(); 33 } 34 } 35 36 @safe @Scenario("Send a TaskFailure to an actor", 37 []) 38 class SendATaskFailureToAnActor { 39 ActorHandle myActor; 40 41 @Given("an #actor") 42 Document anActor() { 43 myActor = spawn!MyActor(actor_task); 44 45 return result_ok; 46 } 47 48 @When("the #actor has started") 49 Document actorHasStarted() { 50 check(waitforChildren(Ctrl.ALIVE), "Actor never alived"); 51 check(myActor.tid !is Tid.init, "Actor task is not running"); 52 53 return result_ok; 54 } 55 56 @Then("send a `TaskFailure` to the actor") 57 Document toTheActor() { 58 myActor.send(TaskFailure("main", new immutable Exception("This big fail"))); 59 return result_ok; 60 } 61 62 @Then("the actor should echo it back to the main thread") 63 Document theMainThread() { 64 bool received = receiveTimeout( 65 1.seconds, 66 (TaskFailure tf) @safe { 67 writefln("Task failed succesfully with: %s, %s", typeid(tf.throwable), tf.throwable.msg); 68 }, 69 (Variant val) @trusted { check(0, format("Unexpected value: %s", val)); } 70 ); 71 check(received, "Timed out before receiving taskfailure"); 72 return result_ok; 73 } 74 75 @Then("stop the #actor") 76 Document stopTheActor() { 77 myActor.send(Sig.STOP); 78 check(waitforChildren(Ctrl.END), "Actor never stopped"); 79 return result_ok; 80 } 81 82 }