域与状态共享
消息传递是种优秀的沟通机制,但它要消息中的数据必须可以被深拷贝或者不可变。但有时代理间共享数据会让程序更有效率,也更简单,当然,要提供一种安全的方式。
这就是设计出域的目的。域存在的目的是允许一组代理安全的共享状态,同时将该状态与其他人等隔离开来。
在代理间共享状态
象普通类,域可以包含字段与方法,但更重要的,域定义可以包含代理的定义,在域内定义的代理可以存取域的字段。如
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 Programmers Guide
它包括拉利贝拉(Lalibela)的岩石凿成教堂,阿克苏姆(Axum)方尖碑和哈拉尔(Harar)朱古拉斯主题。 我选择这个主题是因为我在EIABC校园学习,所以发现这个主题与我们所从事的领域以及课程的类型非常相关,因为...
此版本升级Axum至0.6.6,并消除2/3的编译警告。此版本支持Go语言通用代码生成器仙童的模板直接生成Rust代码生成物。也支持Java兼容性。支持Excel,PDF数据导出。支持Vue,ElementUI的独立前端。支持MySQL,MariaDB和...
multipart:与后端无关的扩展,用于在Rust的HTTP库中上传文件
webdav-handler-rs:用于hyper,warp,actix-web或任何可使用“ http”板条箱进行接口的东西的webdav处理程序库
为了适应海量规模存储环境的要求,设计并实现了一种块级别的带内存储虚拟化系统(AXUM)。它使用连续空间段来组织虚拟盘和物理盘,减少了元数据的空间开销。并通过实现目标器模式的虚拟化服务,提供良好的兼容性。...
“不那么难” OAuth2客户端OAuth2确实不那么难,您知道吗? 文档许可证版权所有:copyright:2015,Curtis McEnroe,[受电子邮件保护]“不那么难” OAuth2客户端OAuth2确实不那么难,您知道吗? 文档许可证版权:...
Rust_Projects 之所以这样做,是因为我最近丢失了所有C文件,并且不想在Rust项目中发生同样的情况。 这个GitHub存储库供我回顾,看看我在几个月/几年中的进步。
Working through step-by-step exercises using P/LINQ, DLR, MEF, MVC, IronPython, Axum, and Ajax, you will learn a variety of approaches to building each of the key application tiers common to all web ...
zino是 Rust 中可组合应用程序的下一代框架 它强调简单性、可扩展性和生产力。突出:开箱即用的功能,可快速开发应用程序。极简设计、可组合架构和高级抽象。...与 actix-web、axum 和 dioxus 完全集成。
此版本是第一个功能完整的可用版本,支持自动登录模块,支持Axum最新版0.6.18,彻底改进了数据库访问层,解决了每次查询新建一个数据库链接,以致只能查询10余次的重大缺陷,经过更多测试,此版本支持MariaDB,MySQL和...
formdata文档位于https://mikedilger.github.io/formdata。该库提供了一种用于存储多部分/表单数据数据的类型,因为formdata文档位于... multipart / form-data格式,如RFC 7578所述。... ... he
各种绘图统计软件,包括常用的Origin,SigmaPlot等,虽然每种不是很详细,但还是可以帮助了解下这些软件的优势和特点。