域与状态共享
消息传递是种优秀的沟通机制,但它要消息中的数据必须可以被深拷贝或者不可变。但有时代理间共享数据会让程序更有效率,也更简单,当然,要提供一种安全的方式。
这就是设计出域的目的。域存在的目的是允许一组代理安全的共享状态,同时将该状态与其他人等隔离开来。
在代理间共享状态
象普通类,域可以包含字段与方法,但更重要的,域定义可以包含代理的定义,在域内定义的代理可以存取域的字段。如
domain Chatroom {
private string m_Topic;
private int m_UserCount;
reader agent User : channel UserCommunication {
// ...
}
writer agent Administrator : channel AdminCommunication{
// ...
}
}
这里声明的域Chatroom包含两个代理 User和Administrator。chatroom让许多不同的用户互相交换信息,(或在管理员间),并且读取域的状态,如m_Topic,但不能改变这些字段。administrator是唯一能改变域状态的代理。让我们更仔细的探讨一下reader和writer的区别。
Reader与Writer的语义
Reader和Writer锁相当普遍地用同步上,它允许在多个读用户或者一个写用户间存取一个共享资源。这保证了读用户总是看到资源的一致状态,且两个写用户不会彼此干扰。
Axum中的代理遵循同样的原则。声明成"reader"的代理只允许读域的状态,而写代理可以读写这个状态。既不是reader也不是writer的代理只能读取域内不可变状态。
在代理内可以用parent关键字来存取所在域的字段和方法。上面的User代理可以这样读取域的状态:
reader agent User : channel UserCommunication
{
public User() {
if( parent.m_Topic.Contains("Axum") ) {
// Start talking to other users in this chatroom
}
else {
// Do nothing and leave
}
}
}
如果这个代理试图改变域的状态,编译则无法通过。
与"this"类似,parent是可以省略的。关键字parent只在需要消除同名的域成员与本地变量的歧义时才是必须的,否则使用parent只是个人习惯问题。
同样,代理也被限制改变系统的全局状态。例如,代理不能写一个静态字段,或者调用可以改变(甚至只是可能)静态字段的方法。
当你开始用Axum编写程序的时候,你会注意到一些代码(特别是第三方的类库)不能被编译除非你把Agent标记为writer,或把类标记为isolated(后面会详述)。虽然某些情况下这样做事可以的,但要记住同一域内的writer代理是无法并发执行的。只有一个域且所有代理都是writer的应用只是个单线程。
Axum有个“后门”让你能执行那些会改变共享状态的代码 -- 使用unsafe关键字。正如它的名字一样,使用unsafe就意味着代码不安全,你应该只在你确定代码不修改任何共享状态或这些修改是良性的。让程序慢点但无错误总比快而到处是错强多了。
reader agent User : channel UserCommunication {
private WriteLog(string str) {
unsafe { Logger.WriteLine(str); }
}
}
这儿我们想要使用unsafe如果第三方的类Logger使用它自己的同步,或者我们不担心记录文件可能出现的行错位。
宿主代理 Hosting Agent
回忆第一个Adder例子,通道Adder的实例是这样被创建的:
var adder = AdderAgent.CreateInNewDomain();
这样创建了由代理AdderAgent所实现的,通道Adder的两个ends(记得么 implement end和using end),并返回通道Adder的using end.和名字所示一样,CreateInNewDomain方法同时也创建了域,并让AdderAgent的parent参考指向它。
每次都这样创建一个新的域实例意味代理间无法共享状态,因为他们的parent参考指向了不同的域实例。显然,我们需要一种方法来解决实例化代理并与域相关联的问题。
Hosting是种将代理类型与域的特殊实例关联的方法。 通过保有代理的类型,可以如下:
Host<AdderAgent>("my adder");
当用户请求保有在"my adder"地址的"Adder"服务时,代理AdderAgent将被实例化,关联到当前域,并返回通道Adder的using end。保有代理类型的地址可以是任何表达式,只要支持“等于”比较。这儿我们选择字符,因为它是描述性的。
因为Host方法将代理与当前域相关联(它是个域方法),它只能在域的上下文中被执行,而不能在域之外声明的agent中。
现在,代理可以这样被实例化:
var adder = new Adder("my adder");
这可以理解为“创建通道channel的using end,该通道由保有在地址“my adder"的服务所实现”。
注意:用户不了解这个代理的类型,他所要关心的只是通道的类型和实现该通道的服务的地址。
为了更好理解代理作为服务的想法,想一下一个给个数字会返回相应的斐波那契数列的通道。不象加法,只有一种有意义的方式,斐波那契额数列可以用很多种不同的计算方法,高效的低效的。
同一个Fibonacci通道可以由两个不同的代理来实现,让我们称他们为FibonacciSlow和FibonacciFast,这两个代理类型被保有在不同的地址上:
Host<FibonacciSlow>("slow");
Host<FibonacciFast>("fast");
现在根据用户的需要,她可以在这个或那个代理上实现Fibonacci通道。
Fibonacci fibChannel;
if(gotTimeToSpare) {
fibChannel = new Fibonacci("slow");
}
else {
fibChannel = new Fibonacci("fast");
}
var request = fibChannel::Number <-- 42;
当代理提供的服务不再需要的时候,可以用evicted方法将其从域内清除出去。
Evict("slow");
Evict("fast");
记住从域内清除一个代理类型不会影响已经创建的该代理类型的实例,不过,无法再通过操作符new创建更多的该代理的实例。一旦该代理类型被清除了,试图创建它的实例会导致一个运行时异常。
版权所有,如有转载,请站内联系.
分享到:
相关推荐
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客户端和服务器之间处理多部分表单数据,包括文件上传。在这...
它包括拉利贝拉(Lalibela)的岩石凿成教堂,阿克苏姆(Axum)方尖碑和哈拉尔(Harar)朱古拉斯主题。 我选择这个主题是因为我在EIABC校园学习,所以发现这个主题与我们所从事的领域以及课程的类型非常相关,因为...
基于Rust语言的新一代组装式应用开发框架,它强调 简单性、可扩展性和生产力。用于快速应用程序开发的开箱即用功能。最小设计、可组合架构和高级抽象。采用 API 优先的 approch 进行具有开放标准的开发。采用实用的...
Rust是一种系统级编程语言,它专注于速度、内存安全和并行性,被广泛用于构建高性能软件,尤其是网络服务、操作系统组件以及游戏引擎。 描述中提到,创建者由于曾经丢失了所有C语言的源代码,因此决定将Rust项目...
基于Rust语言的新一代组装式应用开发框架。zino是 Rust 中可组合应用程序的下一代框架 它强调简单性、可扩展性和生产力。开箱即用的功能,可快速开发应用程序。最小的设计、可组合的架构和高级抽象。采用 API 优先的...
此版本升级Axum至0.6.6,并消除2/3的编译警告。此版本支持Go语言通用代码生成器仙童的模板直接生成Rust代码生成物。也支持Java兼容性。支持Excel,PDF数据导出。支持Vue,ElementUI的独立前端。支持MySQL,MariaDB和...
本项目是一款基于Java实现的Rust通用代码生成器,代码名为“莲花”。...代码生成器依赖Axum 0.6.20、Tokio 1.32.0、sqlx 0.7.1等库,并支持连接MariaDB、MySQL 8、PostgreSQL、Oracle等多种数据库。
它在科学界享有极高的声誉,以其丰富的功能和灵活性著称,尽管学习曲线相对陡峭,但相比竞争对手如SPSS的SigmaPlot和MathSoft的Axum,Origin提供了更多的功能。Origin的主要版本包括5.0、6.0、6.1、7.0和7.5,而描述...
async fn add_number(_ctx: Context<'_>, number: i32) -> i32 { number * 2 } } ``` 在这个例子中,我们定义了一个名为`Query`的对象类型,它有一个名为`hello`的字段,以及一个名为`Schema`的突变,包含`add_...
WebDAV Handler库,以`webdav-handler-rs`命名,是专为Rust编程语言设计的一个高效、灵活的处理程序库。该库的主要目标是支持与HTTP服务器框架如Hyper、Warp以及Actix-Web等无缝集成,提供WebDAV协议的实现。WebDAV...
尽管其学习曲线相对较陡峭,但Origin提供的强大功能使其在同类软件中独树一帜,与SPSS Scientific的SigmaPlot和MathSoft的Axum等竞争产品相比,Origin具有更多的数据分析和绘图选项。 Origin的核心功能分为两大部分...
为了适应海量规模存储环境的要求,设计并实现了一种块级别的带内存储虚拟化系统(AXUM)。它使用连续空间段来组织虚拟盘和物理盘,减少了元数据的空间开销。并通过实现目标器模式的虚拟化服务,提供良好的兼容性。...
“不那么难” OAuth2客户端OAuth2确实不那么难,您知道吗? 文档许可证版权所有:copyright:2015,Curtis McEnroe,[受电子邮件保护]“不那么难” OAuth2客户端OAuth2确实不那么难,您知道吗? 文档许可证版权:...
RustJavaRust rust 1.69Axum 0.6.20Tokio 1.32.0sqlx 0.7.1MariaDB, MySQL 8, PostgreSQLOracle