Orleans例子再进一步
Orleans例子再进一步
这是Orleans系列文章中的一篇.首篇文章在此
步骤
现在我想再添加一个方法,到IGrains项目内,这个方法里面有个延迟3秒,然后返回一个Task<string>.就叫做DelayedMsg吧,如下图所示:
我调用了这个DelayedMsg,同时又调用了SayHello函数,看看效果:注意这个DelayedMsg的调用方法没有await.
虽然我的SayHello的调用时间紧随着DelayedMsg之后,
可是发现SayHello仍然延迟了3秒才出来,这是因为SayHello必须等待DelayedMsg方法执行完毕.如图:
这说明一件事情,就是grain接受消息是异步的。而且Grain处理消息是“单线程约束”的。
如果有两个Grain实例,一个调用DelayMsg,而另一个调用SayHello,可以发现此时的SayHello会立马执行,如图:
这又说明两个不同的Grain实例是在不同的线程执行的。
解释一下
好了,初步的例子就展现到此,现在来解释一下下…
1.往Grain发送消息,实质上是调用它的接口,但是不论何时,不论何地,哪怕是不同的计算机,调用具有相同标识的Grain里的任何一个方法,这些方法都会在单一的线程中被执行。所以如果Grain有个list类型的私有字段,在操作的这个字段的时候就无需架锁。因为list根本不会出现“脏读”。所以在Orleans的世界里,消息的处理可以做到全程无锁。
2.Grain的标识:Orleans使用以下类型作为Grain的标识:Guid,Long,String,以及组合标识。在面向对象的环境中,做到严格区分一个实例和一个实例的引用,并不是很容易,有时候很容易混淆,就算混淆了对程序也不会有太大影响.在分布式的环境里想要用一个对象的引用来代表这个对象,这是做不到的.因为对象的引用只有在一定的地址空间内才有效,而在分布式的环境下,系统有可能分布在多台机器上.
这就要求用一个新的东西来代表Grain.这就是使用标识的原因.使用标识时,Orleans要求主标识对于一个特定的grain类来说,要唯一.因此一个grain的完整标识必须时由它的类型和它的主标识组成.在实际使用的过程中,很少去关注grain的完整标识,在记录日志的时候,完整标识也许有点用.大部分时候只需要知道主标识就可以了,Orleans提供了几个方法,可以调用它们得到grain实例的主标识:在Grain类的内部,可以通过调用this. GetPrimaryKeyXXX()得到本实例的标识.而在Grain的外部,则只能通过指定主标识来往对应的对象发送消息,比如以下语句:
GrainClient.GrainFactory.GetGrain<IExample>() ;
简单一句话,Orleans通过标识来区分grain的所有实例.要想使用Grain必须通过GetGrain方法得到一个对应实例的引用,再通过调用此引用的方法往对应对象发送消息.
组合标识对应的可以继承一个IGrainWithGuidCompoundKey或者IGrainWithIntegerCompoundKey,如下所示.
public interface IExampleGrain : Orleans.IGrainWithIntegerCompoundKey { Task Hello(); }
在客户端,你可以在GrainFactory.GetGrain方法中设置第二个参数.
var grain = GrainClient.GrainFactory.GetGrain<IExample>(, "a string!");
为了在grain内部获得主标识,我们需要调用GetPrimaryKey 的方法.
public class ExampleGrain : Orleans.Grain, IExampleGrain { public Task Hello() { string keyExtension; long primaryKey = this.GetPrimaryKey(out keyExtension); Console.WriteLine("Hello from " + keyExtension); return TaskDone.Done; } }
3.Grain是虚拟的Actor---.Orleans的Actor模型更进一步,它是”虚拟Actor”的模型.任何时候都可以直接使用GetGrain方法得到一个Grain的引用.就好像对应的Grain对象早就创建好了,等待被人引用一样.这种表现背后的工作都由silo来完成,当你调用GetGrain<IgrainA>方法后,意图得到grainA类的一个实例的引用,silo会在服务端的内存中通过复制来激活一个grainA的实例.这个复制内存的过程在Orleans中称之为激活(activation),所以每一个grain类都可以重写一个方法就是OnActivationAsyc.在这个方法里可以实现类似于初始化的动作.
激活一个Grain实例之后,如果长时间没有新的消息到达此实例,这个Grain也许会被反激活,进入休眠状态,这时候可以通过重写OnDeactivateAsync来干预反激活过程,大部分应该是些扫尾的工作.
不用显式的创建和销毁一个grain对象.关于虚拟Actor的进一步讨论,会在下一篇中继续进行.
4.Grain内部如果想要发送消息给其他的Grain.必须使用类内部的GetGrain<>方法,而不能通过GrainClient.GrainFactory.GetGrain<>方法.
5.Grain可以有字段,这些字段可以是公共的,也可以是静态的.但是如果这样设计,使用者必须小心处理.
其实在Orleans的世界里,公共字段没有太大的用处,因为你要想得到Grain的实例,必须通过GetGrain方法,而此方法返回的引用里并没有字段,而只有方法(因为是接口)…
静态字段也许有用,比如有人想要用一个静态字段来保存所有活动的GrainA类实例,一个办法就是使用静态字段.但是这是一个麻烦的办法,因为此字段有可能”脏读”.要想有效的控制此字段的读写,就要架锁..这破坏了很多Orleans带来的好处..,简单的办法就是再创造一个grainB类型,让它的一个实例来统一管理所有的GrainA实例.这样就还是一个纯洁的Orleans世界.
好了,这样简单Orleans完全体就说完了.可是这个例子还是太过于简单了.虽然体现了Orleans的系统的主要方面,但是并不是所有的关键方面.仍然是一个类似于WCF程序或者类似于RPC的框架.吃瓜群众的c#理论知识还是很丰富的.
在orleans框架里,Grain就是对应的理论模型的actor,所以很多语境下,actor和grain是相同的.这个必须要强调下.
为了进一步破坏吃瓜群众的阴毛..我决定弄一个稍微复杂的例子,让Orleans摆脱这些帽子.
Orleans例子再进一步的更多相关文章
- 泛化之美--C++11可变模版参数的妙用
1概述 C++11的新特性--可变模版参数(variadic templates)是C++11新增的最强大的特性之一,它对参数进行了高度泛化,它能表示0到任意个数.任意类型的参数.相比C++98/03 ...
- -C++11可变模版参数(转载)
泛化之美--C++11可变模版参数的妙用 1概述 C++11的新特性--可变模版参数(variadic templates)是C++11新增的最强大的特性之一,它对参数进行了高度泛化,它能表示0到任意 ...
- C++一些新的特性的理解(二)
1 C++11多线程thread 重点: join和detach的使用场景 thread构造函数参数 绑定c函数 绑定类函数 线程封装基础类 互斥锁mutex condition notify.wai ...
- 泛化之美 —— C++11 可变参数模板的妙用
概述 首先这篇文章出自博客园作者:[qicosmos ],我对本文的实例代码进行了学习.思考和整理纠正,理清了文章的全部细节,觉得这是一篇让我受益匪浅的文章.之所以会接触「可变参数模板」这部分的内容, ...
- Orleans稍微复杂的例子—互动
这是Orleans系列文章中的一篇.首篇文章在此 我费力费心的翻译过官方的教程,但是本人英语词汇量不高,可是架不住电子词典啊-只要肯花时间,我这些内容谁都可以做出来.所以这个事例告诉我们一个道理,那就 ...
- Orleans入门例子
Orleans入门例子 这是Orleans系列文章中的一篇.首篇文章在此 一.铺垫. 虽然是个入门例子,还是需要一些铺垫. Orleans的最小完全体,应该分为2个部分.一个是Orleans客户端, ...
- Orleans 初接触(一) 入门例子
[返回导航] 在简单了解了Orleans 之后我们可以通过几个例子去加深印象 一.Orleans入门例子 这个例子是跟着<Orleans入门例子>(https://www.cnblogs. ...
- 一些ServiceFabric、Orleans、Asp.net Aore的例子
Sample: ServiceFabric + Orleans + Asp.net Core : Asp.net Core 142 samples for ASP.NET Core 2.1 funda ...
- C# 关于委托和事件的妙文:通过一个例子详细介绍委托和事件的作用;Observer模式简介
委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见 ...
随机推荐
- eclipse从SVN检出项目之后,项目出错
今天公司把我分配到另一个项目组工作,然后下午使用SVN检出项目,出了问题 1.从SVN检出项目之后,要导入jar包.结果右键项目找不到Build Path,问了大牛才知道是这里的问题,一共四个步骤解决 ...
- 记一次redis挂机导致的服务雪崩事故~不对,是故事
事故时常有,最近特别多!但每次事故总会有人出来背锅!如果不是自己的锅,解决了对自己是一种成长,如果是自己的锅,恐怕锅大了,就得走人了,哈哈哈... 这不,最近又出了一个锅:从周五开始,每天到11点就不 ...
- 转载文章之提供给开发者 10 款最好的 Python IDE
Python 非常易学,强大的编程语言.Python 包括高效高级的数据结构,提供简单且高效的面向对象编程. Python 的学习过程少不了 IDE 或者代码编辑器,或者集成的开发编辑器(IDE).这 ...
- MySQL慢查询日志
实验环境: OS X EI Captian + MySQL 5.7 一.配置MySQL自动记录慢查询日志 查看变量,也就是配置信息 show (global) variables like '%slo ...
- 以芯片直读方式得到的全盘镜像解析及ext4日志区域解析
之前在centos中分析了/dev/sda1下的结构,但当对象是一块以芯片直读方式作出来的全盘镜像呢? 这次以安卓手机的全盘镜像为对象,尝试按照ext4文件系统结构手动解析,加强对ext4文件系统.E ...
- 收集了一些容易出错的题,可能大家也不会注意到的基础知识(js)
---恢复内容开始--- 1.题中运用到函数表达式.构造函数.原型.优先级.this. 2.参数影响 3.对原型的运用 4.递归 5.基本类型与引用类型传递 6.优先级 7.自调用函数 ---恢复内容 ...
- Android帧动画笔记
创建drawable资源文件,选择animation-list<?xml version="1.0" encoding="utf-8"?><a ...
- 小哈学Python第二课:Hello Word
Python入门 1.Hello World 2.Hello World
- JAVA的高并发编程
一.多线程的基本知识 1.1进程与线程的介绍 程序运行时在内存中分配自己独立的运行空间,就是进程 线程:它是位于进程中,负责当前进程中的某个具备独立运行资格的空间. 进程是负责整个程序的运行,而线程是 ...
- (转)Synchronized(对象锁)和Static Synchronized(类锁)的区别
场景:面试的时候经常用得到! 1 综述 Synchronized和Static Synchronized区别 一个是实例锁(锁在某一个实例对象上,如果该类是单例,那么该锁也具有全局锁的概念),一个是全 ...