Merged PR 1472: remove temporary press release

remove temporary press release
This commit is contained in:
Chris Lovett 2020-03-12 18:52:08 +00:00
Родитель 22d42efd81
Коммит 09a71ec714
2 изменённых файлов: 64 добавлений и 167 удалений

Просмотреть файл

@ -142,72 +142,102 @@ an event is sent to a target actor there is no deep-copying of those members, fo
reasons. The target actor will be able to see the Event object and cast it to a specific type to
extract the information it needs.
Now you can write a complete actor, declaring what type of events it can handle, and defining some
initialization behavior and an event handler:
Now you can write a complete actor, declaring what type of events it can handle:
```c#
[OnEventDoAction(typeof(PongEvent), nameof(HandlePong))]
[OnEventDoAction(typeof(PingEvent), nameof(HandlePing))]
class Server : Actor
{
ActorId ClientId;
protected override Task OnInitializeAsync(Event initialEvent)
public void HandlePing(Event e)
{
Console.WriteLine("Server creating client");
this.ClientId = this.CreateActor(typeof(Client));
Console.WriteLine("Server sending ping event to client");
this.SendEvent(this.ClientId, new PingEvent(this.Id));
return base.OnInitializeAsync(initialEvent);
}
void HandlePong()
{
Console.WriteLine("Server received pong event");
PingEvent ping = (PingEvent)e;
Console.WriteLine("Server handling ping");
Console.WriteLine("Server sending pong back to caller");
this.SendEvent(ping.Caller, new PongEvent());
}
}
```
This `Server` is an `Actor` that can receive `PongEvents`. During initialization it creates a new
`Client` actor and sends a `PingEvent` to it containing `this.Id` which is the `ActorId` of the
`Server`. It handles the `PongEvent` by calling the `HandlePong` event handler method which prints a
message.
This `Server` is an `Actor` that can receive `PingEvent`. The `PingEvent` contains the `ActorId` of
the caller and the `Server` uses that to send back a `PongEvent` in response.
An event handler controls how a machine _reacts_ to a received event. It is clearly just a method so
you can do anything there, including creating one or more actor instances, sending one or more
events, updating some private state or invoking some 3rd party library. Notice the `HandlePong`
event handler has no parameters. It could also choose to specify one parameter of type `Event` but
in this case it doesn't care about the specific type of event it received here.
events, updating some private state or invoking some 3rd party library.
To complete this Coyote program, you can provide the following implementation of the `Client` actor
created by the above `Server`:
```c#
[OnEventDoAction(typeof(PingEvent), nameof(HandlePing))]
class SetupEvent : Event
{
public readonly ActorId ServerId;
public SetupEvent(ActorId server)
{
this.ServerId = server;
}
}
[OnEventDoAction(typeof(PongEvent), nameof(HandlePong))]
class Client : Actor
{
public void HandlePing(Event e)
public ActorId ServerId;
protected override Task OnInitializeAsync(Event initialEvent)
{
PingEvent pe = (PingEvent)e;
Console.WriteLine("Client handling ping");
Console.WriteLine("Client sending pong to server");
this.SendEvent(pe.Caller, new PongEvent());
Console.WriteLine("Client initializing");
this.ServerId = ((SetupEvent)initialEvent).ServerId;
Console.WriteLine("Client sending ping event to server");
this.SendEvent(this.ServerId, new PingEvent(this.Id));
return base.OnInitializeAsync(initialEvent);
}
void HandlePong()
{
Console.WriteLine("Client received pong event");
}
}
```
This `Client` is an `Actor` that can receive `PingEvents`. It handles the `PingEvent` by calling the
`HandlePing` method. Notice in this case the `HandlePing` method chooses to receive the `Event` as a
parameter. It then casts the incoming `Event` to type `PingEvent` and uses the `Caller` field to
send a `PongEvent` back to the caller (which is the id of the Server in this case).
This `Client` is an `Actor` that sends `PingEvents` to a server. This means the `Client` needs to
know the `ActorId` of the `Server`. This can be done using an initialEvent passed to
`OnInitializeAsync`. The `Client` then uses this `ActorId` to send a `PingEvent` to the `Server`.
When the `Server` responds with a `PongEvent` the `HandlePong` method is called because of the
`OnEventDoAction` declaration on the class. Notice in this case the `HandlePong` event handler
takes no `Event` argument. The `Event` argument is optional on Coyote event handlers.
Note that `HandlePing` could also be defined as an `async Task` method. Async handlers are allowed
so that you can call external async systems in your production code, but do not directly create
parallel tasks inside an actor (e.g. by using `Task.Run) as that can introduce race conditions (if
parallel tasks inside an actor (e.g. by using `Task.Run`) as that can introduce race conditions (if
you need to parallelize a workload, you can create more actors). Also, during testing, you should
not use `Task.Delay` or `Task.Yield` in your event handlers. It is ok to have truly async behavior
in production, but at test time `coyote test` wants to know about and control all async behavior of
your actor. If it detects some uncontrolled async behavior an error will be reported.
One last remaining bit of code is needed in your `Program` to complete this example, you need
to create the `Client` actor in the `Execute` method:
```c#
public static void Execute(IActorRuntime runtime)
{
ActorId serverId = runtime.CreateActor(typeof(Server));
ActorId clientid = runtime.CreateActor(typeof(Client),
new SetupEvent(serverId));
}
```
The output of the program will be:
```
Client initializing
Client sending ping event to server
Server handling ping
Server sending pong back to caller
Client received pong event
```
The `CreateActor` and `SendEvent` methods are non-blocking. The Coyote runtime will take care of all
the underlying concurrency using the Task Parallel Library, which means that you do not need to
explicitly create and manage tasks. However, you must be careful not to share data between actors

Просмотреть файл

@ -1,133 +0,0 @@
---
layout: reference
section: learn
title: Press Release
permalink: /learn/resources/press-release
---
# Announcing Coyote, taking the uncertainty out of asynchronous systems
Software developers face the difficult balancing act of optimizing two metrics that are fundamentally at odds with each
other: on the one hand new software must be created quickly, and on the other, it must also be free of bugs, it must not
crash or hang, or lose customer trust. So developers need a way to keep reliability in check without imposing undue
development costs.
This is getting increasingly more difficult in todays world of cloud services where developers must
integrate multiple back end services in order to deliver scalable solution to their users. Cloud services are
inherently distributed programs that contain multiple dimensions of complexity. Developers must be able to optimize the
concurrency of their service so they can fully exploit multiple back end resources without bottlenecks, and they must
design failover logic so that the service can survive failures without losing data or availability. Furthermore, all
this must be done while being reactive to incoming web requests and asynchronous responses from backend cloud services.
What all this boils down to is developers are struggling with the complexity of asynchronous non-deterministic systems,
in all software domains, not just cloud services. Non-determinism shows up in many places. First there is the
non-deterministic scheduling of concurrent operations where the operating system is scheduling threads and processes.
Next there is non-determinism from the order in which messages are received from remote systems. Then there are random
failures that can happen in all levels of the system. Lastly there are often timers firing at random times either for
retry logic or timeouts from other services that have become unresponsive.
Designing, implementing and testing non-deterministic systems is challenging to say the least. Current practices, such
as stress-testing, or using failure-injection tools can be useful, but developers need more. Failure-injection tools
often require complex setup, and stress-testing requires a large amount of time to find bugs, and those bugs are almost
impossible to reproduce.
Take the following example which shows 5 servers (in green) that are acting as a fault tolerant cluster so they can provide
a highly reliable service to their clients. These services implement the raft consensus protocol to elect a leader and
in doing so hundreds of messages are flying back and forth between these machines, resulting in a large amount of
non-determinism. This system might work under stress tests with no bugs, but can you ever be really confident it is
ready to ship?
<div style="width:400" class="animated_svg" trace="/coyote/assets/data/Raft.xml">
{% include Raft.svg %}
</div>
### Coyote enables fearless development of reliable asynchronous software
Coyote is a .NET framework built on the Task Parallel Library that guides you towards designing, implementing and
testing your code in a way that embraces [non-determinism](/coyote/learn/core/non-determinism) and asynchrony. Instead
of trying to hide non-determinism, Coyote helps you explicitly model where non-determinism is coming from in your
system. Coyote uses this information to provide a state-of-the-art testing tool that can execute your Coyote code in a
special “test” mode. This advanced test engine can control every source of non-determinism that you have defined,
including the exact order of every asynchronous operation, which allows the test engine to systematically explore all
the possibilities. This tool runs very quickly and reaches unheard of levels of coverage of all non-deterministic
choices in your code, and as a result it finds most of the tricky bugs in your code in a way that is also trivial to
reproduce and debug.
One customer said, _“features developed in Coyote test mode worked perfectly in production first time”_. Another
customer said, _“a feature that took 6 months without Coyote was developed in one month using Coyote”_. As a result:
_“developers gained a significant confidence boost”_ and _“Coyote provided us with the confidence and capability to
churn code much faster than before”_.
Coyote is the result of years of investment from [Microsoft Research](https://www.microsoft.com/en-us/research/) in the
space of program verification and testing. Coyote draws on ideas from a previous project called P#. Coyote has now
graduated from Research and is now a full battled-hardened component used by Azure. Multiple Azure infrastructure
services have been written using Coyote from teams like Azure Batch, Azure Compute, and Azure Blockchain.
Coyote is a combination of a programming model, a lightweight runtime and a testing infrastructure all packaged as a
portable .NET library, with minimal dependencies. Coyote supports two main programming models. If you are happy
developing your code using C# async/await construct for asynchronous Tasks, then Coyote can add value on top of that. By
switching to the [Coyote task library](/coyote/learn/programming-models/async/overview) the Coyote tester will be able
to find many bugs in your code. The C# async/await feature is a wonderful thing, but sometimes even that can result code
that is too parallel which results in a lot of complexity, for example, when performing two or more concurrent tasks
you may need to guard private state with locks and then you have to worry about deadlocks and so on.
Coyote solves this with a more advanced programming model called the [Actor programming
model](/coyote/learn/programming-models/actors/overview). Actors constrain your parallelism so that a given instance of
an Actor receives messages in a serialized order via an inbox. [Actor
models](https://en.wikipedia.org/wiki/Actor_model) have gained a lot of popularity especially in the area of distributed
systems, precisely because they help you manage the complexity of your system. Actors essentially embrace asynchrony by
making every message between actors an async operation. The Coyote test engine fully understands the semantics of
Actors and can do a world class job of testing them and finding even the most subtle bugs. Coyote goes one step
further providing a type of Actor called a State Machine and the Coyote test engine knows how to fully test your
state machines ensuring every state is covered and every state transition is tested.
### Building blocks of Coyote applications
The Coyote programming models are easy to use, and so with minimal investment on your part you get huge upside
value from the Coyote test tools that automatically find bugs in your code. You can decide how much to invest in
your use of Coyote so you can find the sweet spot that maximizes your return on that investment. Coyote provides
the following building blocks for more reliable software:
- [ControlledTask](/coyote/learn/programming-models/async/overview) - a wrapper on .NET Tasks that allows the Coyote
test engine to take control of scheduling.
- [Actor](/coyote/learn/programming-models/actors/overview),
[StateMachine](/coyote/learn/programming-models/actors/state-machines) and Event - base classes for the Coyote actor
programming model
- [Specification](/coyote/learn/specifications/overview), [Monitor](/coyote/learn/specifications/liveness-checking) -
ways to embed checks into your code that can be verified at test time. This includes some pretty sophisticated ways
of monitoring the "liveness" of your code (ensuring that it doesn't get stuck spinning it's wheels).
- [Timers](/coyote/learn/programming-models/actors/timers) - provide a way to model timing activities in your system
which is especially useful in the design of mocks that model external systems including their sources of non-determinism.
- [ControlledRandomValueGenerator](/coyote/learn/core/non-determinism) - allows you to tell Coyote where other sources
of non-determinism are in your code. For example you can use this to model situations where a request on a backend
service might randomly fail (e.g. out of disk space, or host not found, etc).
- [Logging](/coyote/learn/advanced/logging) - allows you to see your debug messages in context with decisions being
made during a coyote test run, including nice ways to visualize what is happening as shown above.
Other than the above constructs, Coyote allows you to use the full power of the C# programming language. To get the best
test performance Coyote recommends that you mock all the systems outside of your control. This allows the Coyote test
tool to test your code locally on your laptop. The following example shows a typical test setup, in this case a
shopping cart system with all external services written as Coyote mock actors:
![ecommerce](/coyote/assets/images/ecommerce.svg)
Larger teams can share their Coyote mocks for improved code reuse in testing. In fact, you can publish your Coyote
mocks as a precise protocol definition of your public services. The coyote tester can then be used to fully certify
that new customer code is working properly with the mock model of your service before they even attempt to use your
production api's.
Coyote mock models are typically much more sophisticated than normal mocks. They not only specify the asynchronous
api required to talk to a service, but also include sources of non-determinism, specifications that capture required
semantics, and can even include liveness monitoring and custom logging. Most teams are already building mocks and
testing their code this way, so switching that over to work with Coyote usually requires minimal effort.
### Learn more and contribute
Coyote package is available on [NuGet](https://www.nuget.org/packages/Microsoft.Coyote/) so [getting
started](/coyote/learn/get-started/install) with Coyote is very simple.
Coyote is also available as [open source on github](http://github.com/microsoft/coyote) and is open to all who what to
provide feedback and suggestions. We would love to see your pull requests if you have specific ideas on how to improve
Coyote.
We hope that you can also benefit from more confident coding of asynchronous systems using Coyote!