Open dVakulen opened 6 years ago
Thank you for putting this together, @dVakulen!
There are several good things here, and most of them, fortunately, aren't bottlenecked on the Core team. This is good, as it allows to scale the effort. It seems to me that the community can take an active role in shaping the ASP.NET integration story. Do we need more issues beside #3190 to track those ideas?
Similarly, the DSL idea should be implementable on top of the core stack. A separate issue with more details would help here.
The enterprise support question is being discussed, but it's premature to promise anything about it at this point.
I think it would be great to see the community step up into a more active role here, from submitting PRs to the codebase to building additional extension components to creating samples and documentation. The Core team will prioritize unblocking such efforts where necessary.
We are nearly done with 2.0.0 that will be the new baseline, better structured and with a more flexible and powerful extensibility model. It should make it easier to innovate on top of the core stack.
I do agree that the community can assist with this but I urge MS, or at least the Orleans team to release official tooling as well. It's a massive win to adoption to be able to do this:
I do agree that the community can assist with this but I urge MS, or at least the Orleans team to release official tooling as well.
The Core team can definitely do more here. We are looking at the community to help define those missing experiences. I view this as our blind spot because we mostly deal with major internal customers that already have tooling in place. So a fresh perspective would be very useful here.
@dVakulen What are the use-cases for ASP.NET?
I think 99% (ballpark) of the ASP.NET projects will be fine using smth like Memcached for caching, which has much simpler api/setup than Orleans and is much more mature and have better marketing/coverage.
@yehven I disagree - please see my justification here: #3190. I have seen many traditional aspnet projects which can benefit from the Orleans model as a natural extension of them, but developers don’t realize...
ASP.NET Session Provider based on Orleans will nice additions
@yevhen There's surely a lot of cases where Orleans isn't a match to ordinary caches, but many of ASP.NET projects could use Orleans as smart cache alongside plain caches, providing much better scalability even without thinking about it. It already have nice and api (arguably no more complicated than caching usage) with a bit heavy setup, which could be greatly simplified. Maturity and marketing are important, but they couldn't be the reasons to not even try.
For exaggerated example of using in traditional app: Music store controller action could be changed with Orleans from
var cacheKey = string.Format("album_{0}", id);
Album album;
if (!cache.TryGetValue(cacheKey, out album))
{
album = await DbContext.Albums
.Where(a => a.AlbumId == id)
.FirstOrDefaultAsync();
if (album != null)
{
if (_appSettings.CacheDbResults)
{
//Remove it from cache if not retrieved in last 10 minutes
cache.Set(
cacheKey,
album,
new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromMinutes(10)));
}
}
}
To
Album album = await grainFactory.GetGrain<IAlbum>(id).TryGetProjection();
@yevhen Actually the question about value of Orleans to standard ASP.NET application deserves separate issue, discussion in which could lead in relevant guidelines \ documentation appearance, and also will be point where general consensus of whether Orleans is worthy to be in official ASP.NET examples could be achieved.
I very much agree with this. We should continue polishing a few things to make the co-hosting with ASP.NET scenario smoother, and then we can start reaching out and making Orleans a little more prominent for the current ASP.NET audience.
As far as perf, I do think we need to take co-hosting as a primary use case for this to work, and I'm glad @dVakulen is already improving it to reduce the busy work under low load, as well as optimizing perf all over the place. Of course this is something we need to do as a team and commit to it if we plan to have co-hosting as a main scenario (in the past the main scenario was mainly unlimited scale out, and definitely not really high density co-hosted microservices, not that we need to go that far down that road, but at least be more conscious to co-hosting, instead of assuming the Silo is the main thing running).
As far as API and hosting integration, we are already doing a lot of things with the changes to align with their hosting APIs (silo builder, which we'll eventually migrate to Microsoft.Extensions.Hosting
when that's released), move to Microsoft.Extensions.*
packages (Logging, Options, Configuration, DependencyInjection, etc), adding a local cluster client to be used within the same process especially for co-hosting (https://github.com/dotnet/orleans/pull/3362).
As you can see, the core team is on the same page with this plan, so let's do it.
I opt to use Orleans for just about any Web app I make. It's a low-ceremony way to move quickly from idea to implementation. Particularly for interactive apps (eg involving chat or some other live updates / push notifications) since databases aren't great at that anyway, but also for CRUD apps because it avoids Object-Relational Impedance Mismatch and simple persistence is trivial to work with.
So anyway, we're definitely on-board, and as @jdom mentioned above we have been working to align wherever possible and "de-invent the wheel"
FWIW I wanted to briefly share my experience. I tend to find that I have to defend the "Orleans" framework vs ServiceFabric and other Microservice-eqsue solutions. Having a clear pros and cons document may help both in aiding people choose the right product and also in selling Orleans into their business.
As mentioned Enterprise Customers may be reticent to invest in Orleans when other solutions are available.
Great thread. I think there is a SignalR angle to this as well, Orleans makes a great backplane.
As the creator of both Akka.NET and Proto.Actor, my 2 cents on the topic.
Cloud enabled (distributed) by default solutions will become standard in near future.
Yes, but we are not there right now. most systems can still be built using plain old boring technologies. There is no reason to rush there for the sake of the technology itself. Those who truly have the need for distributed systems will find the tools available. e.g. Fintech, iGaming etc.
and both of them seems to be used only in rare scenarios.
One issue I think both Orleans and Akka IMHO have is that they are thought of as "platforms". It becomes somewhat political in development organizations when they come up, as if there needs to be taken a bigger strategical decision before using such tool.
Promoting things as small libraries instead make them fly under the radar.
I tend to find that I have to defend the "Orleans" framework vs ServiceFabric and other Microservice-eqsue solutions.
But rightfully so I'd say, having standard HTTP+Json + Service Discovery a'la Consul/ETCD takes you really far, and it fits naturally with what many devs already know. It also avoids lockin in terms of language / platform which is of great value for many dev orgs.
We in the .NET distributed computing community must take our responsibility and teach the community what tech to use and when.
That being said, I think there are multiple things that could be unified across the different implementations.
e.g. the Orleans Dashboard could be abstracted to use a provider model where each framework could provide their own implementation for metrics.
Eventsourcing, Scheduling libraries could probably be unified between Akka and Proto. Persistence libs for Orleans could probably be shared with Proto. I'd say there are quite a few things that could be abstracted to make them available cross framework.
That way, there could be a broader ecosystem where companies could pick and chose the right thing for their specific use-case instead of having the same effort repeated over and over in every implementation.
I don't agree that most web applications are easy to build with Orleans. Many smaller apps are done using EF and their developers don't have to deal with anything else. Soon more and more software systems use things like Orleans but at the moment many don't. Take a look at usecases of Akka and Erlang to see that an actor framework is not democratizable because it is not useful as a daily tool for every developer on planet earth. I think instead we should focus on scenarios which can use Orleans and benefit from it. Game servers, IOT, any other real-time high perf server software which is actually hard/impossible to make with caches and ORMS.
We have been considering using Orleans for our main product, but are very much concerned about performance. Startup performance is gruesome (Windows 2000 boots faster, if that's anything to go by), and it appears to be easy to design a system that doesn't perform at all.
There is very little documentation on what to expect performance-wise from the different subsystems (e.g. networking and serialization is built-in; but how does it compare to ProtoBuf/NetMQ or any of the ready-made MQ libraries available for doing the same?). The fact that you have to learn Orleans, then performance test the various parts to figure out what bits you can use (and how), without killing your backend, is just a daunting task. Mind you, performance-oriented people are not going to use ServiceFabric either ;)
My advice would be to focus on .NET Core (it seems to be where all the performance-oriented work is done) and overall performance, including benchmarks to showcase what to expect. If the product is fast and it solves some of the tricky distributed problems, interested people will learn and use it regardless of whether there is a checkbox in a GUI somewhere to enable it. Don't aim for mass market adoption until the experience is a lot smoother or you'll just be burning your future leads.
One issue I think both Orleans and Akka IMHO have is that they are thought of as "platforms".
My thinking on this is inherently tainted by the tradition of Microsoft being a platform company. For better or worse, Orleans was built with that bias. While I recognize that, I still don't quite see how distributed compute can be enabled without at least some platformy aspect to it. For example, technologies like Hadoop, Spark are also platforms for all practical purposes.
Hence, I'm skeptical such technologies can be truly presented as small libraries to knowledgeable audience. At the hosting level, they are just libraries. But there's always a step function decision to bet on them. And that better be explicit than flying under the radar IMO.
That being said, I think there are multiple things that could be unified across the different implementations.
I agree with that and with the examples. Take quite a bit of effort though. I hope the version-tolerant serializer that @ReubenBond is working on will become one such component.
@mnmr
Startup performance is gruesome (Windows 2000 boots faster, if that's anything to go by), and it appears to be easy to design a system that doesn't perform at all.
Would you mind opening a separate issue with the details?
Regarding the timing I believe the majority of .Net devs will indefinitely miss out on Orleans unless it is presented in a more friendly package. Most people simply don’t have the time it takes to get up and running with Orleans in its current form. They need hand holding into the distributed .Net world. Tooling is one area. Another big one is tutorials, and if these can be official (I know it shouldn’t matter but it does for a lot of .Net shops) then that’s even better.
I'll share my thought, about co-hosting. As I understand, It is very useful in use cases as edge gateways, rules' engines , behavior trees, controlled small number of actors (e.g. current calls and agents on shift in a contact center). I think the most useful is that we will become familiar and more confident with the actor model. IMO, model's design (not implementation) is the most difficult. I'm thinking of applications in a "hybrid mode" with services and a subsystem using the actor model. What is the main focus in MS Orleans? the distributed model or the actor model?
Focus on tight integration with ASP.NET should be clearly stated in first pages of documentation as well as normality of single server deployments with silo co-hosted in same process with web app as it being a way of ensuring easy scaling later.
Interesting idea, I have to admit I never considered using it that way in ASP.NET Core. Always and if, then as client being used from ASP.NET Core. But the support for .NET Core was lacking back then when I first had a dive into it and only the client being possible to be used in ASP.NET Core and even then it not being on par with the current ASP.NET Core Version.
A major drawback was that the 1.5.x (iirc it was the one which added basic .NET Core support for the client side) was that it was locked in on ASP.NET Core 1.x and not available when starting an ASP.NET Core 2.0 application (due to the breaking changes in Microsoft.Extensions.DependencyInjection
) and the first usable Orleans 2.0 builds for .NET Core 2 came at a much later point.
Imho another thing that making adopting Orleans into more projects is the way to setup unit tests (means w/o setting up a local silo to run against it). Compared to Orleankka, Unit Testing the grains are a real PITA.
Actors and Orleans in special is a very interesting go for domain driven design where an actor nicely represents an aggregate root in DDD. However, the lack of a nicely cheap and scaleable storage kinda stands up in the way using that more often. While we have Azure Tables support (cheap and reasonable fast storage), but has issues for bigger aggregates it can be a problem (due to the limited size of a column in Azure Table storage).
And while there have been done some steps to add event sourcing to grains, there are no out-of-the-box providers to use Azure Table Storage of even better Apache Kafka as persistence. And while there's Orleans.KafkaStreamProvider, it seems not to be maintained anymore (last commit dates year ago, only 1.x support, not sure if it even works with the current 1.x versions).
Of course, Orleans just works good for things that can be accessed via a single key (though I read an issue about ideas of indexing Grain (State) properties/fields too). For people new to Orleans who want to integrate that into their ASP.NET (Core) applications there should be examples on how to create (denormalized) read only stores, which can be used to do queries and aggregation on it. For most of the seasoned users its easy, using the streams and handlers that denormalize the data and write them back to a document or rdbms.
I'd personally want to see a higher focus on .NET Core (even for windows-only hosting), since its mature enough by now and has performance as a feature and would love to see the integration of System.IO.Pipelines
, Span<T>
/Memory<T>
into Orleans.
I've just finished reading every page of the docs and adding every feature in there to the Adventure sample in the tutorial to make a pretty cool game. I also blog about ASP.NET Core and author ASP.NET Core Swagger and GraphQL project templates. Here is what I found:
dotnet new
project template doesn't work and are also too basic anyway.With all that said, it's an amazing product. If I have the time and depending on the status of 7#, I'll see if I can do something about 6#.
Good feedback. Personally I'd love if you could get (6) to a great point, since you already have the expertise. See https://github.com/dotnet/orleans-templates I believe (3) is already underway, but I don't know the current status. Of course, any help is always welcome.
Working on (5) in my free time at the moment, video course approach. (8) is super important in my line of work. I’m attempting to help modernize the samples, but want to look at adding more design patterns not yet described, and making samples for those as well. Also, I think extra value will come from having samples and training resources that show Orleans integrating with other technologies for various use cases. Orleans is an amazing technology to use as the pumping heart of a solution, with other edge technologies surrounding it.
If anyone is interested I rustled up an Orleans project template based on the code I wrote for the Adventure game. It's aiming to be production ready.
Take a look at the code below, I'll see if I can release it tomorrow.
https://github.com/Dotnet-Boxed/Templates/tree/master/Source/Content/OrleansTemplate
Orleans place in .NET ecosystem
Currently .NET lacks supported by Microsoft cloud independent solution for building distributed applications. Most obvious candidate on this role could be guessed pretty easily from looking at .NET Foundation home page. But even though its stars count is high - actual usage numbers can be seen in nuget package statistics, it's downloads count is two times lower than Akka.NET counterpart, and both of them seems to be used only in rare scenarios.
Broad community likes the idea, but continues to use in-house solutions or plain old caches.
Everything that is going to be said next boils down to the following questions: why Orleans isn't being used in ASP.NET solutions, and being relatively rare pick for high-scale ones, and how to make it viable option to be integrated into wide spectrum of .NET applications.
Assumptions
View of Orleans from ASP.NET developer standpoint
Notion of ASP.NET is missing from online documentation thus creating in mind of passing by visitor impression that Orleans is meant to be used only in high-scale apps.
First place where curious potential user goes is documentation. Orleans' first page (http://dotnet.github.io/orleans/Documentation/Introduction.html) - great in terms of abstractions, but completely missing even a notion of ASP.NET, and so does it's left menu. Getting at least some ASP.NET reference requires navigation to tutorials, where it can be located under entry which name again, like on purpose, avoids mentioning ASP.NET (http://dotnet.github.io/orleans/Tutorials/Front-Ends-for-Orleans-Services.html). Thus such visitor have quite high chances of getting impression that Orleans is for some high scale apps, and for his ASP.NET app with 2 - 5 servers web farm (one of most high loaded ASP.NET deployments architecture - https://nickcraver.com/blog/2016/02/17/stack-overflow-the-architecture-2016-edition uses 11 web and 2 Redis servers) it would be overkill, and will just continue to use in-memory or external caches.
Integration with existing applications is not quite easy while lacking any guidelines.
Problems of such integration: in addition to complexity of awaits introducing into previously synchronous entities, it also usually brings in need in application architecture re-think or re-design as it's entities in many cases are being tightly coupled, making straightforward rewrite for Orleans to result in chatty interactions with obvious outcomes with current Orleans performance. Recommended coordinator pattern lacks guidelines on how to design it, and it's creation requires more thinking on existing system design in terms of DDD than in theoretically possible "every object - actor" approach, thus resulting in harder fit into existing design with reasonable compared to possible outcome costs. And as additional exercise for the ones wanting to incorporate Orleans into their apps - each entity contract needs to be duplicated in marker interface.
Examples with ASP.NET are almost non-existent.
There's no ASP.NET templates besides few without "ASP.NET " in name in examples folder. So for new ASP.NET project question whether to add Orleans to it is usually being rhetorical.
Ways of attracting ASP.NET community
Focus on tight integration with ASP.NET should be clearly stated in first pages of documentation as well as normality of single server deployments with silo co-hosted in same process with web app as it being a way of ensuring easy scaling later.
In addition and expanding already existing issue - simplify out of box experience as much as possible: Orleans should be ready to use immediately after package installation and converting classes to grains, requiring as little configuration as possible, ideally - just adding
UseOrleans()
to ASP.NET host builder. Probably allow grains resolving by class type instead of interface, as entities contracts duplication in marker interfaces, while usually being right approach, for newcomers it could be a bit too much trouble for ghostly benefits, compared to just addingvirtual
keyword alongside with await, matching Entity Framework proxies requirements. Also dependency free reliable deployment would be really nice to have for this matter (it'll require built in distributed coordination solution, but that (Paxos and Raft algorithms) was already implemented on top of Orleans as experiment, so while needing thorough verification with Jepsen - overall remaining effort shouldn't be too big, and resulting solution could be used as .NET alternative to ZooKeeper for those who doesn't want to bring additional dependencies into their apps).Document use cases of common ASP.NET apps, with Orleans being useful addition to old way caching.
Integrate Orleans with main ASP.NET examples: ASP.NET Boilerplate, eShopOnContainers , Music Store, etc. This one is rather high priority, and when (if) Orleans will be ready to be used in any ASP.NET application - probably Orleans core team effort should be spent on fitting Orleans into that examples in order to have it done as soon as possible.
Even though existing performance usually should be enough - sometimes it still might be deciding factor.
Theoretically Orleans could relate to ASP.NET a bit similar to how Akka relates to Play Framework.
Comparison with requirements of high-scale application
Fault tolerance, scalability, performance and programming model are required for framework which targets to solve highload problems. Orleans performance seems to be the main reason of it being relatively rare pick for such app as every additional percent of CPU resulting in increased spending on servers, and every ms of latency influences user experience. Thus potential users sometimes just don't want to pay price of Orleans abstractions.
Lack of enterprise support (like Akka.Net does) plays its part too, even though Orleans team and community does great job of helping in gitter.
Recently made usable .NET Core support is nice feature, but it still in beta and that makes enterprise customers to refrain from using it yet.
Path of making Orleans viable choice to be base building block of high-scale application
Performance. There's no clear obstacles on path of making Orleans two times faster than it is now. With dynamic actor re-partition, co-locating silos with clients and integration with client's threads - theoretically even thread switch cost could be removed from average grain call, leaving only relatively small await overhead.
While performance is being the most critical part, there's some nice to have but a bit orthogonal features, such as convenient graph-resembling streams DSL. As large part of workloads have static data flow processing plans, demand for stream processing is increasing every day, thus leading to success of tools with expressive syntax for building such pipelines (Akka streams, Kafka to name a few lightweight ones, and Spark's being the most outstanding batch-oriented one.) Having such DSL could be deciding factor for many due to lack of such in .NET world (not counting Akka.NET).
Relations with Akka.NET
In addition to existing comparison: Akka.NET, while being strong competitor, lacks two important features - seamless integration with programming model and official Microsoft support.
There could be some thoughts on joining efforts and creating unified model for .Net ecosystem.
Conclusion
For increasing broad ASP.NET community usages: Orleans currently missing two quite important features for it to be able to be promoted in ASP.NET examples alongside with Entity Framework: ease of deployment and performance. After fixing of that issues team effort could be spent on increasing ASP.NET presence in documentation and making Orleans integral part of popular ASP.NET examples.
In order to get more high-scale customers - performance should be uncompromising. Enterprise support would be nice to have, as well as Streams DSL.
P.S. This is subjective opinion of external contributor.