10 benefits of D·ASYNC

Assuming that you are already familiar with the idea behind D·ASYNC and its basic syntax mapping, here are top benefits the technology can offer over industry-standard approaches of developing distributed services.

1. Language level of abstraction

As D·ASYNC leverages the syntax of the C# language itself, there is no need for an application to reference any specific assembly with the API definition. As a developer, you just write code, abide certain rules, and your application becomes a cloud-native citizen. The level of abstraction integrated into a programming language hides any implementation detail and complexity of a concrete distributed platform, what allows to focus on the business logic.

2. Natural code flow

If you have written a distributed workflow, you probably have seen how it becomes more and more complex after a while in terms of writing and maintaining the code, having a lot of small functions and/or deployments, losing track of what invokes what, and understanding the overall intent and responsibilities of many moving parts. The core concept of D·ASYNC mitigates that problem by utilizing finite state machines that are automatically generated by the compiler. Having regular async functions calling other async functions (what comprises a workflow) makes it natural to read, understand, and maintain the code and its purpose.

3. Minimal learning curve

Have you had that moment when you want to try out a new technology, but you also understand that you have to commit some time on learning how it works and how to use it? D·ASYNC is no exception – it has its own rules, but every C# developer knows how to write code in C#, so what can be easier than using a tool that you already know? And this time we are not talking about learning new API, but mostly about the actual C# syntax.

4. Free choice of platform

Without being bound to any specific API of a distributed platform, D·ASYNC gives you a choice to select one that matches your needs, or even create new or adapt your home-grown platform. That means it does not matter if you run an application on Windows or Linux, target .NET Framework or .NET Core, deploy to Azure or AWS – the application code remains the same. That bring opportunities to switch the platform in the future to scale up, improve performance, cut costs, or any other reason without re-writing the code. With the microservice architecture in mind, connected services can run on different platforms, where the contract between them is merely an interface with methods.

With a future design it will be also possible to re-route concrete methods of a service to run on a different platform than the service itself. For example, an abstract image processing service might have two responsibilities – managing images and actual processing. The managing part does not need high-end VMs and big scale, but processing part does. You can have only one class that represents the service, but its methods can run on different deployments or platforms to optimize the cost. That replaces the need of having two separate services (managing and processing) which are the necessity imposed by the limitation of current technologies.

 

5. Simplified testing

A good question would be “What happens if you run an application code without D·ASYNC?” Since D·ASYNC is just a plugable middleware, the answer is “It will just run as a normal .NET application inside a single process producing identical behavior.” That being said, testing of services and their integration is no different from regular unit testing, where dependencies on other services can be injected as mocks or actual implementations into the test target. Essentially, you just test classes and their methods. No need to spin up services locally and be aware of their communication mechanism – that’s the concern of a distributed platform itself, which must have its own set of tests.

6. Event-Driven Design

Most of today’s microservices use the request-response design, but not all work can be done within a couple of minutes – that’s where the message-oriented architecture comes into play. There are cons and pros of each method, which are out of scope of this article, but you definitely won’t be able to build a distributed system solely with request-response design. In C# asyncawait naturally falls into the category of the event-driven design – an async function subscribes to a completion of another function with the await keyword. It’s a special case of a publisher-subscriber model, where in 99% of cases you have exactly 1 publisher and exactly 1 subscriber, what removes the problem of understanding the workflow – in contrast of an event hub with random number of publishers and subscribers. D·ASYNC does not dictate which communication style to use and supports both modes: request-response and publisher-subscriber. The communication mechanism might depend on a concrete platform, it’s hidden from developer’s perspective, and is subject for optimization.

The internal design of D·ASYNC middleware has a concept of connectors, which are platform-dependent. You can have gateways which can connect services in less efficient but more standard way, what also allows to connect to other services not based on D·ASYNC technology.

In both cases, whether it’s request-response or publisher-subscriber, D·ASYNC promotes use of CancellationToken at user level to abort time-sensitive or abandoned operations instead of relying on platform level timeouts.

7. Easier Lift-and-Shift

Regardless if a C# application is not cloud ready or is a cloud monolith, D·ASYNC facilitates move to the cloud or splitting a monolith into microservices with less code re-factoring – a cloud service just needs a contract in form of an interface with set of async methods following certain rules. Such code adaptation process can be called “lift-and-shift” which works exactly as if an application would have been architectured for the cloud in first place.

8. Cuts development time

With benefits described above, D·ASYNC technology can significantly reduce the time needed for writing distributed services and workflows, including testing, maintenance, learning, and comprehension. For example, based on a very basic sample workflow with 10 steps, writing few asyncawait functions takes about 5X less time and 2X less code than writing 10 separate functions conveying a shared context, and most importantly following a natural code flow helps any other developer to understand what your code does much faster. Internet resources are full of great ideas and examples on how to wire up different technologies together to create a distributed system or a workflow, but again it takes time to learn, experiment, and support. Instead of maintaining your own version of such system, it tends towards being more beneficial to let other developers build and maintain that complexity, where D·ASYNC is designed to separate those concerns from actual using of a distributed system.

The time and code size savings can vary per person and complexity of a problem. The numbers provided above are solely based on personal experiments and don’t represent any statistical data.

Debugging the code becomes more natural as well. You can potentially attach a debugger to multiple processes that host various services and/or instances of a distributed system, and use regular means to step though the code, even though it does not run in a single process.

9. Business growth

Let’s not forget the economical aspect that any technology brings to the table, what might play a crucial factor for small businesses and startups, where usually research activities, experts in a field, and time are not affordable. A cloud application does not consist purely from a definition of services and workflows, but if a business finds a way to cut corners at least on that, it can give additional boost in competitive market. D·ASYNC puts less pressure on architects and developers during the initial phase of choosing the right stack of technologies, and as any abstraction layer leaves options open to swap the platform in the future when a product reaches its critical mass of users. Even if down the road you decide to opt out D·ASYNC in favor of other technology, you are still left with a perfectly valid software application that can run on a single machine without any code refactoring.

10. Brings dream closer to reality

How nice would it be to just commit simple code to a source code control system (SCCS) and it’s automatically deployed to the cloud and running in distributed auto-scale manner?  Well, we do have it today. But not exactly. Take for example a combination of ASP.NET, Azure App Service, and Visual Studio Team Services’ (VSTS) integrated Continuous Integration / Continuous Delivery (CI/CD) – you push your code for an ASP.NET application to the SCCS via VSTS, the CD pipeline compiles and deploys to Azure App Service. In such example the application still has to be dependent on a concrete framework (the ASP.NET in this case), and it still has to use an alternative mechanism to run distributed workflows. D·ASYNC tries to close that gap and unite technologies by making the application code universal regardless where it’s deployed. D·ASYNC brings closer to the reality where you simply write C# classes with async methods and push them to SCCS. Period. The rest is a subject of infrastructure optimization, which might involve machine learning for instance to dynamically re-scale and re-organize various pieces of an application with a help of service mesh and without any manual intervention.

D·ASYNC on Azure Functions demonstrates the vision in action.

Other considerations

Despite having advantages described above, D·ASYNC shall not be viewed as an ultimate replacement of existing technologies, it’s rather designed to extends them to serve as an additional layer of abstraction between application code and a distributed platform. The complexity of a distributed system is just shifted to a concrete platform implementation, where interface for any such platform from developer’s standpoint is always the same, what helps to keep two concerns separate from each other. Every single problem might have its own unique solution, where D·ASYNC might not offer specific features or meet certain requirements to tackle all of them in the best way possible. However if it can reduce complexity and save a lot of effort in 80% of cases, that can be good enough to balance out the rest 20% of sophisticated work.

 


Read Next

D·ASYNC on Azure Functions