原文和更新参见:
Ray Linn的EJB.CC
Axum 一个刚刚问世.net家族的新丁,几乎是和这篇文章一样新。它的诞生只为一个目的:一切为了并行。
编写并行程序并不容易,首先要将方案切割为许多并行任务(Task)。较为简单的方案,如计算每只股票的年收益率,很容易实施并行,因为任务之间彼此独立。但另外一些方案则十分复杂,任务之间彼此依赖且要相互协作,比如网络游戏。
Axum试图提供一种更为自然的方式来安排组件之间的协作问题。换句话说,如果将方案按照交互式组件建模,在Axum中编码会更为直接了当,而且你可能可以不被许多常见的并发问题所困扰。
并行的另一个目的是为了提速。经常,程序的反应速度总被象I/O或者用户输入这样的慢速组件所拖累。比如email客户端通过慢速的网络下载邮件的时候,程序还应该能继续响应用户的动作。
Axum的目标之一就是程序不需要再担心并发问题,理论上,你的程序将变得快速而且响应及时。为此,Axum不允许自由的共享和变更线程的状态,而只允许“有节制地”存取共享的状态,这解决了许多并发问题。
从"Hello,World"开始
Axum的安装包提供了Visual Studio的集成,你可以在Visual Studio 2008中使用Axum的解决方案。
我们从最简单的"Hello,World"入手。
using System;
agent Program : Microsoft.Axum.ConsoleApplication {
override int Run(String[] args) {
Console.WriteLine("Hello, World!.....MS Axum By Ray_Linn!");
}
}
这段程序以关键字“agent”开始,Axum中“代理”的概念来自模式中常见的“参与者模式”:参与者被描述成自治的实体,互相之间则通过消息来沟通,处理它们从其他参与者接受的数据,并发送给其他参与者。Axum中参与者表现为“代理”. 用Axum编写程序都是在定义代理并安排他们之间的交互。在许多方面,基于代理编程都不同于面向对象编程。首先不同于对象,代理不提供公共方法或展示他们的状态。你不能“进入”代理修改任何字段。你不能调用代理的方法并等它给你结果。相反地,你可以给它发送消息,要求它完成之后给你个响应。
Axum提供了一些支持类库包括"ConsoleApplication"等代理,这个代理完成了控制台程序”所需的一些工作:启动,设置命令行参数,停止。
上面的程序中的代理衍生自ConsoleApplication,因此我们重写(Override)入口点的Run方法。因为Axum是.net家族中的一员,它可以分享已有的所有类库。比如程序中的System.Console.WriteLine就来自基础类库BCL.
消息流动 -Message-Passing
“消息流动”这个词是我杜撰的,因为它很形象地说明了Axum中的类似流水的消息处理方式,这里我们要介绍两个概念channel-通道和通道的端口port。
代理就像是个水处理机一样,它是提供数据处理的组件,它也有进水口和出水口--我们称之为通道(channel),不同的数据则从不同的通道端口(channel port)流经代理。先看个简单的例子
using System;
agent Program : channel Microsoft.Axum.Application {
public Program() {
// Receive command line arguments from port CommandLine String []
args = receive(PrimaryChannel::CommandLine);
// Send a message to port ExitCode:
PrimaryChannel::ExitCode <-- 0;
}
}
代理"Program"实现了一个通道Microsoft.Axum.Application。 从语法和语义上看,实现通道与继承父代理是截然不同的。一个代理继承另一个代理时,我们只要重写其中的一些虚方法,并添加自己另外一些方法即可。
而当一个代理实现通道之后(注意关键字"channel"紧跟在代理声明的冒号之后),它就和水管一样,一头连在进水端,我们通常叫"Implementing End",另一段连在出水端 - "Using End",连在其后的其他组件就成为了客户端。
通道的存在就是为了定义和传输数据而不提供任何处理,数据的处理由代理来完成。
例子中的Application Channel的"Using End"是由Axum运行时实现的。运行时实例化了一个实现了Microsoft.Axum.Application的代理,并复杂将命令行参数发送至通道的CommandLine端口,然后监听ExitCode端口,收到消息的时候,程序就退出了。
而我们的代理“Program"则在CommandLine端口上等待消息的到来,并负责发送完成信号到ExitCode端口(操作符 <--)。Program代理内建了属性PrimaryChannel来存取所实现的通道,有时候我们称它为“代理的主通道”。双冒号“::”则用来存取通道的端口。
请注意上面提到的“等待消息”。Axum中,接收消息是阻塞操作,这意味着从空端口读取数据的动作将延迟到消息被送抵。另一方面消息发送是异步的,消息发送者不需要一直等待消息被送至目的地。
消息的异步编程
随着消息成为代理之间的主要通讯手段,现在我们需要一些系统的方法来处理它们。总体上,我们把这称为“编曲-orchestration”.Axum提供了两种截然不同的编曲方法:基于控制流与基于数据流。通常,二者被联合使用以实现最后的效果。
在Axum中,消息在交互点之间被发送和接收。消息起源的交互点被称为“源头”,消息的目的地则被称为“目标”。一个交互点可同时成为源头与目标,这意味着,它可以同时发送和接受消息。许多交互点可以连接成数据流网。
简单的说,数据流网构建了数据的转换过程,并产生结果。如果网络上的一些节点间相互依赖,使用数据流网是有利的,由此可并发执行。
不同的是,控制流逻辑是基于条件表达式,循环,方法调用这些逻辑,数据流网则基于在网络中传递、过滤、广播、负载平衡和加入消息的逻辑。请看一个斐波纳契数列的例子:
agent MainAgent : channel Microsoft.Axum.Application {
function int Fibonacci(int n) {
if( n<=1 ) return n;
return Fibonacci(n-1) + Fibonacci(n-2);
}
int numCount = 10;
void ProcessResult(int n)
{
Console.WriteLine("Ray_Linn's Fibonacci: "+ n);
if( --numCount == 0 )
PrimaryChannel::ExitCode <-- 0;
}
public MainAgent()
{
var numbers = new OrderedInteractionPoint<int>();
// Create pipeline:
numbers ==> Fibonacci ==> ProcessResult;
// Send messages to numbers:
for( int i=0; i<numCount; i++ )
numbers <-- 42-i;
}
}
函数“Fibonacci”带有关键字“function",在Axum中,function意味着函数不修改它自身之外的任何状态,换句话说,它的执行不会有任何副作用。如果你试图修改numCount,或者想在“Fibonacci”函数中发送消息,编译器就会报错。
接着看下MainAgent的构造器。第一行创建了OrderedInteractionPoint<int>的实例,它是一个同时扮演“源头”与“目标”的交互点。“ordered”意味着消息接受和发送的顺序是一致的。
接下来,代理创建了用消息传递操作符 “==>”构造了数据流网。
numbers ==> Fibonacci ==> PrintResult;
这个表达式应该被理解为“当一个消息到达交互点“number”时,将它传递到由“Fibonacci”实现的转换交互点,最后传递结果到PrintResult方法”。
将消息从一个节点传递至另一个节点的数据流网相当普遍的,它有一个名称“管道”。
由于Fibonacci函数没有副作用,Axum运行时会产生能让程序最高效运行所需的线程,以便并发执行转换工作。
函数经常被用在管道和其他类型网络中的并发执行节点上。
版权所有,如果转载,请站内联系。
分享到:
相关推荐
1. axum框架概述:axum是一个用RUST编程语言编写的web框架,它是一个高性能、异步的框架,可以让我们更便捷地构建web应用。 2. 环境搭建:在开始使用axum之前,需要先搭建好RUST的开发环境,并安装好axum相关的依赖...
《Axum程序员指南》是一本深入探讨Axum编程语言的专业书籍,主要面向正在学习或已经从事Axum开发的程序员。Axum是由微软开发的一种新型的、高性能的、并发友好的编程语言,它旨在提高现代多核处理器环境下的软件开发...
OpenTelemetry Rust Rust 实现。||概述OpenTelemetry是工具,API和SDK的集合,用于检测,生成,收集和...(), Box < dyn>> { // Create a new instrumentation pipeline let tracer = stdout :: new_pipeline (). insta
You can start with the example actix-app, axum-app, dioxus-desktop or ntex-app. It requires Rust 1.75+ to build the project. cd examples/axum-app cargo run Here is the simplest application to run a ...
rust axumweb web rust,,redis,ormRibatis,casbin-rs, ,jwt casbin-rs websocket rust rust rust rust rust
在Rust编程语言中,处理HTTP请求特别是涉及文件上传时,`multipart`是一个非常重要的库。这个库提供了与后端无关的解决方案,使得开发者能够轻松地在HTTP客户端和服务器之间处理多部分表单数据,包括文件上传。在这...
我选择这个主题是因为我在EIABC校园学习,所以发现这个主题与我们所从事的领域以及课程的类型非常相关,因为这些站点在埃塞俄比亚人口中非常受欢迎,因此创建此网站几乎就像将埃塞俄比亚描述为一个所有的。
Rust是一种系统级编程语言,它专注于速度、内存安全和并行性,被广泛用于构建高性能软件,尤其是网络服务、操作系统组件以及游戏引擎。 描述中提到,创建者由于曾经丢失了所有C语言的源代码,因此决定将Rust项目...
本项目是一款基于Java实现的Rust通用代码生成器,代码名为“莲花”。该生成器旨在为Java开发者提供高效、通用的Rust代码生成服务,支持1.69版本Rust环境。项目源码包含2850个文件,涵盖HTML、CSS、Java、JavaScript...
基于Rust语言的新一代组装式应用开发框架,它强调 简单性、可扩展性和生产力。用于快速应用程序开发的开箱即用功能。最小设计、可组合架构和高级抽象。采用 API 优先的 approch 进行具有开放标准的开发。采用实用的...
async-graphql是一个用Rust语言实现的高性能GraphQL服务器库,它允许开发者轻松地构建符合GraphQL规范的服务。在本文中,我们将深入探讨async-graphql库的关键特性和如何在Rust项目中使用它。 首先,让我们了解...
基于Rust语言的新一代组装式应用开发框架。zino是 Rust 中可组合应用程序的下一代框架 它强调简单性、可扩展性和生产力。开箱即用的功能,可快速开发应用程序。最小的设计、可组合的架构和高级抽象。采用 API 优先的...
此版本是第一个功能完整的可用版本,支持自动登录模块,支持Axum最新版0.6.18,彻底改进了数据库访问层,解决了每次查询新建一个数据库链接,以致只能查询10余次的重大缺陷,经过更多测试,此版本支持MariaDB,MySQL和...
此版本升级Axum至0.6.6,并消除2/3的编译警告。此版本支持Go语言通用代码生成器仙童的模板直接生成Rust代码生成物。也支持Java兼容性。支持Excel,PDF数据导出。支持Vue,ElementUI的独立前端。支持MySQL,MariaDB和...
WebDAV Handler库,以`webdav-handler-rs`命名,是专为Rust编程语言设计的一个高效、灵活的处理程序库。该库的主要目标是支持与HTTP服务器框架如Hyper、Warp以及Actix-Web等无缝集成,提供WebDAV协议的实现。WebDAV...
它在科学界享有极高的声誉,以其丰富的功能和灵活性著称,尽管学习曲线相对陡峭,但相比竞争对手如SPSS的SigmaPlot和MathSoft的Axum,Origin提供了更多的功能。Origin的主要版本包括5.0、6.0、6.1、7.0和7.5,而描述...
为了适应海量规模存储环境的要求,设计并实现了一种块级别的带内存储虚拟化系统(AXUM)。它使用连续空间段来组织虚拟盘和物理盘,减少了元数据的空间开销。并通过实现目标器模式的虚拟化服务,提供良好的兼容性。...
《掌握和精通Mathcad》是一本专门针对Mathcad软件操作和应用的教学书籍。Mathcad是由Mathsoft公司于1986年推出的交互式数学系统,它提供了一个直观且高效的数学计算环境,受到工程师、科学家和学生的广泛欢迎。本书...
JDK(Java Development Kit)是由Sun Microsystems针对Java开发人员推出的一款开发工具包。自Java诞生以来,JDK已成为最广泛使用的Java SDK之一。JDK不仅仅是一个编译工具,更是一套完整的开发环境,包括了编写、...