Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
当第一次调用执行组件的任何方法时即可激活该执行组件。 如果执行组件未在可配置的时间段内使用,则会停用执行组件(执行组件运行时回收垃圾)。 还可以在任何时候手动删除执行组件及其状态。
执行组件激活
当激活了某个执行组件,将出现以下情况:
- 当有请求调用一个参与者时,如果该参与者尚未处于活动状态,则会创建一个新的参与者。
- 如果执行组件为维护状态,则加载此执行组件的状态。
- 将调用
OnActivateAsync(C#) 或onActivateAsync(Java) 方法(这些方法可以在执行组件实现中被重写)。 - 现在该执行组件被视为处于活动状态。
执行组件停用
当停用了某个执行组件,将出现以下情况:
- 当执行组件在一段时间内未使用时,将从 Active Actors 表中删除该执行组件。
- 将调用
OnDeactivateAsync(C#) 或onDeactivateAsync(Java) 方法(这些方法可以在执行组件实现中被重写)。 这会清除此执行组件的所有计时器。 不可从该方法中调用诸如状态更改的执行组件操作。
小窍门
Fabric 执行组件运行时发出一些与执行组件激活和停用相关的事件。 它们可用于进行诊断和性能监视。
执行组件垃圾回收
停用某个执行组件后,将释放对此执行组件对象的引用,并且通常使用公共语言运行时 (CLR) 或 Java 虚拟机 (JVM) 垃圾回收器对其进行回收。 垃圾回收只清除执行组件对象;它“不会”删除存储在执行组件的状态管理器中的状态。 当下次激活此执行组件时,将创建一个新的执行组件对象,并还原其状态。
出于停用和垃圾回收的目的,什么算作“正在使用”?
- 正在接收调用
-
正在调用的
IRemindable.ReceiveReminderAsync方法(仅当执行组件使用提醒时该方法才可用)
注释
如果执行者使用计时器并调用其计时器回调,则 不会 算作“正在使用”。
在深入了解停用的详细信息之前,必须定义以下术语:
- 扫描时间间隔。 这是执行组件运行时为可以停用和进行垃圾回收的执行组件扫描其活动执行组件表的时间间隔。 此状态的默认值为 1 分钟。
- 空闲超时。 这是在停用执行组件并对其进行垃圾回收之前,该执行组件需要保持未使用(空闲)状态的时间。 此状态的默认值为 60 分钟。
通常,无需更改这些默认值。 但是,如有必要,可在注册ActorServiceSettings时通过 更改这些时间间隔:
public class Program
{
public static void Main(string[] args)
{
ActorRuntime.RegisterActorAsync<MyActor>((context, actorType) =>
new ActorService(context, actorType,
settings:
new ActorServiceSettings()
{
ActorGarbageCollectionSettings =
new ActorGarbageCollectionSettings(10, 2)
}))
.GetAwaiter()
.GetResult();
}
}
public class Program
{
public static void main(String[] args)
{
ActorRuntime.registerActorAsync(
MyActor.class,
(context, actorTypeInfo) -> new FabricActorService(context, actorTypeInfo),
timeout);
}
}
对于每个活动角色,角色运行时会跟踪其空闲时间(即未使用的时间)。 执行组件运行时每隔 ScanIntervalInSeconds 检查每个执行组件,以查看是否可以对它进行垃圾回收,并且如果它已空闲 IdleTimeoutInSeconds,则对其进行标记。
任何时候只要使用了执行组件,其空闲时间都会重置为 0。 此后,仅在此执行组件再次空闲 IdleTimeoutInSeconds,才会对其执行垃圾回收。 如果执行执行组件接口方法或执行组件提醒回调,则想到执行组件被视为已使用。 如果执行其计时器回调,则执行组件不被视为已使用。
下图通过单个执行组件的生命周期来说明这些概念。
此示例显示了执行组件方法调用、提醒和计时器对此执行组件的生存期的影响。 值得一提的是有关示例的以下几点:
- ScanInterval 和 IdleTimeout 分别设置为 5 和 10。 (单位在这里无关紧要,因为我们的目的是说明这个概念。
- 按照扫描间隔时间为 5 的定义,对要执行垃圾回收的执行组件进行的扫描发生在 T = 0、5、10、15、20、25 时。
- T = 4、8、12、16、20、24 时启动定期计时器,并执行其回调。 它不会影响actor的空闲时间。
- 在 T = 7 时调用的执行组件方法将空闲时间重置为 0,并延迟此执行组件的垃圾回收。
- 执行组件提醒回调在 T = 14 时执行,并进一步延迟执行组件的垃圾回收。
- 在 T = 25 时的垃圾回收扫描期间,执行组件的空闲时间最终超过空闲超时时间 10,将对此执行组件进行垃圾回收。
演员模型在执行其某个方法时,不会被垃圾回收,无论执行这个方法所需的时间是多少。 前面曾提到,执行执行组件接口方法和提醒回调可以防止通过将执行组件的空闲时间重置为 0 进行垃圾回收。 计时器回调的执行不会将空闲时间重置为 0。 但是,执行组件的垃圾回收会推迟到计时器回调执行完毕。
手动删除执行组件及其状态
已停用执行组件的垃圾回收只会清理执行组件对象,但它不会删除存储在执行组件状态管理器中的数据。 重新激活执行组件后,其数据将通过状态管理器再次提供给它。 如果执行组件在 State Manager 中存储数据,并且已停用但从未重新激活,则可能需要清理其数据。 有关如何删除执行组件的示例,请阅读删除执行组件及其状态。