by

Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Noel
    @nanderto

    @pdeligia Thanks for taking a look. Yes I was returning a Coyote task instead of a System.Threading.Tasks task . Interestingly If I change to a System.Threading.Tasks then my code still compiles and runs in the website. This below is the method that is called and it returns a System.Threading.Tasks.Task

    public async Task IncrementCount()
     {
         var request = new RequestEvent<int, int>(IncrementAmount);
         AddActor = runtime.CreateActor(typeof(AddActor), request);
         var response = await request.Completed.Task;
         CurrentCount = CurrentCount + response;
         runtime.SendEvent(AddActor, HaltEvent.Instance);
     }

    This actually works in the website even though the requested.Completed.Task is a coyote task, but it does not work in the unit test.
    The sample you provide also does not work as there is no runtime available to pass into the method. Besides which, I am not looking to replace the how the Coyote test engine works I just want to be able to run unit tests.

    Pantazis Deligiannis
    @pdeligia

    @nanderto sorry my code snippet was incomplete, this is how you pass the runtime:

    TestingEngine engine = TestingEngine.Create(configuration, async runtime =>
    {
       ...
    });

    Btw, my code does not try to replace how the Coyote test engine works, it shows you how to run a Coyote test from inside another unit testing framework (MSTest, Xunit) using the Coyote systematic testing engine :)

    You can think of the Coyote testing engine as its own "unit test runner for Coyote". The TestingEngine will create a special "systematic testing mode" Coyote runtime and pass it to your test via dependency injection. You are not supposed to create your own Coyote runtime during systematic testing (only in production).

    E.g. see how tests are written here: https://github.com/microsoft/coyote-samples/blob/master/HelloWorldActors/Program.cs. Notice that a runtime is passed as input parameter (and not created by the user), when writing a test method using the Microsoft.Coyote.TestingServices.Test attribute (https://github.com/microsoft/coyote-samples/blob/master/HelloWorldActors/Program.cs#L38), but in the Main method you explicitly create a runtime (https://github.com/microsoft/coyote-samples/blob/master/HelloWorldActors/Program.cs#L16) since that is invoked in production.

    However, using the Microsoft.Coyote.TestingServices.Test only works when running tests with our coyote test command line tool (see https://microsoft.github.io/coyote/learn/tools/testing). What I described above does the same thing but allows you to integrate with other unit testing frameworks like MSTest or Xunit.

    Hope this clarifies your question?

    @nanderto if you just want to run a regular unit test, without the systematic testing capability that coyote test gives you, then you can do this:

            [TestMethod]
            public async System.Threading.Tasks.Task IncrementCountTestAsnc()
            {
                ICoyoteRuntime runtime = new CoyoteRuntime();
                var viewmodel = new SecondCoyoteLibrary.Pages.CounterViewModel(runtime);
    
                viewmodel.CurrentCount = 10;
                viewmodel.IncrementAmount = 3;
                await viewmodel.IncrementCount();
                Assert.AreEqual(13, viewmodel.CurrentCount);
            }

    Notice how I changed the signature of the method to return a regular C# task. Thats all you need to run this. System tasks and Coyote tasks can work together in production :) But doing this approach will result in a flaky test as the concurrency is not controlled, whereas the approach that I described in my last post will result in Coyote controlling the concurrency and systematically exploring interleavings to find bugs in your unit test!

    Noel
    @nanderto
    Not sure what happened yesterday, having the test return a System.Threading.Tasks.Task was not working, but after updating some (xunit) extensions and Visual studio, it started working. So that was great, thanks for the help. I also have the Coyote Test runner running as part of the unit tests as well, although it does not return the exception expected, I can at least keep moving forward. Again thanks for the help
    Kapil Khandelwal
    @kapil_k_twitter
    Hi, I was working on implementing a Coyote State Machine (Master) which will be receiving all the events of specific types. This Master State Machine will be responsible for creating & distributing these events to fixed set of Worker State Machines for actual event processing. I have achieved that part. But now I need to implement some sort of priority queue implementation such that each Worker State Machine maintain a priority queue of events & those having higher priority are processed first. I was not sure how can enqueue all pending events of specific type in my priority queue collection while the Worker Machine is still in "Processing" state i.e. working on particular event processing.
    Akash Lal
    @akashlal
    @kapil_k_twitter Great to hear that you're making progress. Coyote Actors currently only have a FIFO queue for inbox. They don't support priority queues at the moment. It seems you are trying to implement your own priority queue inside the actor? It won't be easy because actors are single threaded. You will need some kind of polling. Thinking out loud, what about the following: your actor periodically sends a special message to itself. The actor dequeues all messages and stashes it in its priority queue until it gets this special message. At this point, it sends the special message to itself and then starts processing its priority queue. Once its priority queue is empty, it goes back to dequeing from its inbox. You get "bounded priority queue" in this case, because you won't be fully able to respect priority of messages in the inbox.
    @kapil_k_twitter Perhaps easiest is to extend the Coyote Actor inbox implementation to have priorities. Feel free to open an issue on it. An example use case would also be useful.
    Chris Lovett
    @lovettchris
    To help implement a priority queue you can use the WildCard event handler which can handle all events sent to your actor, your actor can then put them in a priority queue for handling in the right order. The "special message to self" could be a TimerElapsedEvent from StartPeriodicTimer.
    Kapil Khandelwal
    @kapil_k_twitter
    @akashlal @lovettchris Thanks for your response. Will try out your suggestions.
    Lane Kelly
    @lanekelly

    This command doesn't seem to work out of the box: dotnet tool install --global Microsoft.Coyote.CLI

    The error is that the package cannot be found. Is there a prereq I'm missing?

    2 replies
    Pantazis Deligiannis
    @pdeligia
    Hi @lanekelly, there is some issue with publishing the new signed Microsoft.Coyote.CLI package on NuGet that is used to install coyote as a dotnet tool, we are trying to resolve it with the nuget team so hopefully it will not be long until we can publish it, and then you will be able to update it (just realized that we pushed the above command in the docs without the package, sorry for the confusion)
    Lane Kelly
    @lanekelly
    Gotcha, thanks
    Lane Kelly
    @lanekelly
    One issue I'm running into with using Coyote with asynchronous tasks is that I'm not able to use types like ConcurrentDictionary or System.Threading.Channels.Channel since they only expose System.Threading.Tasks.Task/ValueTask. I was hoping to use these sorts of primitives to mock things like service bus queues, but it seems I will have to reimplement them myself to work with the Coyote task type. Any advice on how to proceed from here?
    Akash Lal
    @akashlal
    @lanekelly There shouldn't be any issues with using ConcurrentDictionary. I don't see any of its methods returning a native Task. For improved test coverage, make sure to insert a ExploreContextSwitch before calling any method on a ConcurrentDictionary. Let me look up the Channel type, haven't used it before ...
    Lane Kelly
    @lanekelly
    @akashlal, you're right, I should have specified only Channel as the one with an issue. I suppose I could use BlockingCollection instead with an async wrapper to mock a queue
    Akash Lal
    @akashlal
    @lanekelly I think a bit of work would be required to mock Channel. Ideally, you should mock it in the same way that we mocked TaskCompletionSource. But this implementation uses some internal APIs that make the mocking easy. We are going to consider making these APIs public so that your exercise will be simpler. For now, maybe you can have a simple mock.
    Lane Kelly
    @lanekelly
    @akashlal , thanks. I was just using Channel as a potential way to mock a queue, it's not something I want to mock myself. I ended up using ConcurrentQueue with some async wrapper methods, which is working well
    wanton7
    @wanton7
    Does Coyote support virtual actors similar to Orleans & Dapr? Or is something like UsersActor with specific name the way to go that handles multiple users state? Maybe even using consistent hashing for user id and create UsersActor per cpu core if performance is needed.
    Akash Lal
    @akashlal
    @wanton7 Coyote actors are not virtual. Because they are in-memory, there is no concept of activating/deactivating or moving actors. If you want such functionality, you will have to implement it yourself. I'm not sure what you mean by "UsersActor". What is that?
    wanton7
    @wanton7
    @akashlal having virtual actors doesn't mean they are moved anywhere. You can have virtual actors just in single machine. "UsersActor" would be just actor that keeps and handles state for multiple users. This the way I've done it when I've been using Elixir. It's actor that coordinates state (cache) management for multiple users. In Orleans we have had UserGrain presenter single user and it's state (cache).
    1 reply
    Akash Lal
    @akashlal
    @wanton7 Ok, so you can use a string to create ActorId via ActorRuntime.CreateActorIdFromName and then send messages to that actor. But you still need to create an Actor before you can Send to it.
    Noel
    @nanderto
    I am trying to use the replay command to debug and find the bug, but I don't see from the instructions where visual studio is supposed to find the source code from. The IDE opens up it appears to be in the middle of debugging but there is no where to point it to the source code.
    Chris Lovett
    @lovettchris
    Right, if it has trouble finding the symbols for your code (the code being tested) then the way I normally do it is to load my solution (containing the code being tested) and change the "Executable" to coyote.exe and the command line to be the replay command line then press F5 and then you can watch the entire test sequence take place that leads up to the bug.
    Akash Lal
    @akashlal
    @nanderto What I do is that I add a System.Diagnostics.Debugger.Launch() to the beginning of my test (and recompile). Then when I do replay, I get a window asking me to attach the test to a debugger. I choose the VS instance that has my test code open and I'm good to go.
    Pantazis Deligiannis
    @pdeligia

    Btw, just to add to this, if you run the test from the command line tool (coyote test or coyote replay) you can add the option --break (-b) which will start the debugger before it runs the test (it basically instruments a System.Diagnostics.Debugger.Launch()). This typically opens a Visual Studio selector for the debug session, as @akashlal described. But I have only tried this approach of debugging using the VS IDE on Windows so far.

    Another way, is to run the Coyote test programmatically. We plan to add documentation on this asap, but basically you can programmatically create a Coyote TestingEngine and run the test based on a test Configuration (the coyote command line tool uses this logic under the hood). That way, you can just debug the test with whatever IDE or process you are using until now (e.g. add breakpoints, right click the test and click debug). This is also useful if you want to run Coyote tests on a unit testing framework like xUnit or MSTest, etc. Until we add this info in our docs, you can see my answer on this closed GitHub issue that provides a code snippet how to do this (shows both test and replay): microsoft/coyote#23

    Tomáš Deml
    @tomasdeml
    Hi, I am evaluating Coyote and in the documentation there is no word about the ValueTasktype. I searched the repo and could not find anything related...
    Pantazis Deligiannis
    @pdeligia
    Hi @tomasdeml, thanks for your interest in Coyote! Yes, you are right: we do not support the ValueTask type yet, only the original Task type and other common types like TaskCompletionSource (please note that comparing to our actor/state-machine programming model, our task programming model is still in-preview, so we are keep adding new features and supported types, to make it easier to be consumed, and are prioritizing those based on user demand and feedback). Saying this, supporting ValueTask should not be too hard (as a lot of the logic to control and systematically test those is the same with Task), so we can try to add this asap.
    Rob Landers
    @withinboredom
    Hello all. I was exploring the documentation, but is there a "right" way to serialize/store actors (for program shutdown or resume)?
    Akash Lal
    @akashlal
    @withinboredom One option is to define a Shutdown event, to which an actor will respond by serializing and storing its state, and then halting itself. There should not be any complications here, unless you have special requirements like shutting down actors without pausing client requests.
    Rob Landers
    @withinboredom
    I played a bit with that. I overrode OnHaltAsync(Event e) and called runtime.Stop() which according to the docs "Terminates the runtime and notifies each active actor to halt execution." however OnHaltAsync was never called. Does that seem like a bug or should I move that to an issue?
    Akash Lal
    @akashlal
    The OnHaltAsync method is called when an actor is about to halt. Note that halting of actors has to be done explicitly, by either sending the HaltEvent to it, or the actor itself doing a RaiseHaltEvent. Were you trying to halt an actor, but OnHaltAsync never got invoked? If so, do file an issue.
    Rob Landers
    @withinboredom
    No, I didn't explicitly send the event. https://microsoft.github.io/coyote/learn/ref/Microsoft.Coyote.Runtime/ICoyoteRuntime/Stop seems to say that it will do it for me (which may be needed to halt any actors that may be started by the first actor).
    I'll file an issue later today, need to run a few errands.
    Akash Lal
    @akashlal
    Ah, I see. You called Stop but OnHaltAsync never happened. Do file an issue when you get the time and we can take a closer look.
    Chris Lovett
    @lovettchris

    I checked the code and indeed Runtime Stop was not designed to notify all existing running actors via OnHaltAsync. it just does this :-)

    public void Stop() => this.IsRunning = false;

    But is an interesting idea, but we'd have to change the api to make Stop async, perhaps a new HaltAsync on ICoyoteRuntime would make sense, and this would be implemented by the ActorRuntime, and ignored by the task runtime. So how about this: microsoft/coyote#36

    Brian Chavez
    @bchavez

    I have some questions about using Coyote and Orleans. I think I understand the conceptual programming model with System Task vs Coyote Task; one in which the Task behavior is transparent when running in the runtime/release mode vs under test using the coyote test engine. However, w.r.t. Coyote's Actor model, there doesn't seem to be a 1:1 comparison because there is no Actor object in the .NET Framework. The closest model we have would be something like Akka.net or Orleans.

    So, how does one conceptualize the usage of Coyote's Actor in relation to Orleans Actor/Grain? Is there some way to make Coyote's Actor's behavior become transparent when running under the Orleans runtime?

    Akash Lal
    @akashlal
    @bchavez You're right that Coyote is simply pass-through for Task and for Actors Coyote provides a runtime. However, the runtime is in-memory and very lightweight. One option is the following. Each Orleans Grain hosts a single Coyote Actor. When the grain gets a message, it passes it to the actor. For testing, the Grain is erased away and the actors talk directly to each other. In production, the Grain provides all the distributed goodies. This way, you do incur a small overhead of using the Coyote runtime in production, but it should be very minor. This seems to be a common question -- if you're up for it, perhaps you can prototype a simple solution for "test with coyote, deploy with Orleans" so we can discuss more concretely.
    Brian Chavez
    @bchavez
    @akashlal, thank you for the clarification. It is starting to make much more sense now. I'll try to put together a sample solution over the weekend. Looking forward to it!
    Akash Lal
    @akashlal
    @bchavez excellent, would be happy to help.
    Brian Chavez
    @bchavez

    Hi @akashlal , I have the basic Orleans <-> Coyote grain/actor working. However, the coyote testing part isn't done yet.

    The example below tries to model the operation of a shopping cart:
    https://github.com/bchavez/coyote-samples/tree/master/OrleansActors

    • Items can be added, removed, and a total can be requested.
    • The model can be improved to allow the concept of a quantity, but we can do that later.

    I wanted to pause here because I'm noticing some call semantic issues between the Coyote and Orleans runtimes; I'd like to get some feedback on the call semantics.

    The first thing I notice is this part here:
    https://github.com/bchavez/coyote-samples/blob/0b1d4bb43aa4c8a1549a356840f23913d72802a4/OrleansActors/Grains/CartGrain.cs#L32-L42

    Orleans calls actorRuntime.SendEvent and this operation returns immediately when the item is enqueued for the Coyote Actor's inbox. The ideal semantics I'm looking is "awaiting" for the event to be processed before returning control to the Orleans runtime. I think this is important because if control is returned back to the Orleans runtime (based on Coyote inbox semantics), there's a chance that the Coyote Actor will "lag behind" the Orleans runtime; which I don't think is a good situation to be in.

    The second issue is getting simple values "out of" the Coyote runtime here:
    https://github.com/bchavez/coyote-samples/blob/0b1d4bb43aa4c8a1549a356840f23913d72802a4/OrleansActors/Grains/CartGrain.cs#L65-L76
    Again, I think I need some kind of construct to "await" for the Coyote Actor to "finish its work" before we can return control back to the Orleans runtime. One approach that seemed to work is using the AwaitableEventGroup<T> mechanism, but it feels like a hack. It feels like a hack because I think I should be using something like .SendEvent(backToCaller, response); and instead I'm using a completely different response mechanism this.CurrentEventGroup to acquire the mechanism to respond; where other mechanisms use .SendEvent in the Coyote Actor.

    https://github.com/bchavez/coyote-samples/blob/0b1d4bb43aa4c8a1549a356840f23913d72802a4/OrleansActors/Actors/CartActor.cs#L62-L71

    Ideally, the natural semantics I'm looking for are shown below (when interacting with the Coyote runtime from outside):

    actorRuntime.SendEvent(event);
    await actorRuntime.ReceiveEventAsync(actorId, typeof(Response));

    I guess I could create C# extension methods to hack-in using the this.CurrentEventGroup mechanism, but not sure. Let me know your thoughts. Thanks!

    Brian Chavez
    @bchavez
    image.png
    Chris Lovett
    @lovettchris
    A more general solution to this is the AwaitableEventGroup<T>, see https://microsoft.github.io/coyote/learn/programming-models/actors/event-groups
    Akash Lal
    @akashlal
    @bchavez Great progress. What you need, in some sense, is to synchronously execute the Coyote actor (so its in lockstep with the Orleans Grain). We used to have these APIs for this purpose but we are retiring them in favor of something more general that Chris is referring to.
    Minotaur
    @Psiman62
    I am a Coyote novice, but an actor programming fan. I want to use Coyote actors to express my business logic and conduct systematic testing. I want to continually deploy my actors as Durable Entities in Azure Functions. Your doco seems to suggest that using Coyote StateMachines inside my Durable Entities is the right way to do this. But I have many questions and concerns about this, particularly re systematic testing of multiple concurrent actors. Before I start asking detailed how-to questions re this, is there a guide, or sample or demo, of how a Coyote actor/state machine might be used within other actor-like runtime environments?
    Akash Lal
    @akashlal

    @Psiman62 We don't have specific guidance documented at the moment. The basic strategy follows what we have in our samples: use the distributed machinery in production (e.g., use the "Send" that the distributed actor framework provides), but erase it all away for testing (e.g., use the Coyote Send instead).

    We have some experience doing this with Service Fabric Actors, but it was on an internal codebase. @bchavez is putting together a solution with Orleans Actors that can be a useful guide as it comes together. The "serverless" aspect of Durable Function is perhaps new, so I would be interested in following your progress. And happy to answer questions, of course, as you go along.

    Minotaur
    @Psiman62
    Thanks @akashlal . I'm going to try to write my business actors in a runtime-agnostic way against a minimal abstract actor runtime, then plug-in Coyote for systematic testing. I'll see how far I get with it before trying to implement business actors as state machines - which is really what I ultimately want to do.
    Mark Davies
    @joro550
    Hey there! I'm looking into coyote and am kind of curious about how it interacts with things outside of the system you are developing, say for example I am reading information from a database in the code where i am writing a test around will coyote save the state of the object at the time of testing?
    Akash Lal
    @akashlal
    @joro550 When running in production, coyote is just like any other .NET library. When you're writing a coyote test, you should write it in the style of a unit test. So you won't interact with an actual database (that would be way too slow) but rather a mocked version of it. The mock would then be responsible, say, for saving the state in-memory.
    Mark Davies
    @joro550

    I'm a little confused by that, if you are treating coyote tests as some form of unit tests where you are faking the boundaries between your system and an IO system how are you ever going to find any locking issues.

    For example if I was using files to save and loading information into my application and there was alocking issue in that particular part of my code but then in my coyote tests I replace actual file system with a fake that just talks to in memory file system how would it ever find the locking?

    Akash Lal
    @akashlal
    @joro550 I don't follow your example. How are you associating locks with IO? A coyote test, like a unit test, is naturally designed to find issues in your code when exercised against a model of external dependencies. The difference is that your code, or even the mock, can have concurrency or non-determinism. You need to ensure that the mock is rich enough so that it exercises your code. Can you spell out your example a bit more?