Dasync 正在参加 2021 年度 OSC 中国开源项目评选,请投票支持!
Dasync 在 2021 年度 OSC 中国开源项目评选 中已获得 {{ projectVoteCount }} 票,请投票支持!
2021 年度 OSC 中国开源项目评选 正在火热进行中,快来投票支持你喜欢的开源项目!
2021 年度 OSC 中国开源项目评选 >>> 中场回顾
Dasync 获得 2021 年度 OSC 中国开源项目评选「最佳人气项目」 !
授权协议 Apache-2.0 License
开发语言 JavaScript
操作系统 跨平台
软件类型 开源软件
所属分类 云计算Serverless 系统
开源组织
地区 不详
投 递 者 首席测试
适用人群 未知
收录时间 2021-12-02

软件简介

Build Status Follow on Twitter Stories on Medium D-ASYNC | Cloud-Native Apps Without Frameworks

Sign up for the early invite to the fully managed experience with D-ASYNC Platform.

D-ASYNC: Zero-Cost Microservices

D-ASYNC is a multifaceted and comprehensive solution for building service-oriented applications. It is based on the new Service-Oriented Programming Language paradigms, which provide an extendible framework for inter-service communication (HTTP, gRPC, message queues, event streams), a unique language-integrated stateful workflow engine, implementation of best microservice practices, a unified approach for distributed tracing, API generator and versioning capabilities, error-handler free clean code.

D-ASYNC Concept

The mission of D-ASYNC is to give developers a superpower of zero-cost development of scalable, reliable, and secure microservices. The ability to use the language itself helps to focus on the core value of your application, making it easy to write, read, evolve, and maintain.

Basic Programming Concepts in C#

The following examples may look trivial and as for a single-process application, but D-ASYNC technology makes them run (without any modifications) in a resilient, persistent, scalable, and distributed manner. The new service-oriented syntax will be introduced with the CloudSharp project.

  1. Inter-Service Communication.
// Declaration of the interface of another service
// that might be deployed in a different environment.
public interface IPaymentTerminal
{
  Task Pay(Order order, CreditCard card);
}

public class BaristaWorker
{
  private IPaymentTerminal _paymentTerminal;

  // Another service can be used with the dependency
  // injection. All calls to that service will use
  // its communication mechanism. All replies will
  // be routed back to this service.
  public BaristaWorker(IPaymentTerminal paymentTerminal)
  {
    _paymentTerminal = paymentTerminal;
  }
  
  protected virtual async Task<Order> TakeOrder()
  {
    Order order = ...;
    CreditCard card = ...;
    
    // Simple call to another service may ensure
    // consistency between two. That complexity is
    // hidden to help you focus on the business logic.
    await _paymentTerminal.Pay(order, card);
    
    // Unlike any RPC, the state of execution is saved,
    // and restored when the service replies. If the call
    // fails, it is automatically retried and an exception
    // is never seen in this method.
    
    // There is no need to create API controllers and service
    // clients, and no need to worry about asynchronous APIs.
  }
}
  1. Service Events and Reactive Programming.
public class CustomerManagementService : ICustomerManagementService
{
  // Implement the domain event simply as a C# event.
  public virtual event EventHandler<CustomerInfo> CustomerRegistered;

  public virtual async Task RegisterCustomer(CustomerInfo customerInfo)
  {
    // ... (register a new customer in the system here)

    // Then notify observers about successful registration.
    // The event may not fire immediately, but will get scheduled
    // when this method exits to guarantee consistency.
    CustomerRegistered?.Invoke(this, customerInfo);
  }
}

public class RewardProgramService : IRewardProgramService
{
  public RewardProgramService(
    ICustomerManagementService customerService)
  {
    // Subscribe to the domain event.
    customerService.CustomerRegistered += OnCustomerRegistered;
  }

  protected virtual void OnCustomerRegistered(
    object sender, CustomerInfo customerInfo)
  {
    // This method is executed in a resilient manner
    // and can be a workflow (see next example).
  }
}
  1. Stateful Workflows.
// This is a service with a workflow.
public class BaristaWorker
{
  // This is a 'routine' of a workflow.
  public virtual async Task PerformDuties()
  {
    // This will call a sub-routine and save the state
    // of the current one.
    var order = await TakeOrder();
    
    // If the process terminates abruptly here, after restart
    // the routine continue at exact point without executing
    // previous steps. Any async method is compiled into a
    // state machine, so it's possible to save and restore
    // its state and context.
    
    var cup = await MakeCoffee(order);
    
    // Essentially this is an Actor Model of a scalable
    // distributed system. A routine maps to an actor,
    // because an async method compiles into a state
    // machine (which has its state), and a routine can
    // call sub-routines - same as an actor can invoke
    // other actors.
        
    await Serve(cup);
    
    // Workflows are not limited to one service and
    // its methods, and can span across many services
    // (as shown in the very first example and below).
    
    // Varies degrees of consistency can be guaranteed
    // in case of failures, and that settings does not
    // change the business logic.
  }
  
  // This is a 'sub-routine' of a workflow.
  protected virtual async Task<Order> TakeOrder();
  
  protected virtual async Task<Cup> MakeCoffee(Order order);
  
  protected virtual async Task Serve(Cup cup);
}
  1. Saga Pattern.
// This method represents a workflow with
// application-specific error-handling.
public async Task PlaceOrder()
{
  // Hard-coded sample input.
  var price = 10;
  var itemId = "Whole Coffee Beans 1lb";
  var quantity = 1;

  // Generate unique ID which will be persisted in this routine.
  var transationId = Guid.NewGuid();

  // 1. First, make sure that payment can be made.
  // This is a call to a service #1.
  await _paymentProcessor.Credit(transationId, price);
  try
  {
    // 2. Then, reserve the item being purchased.
    // This is a call to a service #2.
    await _warehouse.ReserveItem(transationId, itemId, quantity);
  }
  catch (OutOfStockException)
  {
    // 3. If they are out of stock, refund the cost of an item.
    // Perform a compensating action on service #1.
    await _paymentProcessor.Debit(transationId, price);
  }

  // This method acts as an orchestrator and represents clear
  // business logic of placing an order without a need to
  // decompose it into dozens of message classes and their
  // respective handlers.
}
  1. Parallel execution.
public class CoffeeMachine
{
  public virtual async Task PourCoffeeAndMilk(Cup cup)
  {
    // You can execute multiple methods in parallel
    // to 'horizontally scale out' the application.
    Task coffeeTask = PourCoffee(cup);
    Task milkTask = PourMilk(cup);
    
    // Then just await all of them, as you would
    // normally do with TPL.
    await Task.WhenAll(coffeeTask, milkTask);
    
    // This is translated into a such series of steps:
    // 1. Save state of current method;
    // 2. Schedule PourCoffee
    // 3. Schedule PourMilk
    // 4. PourCoffee signals 'WhenAll' on completion
    // 5. PourMilk signals 'WhenAll' on completion
    // 6. 'WhenAll' resumes the current method from saved state.
    
    // The built-in concurrency control removes the
    // complexity of writing a synchronization logic
    // of distributed workflows.
  }
}

Quick Start

The technology currently matures with early adopters in a closed environment. You can self-start by following these guides:

Cannot find what you are looking for? Ask me a question!
drawing
— Serge Semenov

Problems it Solves

High-level language-integrated abstractions hide a lot of implementation details like:

  1. Unified Service Communication - both external and internal; HTTP, gRPC, message queues, event streams.
  2. API specification is auto-generated.
  3. Pub-Sub is simply declarative in the code.
  4. Transparent serialization and wire format.
  5. Stateful workflows are merely methods.
  6. Minimal learning curve.
  7. Clean Code up to 5x smaller in size.
  8. Near-zero cost of programming microservices.
  9. Delays design decisions.
  10. No specific framework is needed.
  11. Exactly once execution for mission-critical apps.
  12. No error handlers in the code.
  13. Simplified testing due to the absence of non-functional code.
  14. Easy API and workflow versioning.
  15. Unified approach for distributed tracing.

More Info

Publications:

"Conquest of Distributed Systems":

References:

Why D-ASYNC

We believe that every developer deserves the right of creating microservices without using any framework 🤍

展开阅读全文

代码

评论

点击引领话题📣
暂无内容
发表了博客
{{o.pubDate | formatDate}}

{{formatAllHtml(o.title)}}

{{parseInt(o.replyCount) | bigNumberTransform}}
{{parseInt(o.viewCount) | bigNumberTransform}}
没有更多内容
暂无内容
发表了问答
{{o.pubDate | formatDate}}

{{formatAllHtml(o.title)}}

{{parseInt(o.replyCount) | bigNumberTransform}}
{{parseInt(o.viewCount) | bigNumberTransform}}
没有更多内容
暂无内容
暂无内容
0 评论
0 收藏
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部