24、Ada 95 在分布式系统中的应用:HLA 运行时基础设施与网络协调语言实现

Ada 95 在分布式系统中的应用:HLA 运行时基础设施与网络协调语言实现

一、Ada 95 HLA 运行时基础设施

1.1 联邦成员加入流程

联邦成员加入过程较为简单。首先,联邦成员从运行时基础设施数据(RTID)获取对联邦执行数据交换(FedEx)的访问权限,然后告知 FedEx 自己要加入。作为回应,FedEx 会为联邦成员提供一个唯一的标识符(Id),以及已加入联邦成员的(访问权限,Id)对。联邦成员的运行时基础设施(RTI)内核首先会使用 FedEx 提供的联邦执行数据(FED)来初始化其内部数据。

1.2 分布式声明管理

发布或订阅对象类属性或交互的联邦成员必须通知所有其他已加入的联邦成员,原因如下:
- 可能有其他联邦成员在其加入之前就已订阅了它所发布的内容。发布联邦成员的内核需要确切知道哪些成员在订阅,以避免向所有已加入的联邦成员发送所有后续更新而浪费带宽。当联邦成员内核收到发布通知时,它会检查是否与自己的某些订阅匹配。如果匹配,它会通知发布联邦成员的内核自己的兴趣。
- 订阅联邦成员的内核需要通知发布联邦成员的内核,要求它们向自己发送更新。此外,出于分布式声明管理(DDM)的考虑,它需要知道发布联邦成员的信息(必须知道要通知哪些成员订阅区域的变化)。当联邦成员内核收到订阅通知时,如果其某些发布与之匹配,它会通知发出通知的内核。

订阅机制的控制流方案如下:

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;

    A([订阅]):::startend --> B(验证正确性):::process
    B --> C(通知订阅):::process
    C --> D{发布是否匹配}:::decision
    D -->|是| E(通知发布):::process
    E --> F(记住发布者):::process
    F --> G{是否开启更新}:::decision
    G -->|是| H(开启更新):::process
    H --> I(准备接收更新):::process
    I --> J([返回通知订阅]):::startend
    D -->|否| J
    G -->|否| J
    B --> K([返回订阅]):::startend

1.3 分布式对象管理

每个联邦成员内核管理一个对象实例字典,该字典包含联邦成员应用程序创建的实例以及一些发现的远程实例。发现机制有两个步骤:
- 如果应用程序订阅了某个类或其超类,内核会发现一个远程实例。
- 根据订阅匹配和当前反射策略,联邦成员应用程序会在第一次需要反射相关属性更新之前发现远程实例。

发现实例的类是该实例实际类的最低订阅超类,包括实际类。

传入的原子存储在两个队列中:一个用于“接收顺序”原子的先进先出(FIFO)队列(RO 队列),以及一个用于“时间戳顺序”原子的排序队列(TSO 队列)。传出的原子放入一个唯一的 FIFO 队列,该队列由一个发送任务尽快处理。

“可靠”传输模式通过同步调用(正常的 RACW 远程调用)实现。分布式系统附件保证被调用方“恰好执行一次”,并且调用方会等待远程调用完成,因此当远程调用返回时,可以确定数据已送达。“尽力而为”模式通过异步调用(使用带有异步编译指示的 RACW 远程调用)实现。语言保证被调用方“最多执行一次”。不过,无法确定数据是否已送达,但过程会快得多,因为调用方不会等待远程调用完成。

1.4 分布式时间管理

时间管理机制涉及每个受约束联邦成员(可以接收 TSO 消息的联邦成员)的 TSO 队列,以及每个调节联邦成员(可以发送 TSO 消息的联邦成员)的“时间状态”。

每个联邦成员必须能够计算下限时间戳(LBTS),即联盟中没有时间戳低于该时间的 TSO 消息的最高时间。为了实现这一点,每个调节联邦成员会向其他联邦成员传播其“时间状态”,即当前时间、前瞻时间、当前时间推进请求(如果有未决请求)以及其 TSO 队列中的最低时间戳(如果它也是调节联邦成员)。

任何其他接收到此状态的联邦成员可以推断出发送方可能发出的最低时间戳:
- 如果没有未决请求,它是当前时间加上前瞻时间。
- 如果有时间推进请求未决,根据请求类型,它是请求时间加上前瞻时间,或者是 TSO 队列中的最低时间戳加上前瞻时间。

对于给定的受约束联邦成员,LBTS 是所有其他调节联邦成员中最低时间戳的最小值。

时间推进方案如下:

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;

    A([时间推进请求]):::startend --> B(验证正确性):::process
    B --> C(记住请求时间):::process
    C --> D([返回]):::startend
    E([时间状态改变]):::startend --> F{LBTS 是否增长}:::decision
    F -->|是| G{LBTS 是否大于请求时间}:::decision
    G -->|是| H(提取并交付 TSO 队列中时间戳小于请求时间的所有消息):::process
    H --> I(反射属性值或接收交互回调):::process
    I --> J([时间推进授权]):::startend
    F -->|否| D
    G -->|否| D

目前,时间状态更改通知在发送方排队,这意味着需要使用集中资源(位于 FedEx 上的计数信号量)来确保及时获得正确的 LBTS。

1.5 yaRTI 的优势与不足

yaRTI 最初旨在进行研究和概念评估,它已在现有的实时联邦中证明了其效率。将 yaRTI 集成到该联邦中仅用了几个小时,并对 yaRTI 算法进行了重大改进。

yaRTI 的开发成本非常低,约 18,000 行代码(包括注释),实现了约 90% 的功能,包括:
- 完整的联邦管理
- 完整的声明管理
- 完整的对象管理
- 完整的时间管理
- 数据分发管理的重要部分

此外,它还具有一些本文未提及的功能,如管理对象模型(MOM)。与任何 C++ RTI 相比,yaRTI 更易于与现有的 Ada 模拟集成(军事和空中交通管理中的许多模拟都是用 Ada 编写的)。

然而,仍有一些工作需要完成:
- 所有权管理有待实现。
- 时间管理应完全分布式,不再使用中央信号量。
- 需要消除由于 GLADE 1.03p 限制而采取的一些变通方法,以实现更直接的消息管理并提高性能。
- 有序的联邦成员崩溃恢复是理想的。

二、Ada 95 实现的具有代码移动性的网络协调语言

2.1 背景与目标

定义适合编写全局计算(在全球计算机上运行的资源上进行的计算)的语言是分布式编程研究的目标之一。在这些语言中,需要考虑三个基本方面:
1. 网络流量最小化
2. 网络异构性
3. 网络安全(本文不考虑)

最近,对能够指定某种形式代码移动性的范式的兴趣有所增长,因为它们至少在某些情况下能够限制网络流量。例如,处理大量数据(分布在不同物理站点)的分布式应用程序,如果使用允许代理在包含数据的站点上移动的范式,效率会更高。

2.2 分布模型分类

分布模型分为两类:传统分布式系统和移动代码系统。在传统分布式系统中,真正的分布式系统层(TDS)向应用层隐藏网络的物理结构(其站点和连接)。移动代码系统中,TDS 层被计算环境(CE)层取代,CE 层是应用程序对站点的抽象。

2.3 Klada 语言介绍

Klada 是 Klaim 的一种实现。Klaim 是一种基于 Linda 和 Llinda 的内核协调语言,支持代理交互和移动性。Klaim 进程通过“黑板”通信模型进行交互,数据通过访问分布式在网络站点上的元组空间(TS)进行交换。进程可以作为元组的字段使用,语言通信原语通过显式的位置概念选择要使用的 TS。位置和进程一样是一等对象,可以在通信中交换。Klaim 进程可以通过非确定性选择运算符和并行运算符进行组合。

编译器将 Klada 程序转换为 Ada 95 程序,生成相应的 Ada 95 分布式程序的分区和配置文件。配置文件传递给 Glade 工具,可实现 Ada 95 程序在异构网络上的执行。

Klada 是一种弱移动性语言,通过引入 Klada 解释器 kvm 实现移动性。每个实现 Klada 站点 CE 的 Ada 95 分区都与 kvm 链接。

2.4 Klada 进程操作

Klaim 进程的操作如下:
- in(t)@ℓ :计算元组 t,并在位置 ℓ 表示的 TS 中搜索匹配的元组 t′。找到匹配元组后,将其从 TS 中移除,并将其值分配给 t 中相应的变量字段,然后操作终止。如果未找到匹配元组,操作将暂停,直到有可用的匹配元组。
- read(t)@ℓ :与 in 类似,但在将值分配给 t 的变量后,元组 t′ 不会从 TS 中移除。
- out(t)@ℓ :计算元组 t,并将其添加到位置 ℓ 的 TS 中。 out 原语不需要同步,是一个异步操作。
- eval(P)@ℓ :在名为 ℓ 的站点上执行代理 P,对应于远程代码评估。与 out 一样, eval 是异步的。
- newloc(u) :创建一个“新”站点,可以通过位置变量 u 访问。 newloc 也是一个非阻塞指令。

2.5 Klada 语法

Klada 进程可以从以下语法中派生:
| 语法类别 | 语法规则 |
| ---- | ---- |
| 任务(Task) | Task ::= Ext Ch Ext Ch \| Int Ch |
| 外部选择(Ext Ch) | Ext Ch ::= in(Tuple)@L exp.Seq [Ext Ch] \| read(Tuple)@L exp.Seq [Ext Ch] |
| 内部选择(Int Ch) | Int Ch ::= Seq \| Seq # Int Ch |
| 序列(Seq) | Seq ::= Com \| Com; Seq \| call id [(Tuple)] \| id′ \| nil |
| 命令(Com) | Com ::= eval(Task)@L exp \| out(Tuple)@L exp \| in(Tuple)@L exp \| read(Tuple)@L exp \| newloc(L exp) \| if Exp then Task else Task fi \| while Exp do Task od \| id := Exp \| (Task) |

2.6 Klada 语义示例

为了说明 Klada 的语义,给出一个电子商务应用程序的示例。我们要编写一个代理,访问距离 d 以内的“最近”相机店,寻找价格最低的相机。相机店由以下进程建模:

shop ≡ begin
    out(“camera1”, price1)@self; ... ; out(“camerak”, pricek)@self;
end

MarketPlaceClient 向本地服务器 MarketPlace 请求距离 d 以内的相机店列表。收到列表后,如果有店铺可访问,它会远程评估 ShopAgent ,并传递相机类型、店铺列表、结果返回位置和当前获得的价格。

MarketPlace 维护店铺列表及其距离,执行无限循环等待请求。收到请求后,它会创建一个新站点来分配店铺列表,构造列表,将列表的位置返回给客户端,并在屏幕上打印消息。

ShopAgent 在新店铺站点开始执行时,读取相机价格,如果新价格低于旧价格,它会从结果返回位置的 TS 中移除旧价格,并替换为新价格。然后,它读取剩余要访问的店铺数量。

通过这个示例,可以更清楚地理解 Klada 语言的语义和使用方式。

2.7 示例代码分析

下面详细分析上述示例代码的执行流程:

MarketPlaceClient 代码分析
1.  rec MarketPlaceClient (Cam: str; RLoc: loc; d: int) declare
2.      var ShopList, FirstShop: loc;
3.      var NumShop: int
4.      begin
5.          out(“Shop list”, d)@self;
6.          in(!ShopList)@self;
7.          in(!NumShop)@ShopList;
8.          if NumShop = 0
9.              then out(Cam, “NO SHOP”, -1)@RLoc
10.             else
11.                 in(!FirstShop)@ShopList;
12.                 out(NumShop - 1)@ShopList;
13.                 eval(call ShopAgent (Cam, ShopList, RLoc, 0))@FirstShop
14.             fi
15.  end
  • 第 1 - 3 行 :声明 MarketPlaceClient 递归过程,并定义了局部变量 ShopList FirstShop 用于存储店铺列表和第一个店铺的位置, NumShop 用于存储店铺数量。
  • 第 5 行 :向本地服务器发送请求,要求获取距离为 d 的店铺列表。
  • 第 6 行 :从本地接收店铺列表的位置。
  • 第 7 行 :从店铺列表位置接收店铺数量。
  • 第 8 - 14 行 :根据店铺数量进行判断,如果没有店铺,则向结果返回位置发送“NO SHOP”信息;否则,获取第一个店铺的位置,更新店铺列表中的店铺数量,并远程评估 ShopAgent 去访问第一个店铺。
MarketPlace 代码分析
# 假设 MarketPlace 代码如下
rec MarketPlace () declare
    var ShopListLoc: loc;
    var ShopList: tuple;
    begin
        while true do
            in(“Shop list”, d)@self;
            ShopListLoc := newloc();
            ShopList := construct_shop_list(d);
            out(ShopListLoc)@self;
            out(length(ShopList))@ShopListLoc;
            for each shop in ShopList do
                out(shop)@ShopListLoc;
            end for;
            out(“List sent”)@screen;
        end while;
    end
  • 第 1 - 2 行 :声明 MarketPlace 递归过程,并定义了局部变量 ShopListLoc 用于存储店铺列表的新位置, ShopList 用于存储店铺列表。
  • 第 3 - 12 行 :进入无限循环,等待 MarketPlaceClient 的请求。收到请求后,创建一个新的站点用于存储店铺列表,构造店铺列表,将店铺列表的位置返回给客户端,将店铺数量和每个店铺的位置存储在新站点中,并在屏幕上打印消息表示列表已发送。
ShopAgent 代码分析
rec ShopAgent (Cam: str; ShopList: loc; RLoc: loc; OldPrice: int) declare
    var Price: int;
    begin
        in(Cam, Price)@self;
        if Price < OldPrice or OldPrice = -1
            then
                in(Cam, _, _)@RLoc;
                out(Cam, Price)@RLoc;
            fi;
        in(NumShop)@ShopList;
        if NumShop > 0
            then
                in(NextShop)@ShopList;
                out(NumShop - 1)@ShopList;
                eval(call ShopAgent (Cam, ShopList, RLoc, Price))@NextShop;
            fi;
    end
  • 第 1 - 2 行 :声明 ShopAgent 递归过程,并定义了局部变量 Price 用于存储当前店铺相机的价格。
  • 第 3 行 :从当前店铺读取相机的价格。
  • 第 4 - 7 行 :如果新价格低于旧价格或旧价格为 -1,则从结果返回位置移除旧价格,并存储新价格。
  • 第 8 - 14 行 :读取剩余店铺数量,如果还有店铺,则获取下一个店铺的位置,更新店铺列表中的店铺数量,并远程评估 ShopAgent 去访问下一个店铺。

2.8 总结

通过上述对 Ada 95 在分布式系统中的应用介绍,我们可以看到 Ada 95 在 HLA 运行时基础设施和网络协调语言实现方面具有重要作用。

在 HLA 运行时基础设施中,yaRTI 以较低的开发成本实现了多种重要功能,并且在实时联邦中展现出了高效性。然而,它仍有一些功能需要完善,如所有权管理和时间管理的分布式优化等。

在网络协调语言方面,Klada 作为 Klaim 的实现,通过代码移动性范式有效地减少了网络流量。其语法和语义设计使得开发者可以方便地编写分布式应用程序,如电子商务示例所示。

总的来说,Ada 95 为分布式系统的开发提供了强大的支持,无论是在联邦管理、对象管理还是代码移动性方面,都有其独特的优势。未来,随着技术的不断发展,我们可以期待 Ada 95 在分布式系统领域发挥更大的作用,同时也需要不断改进和完善相关的技术和工具,以满足日益增长的需求。

以下是整个流程的总结表格:
| 技术领域 | 主要内容 | 优势 | 待改进点 |
| ---- | ---- | ---- | ---- |
| HLA 运行时基础设施 | 联邦成员加入、分布式声明管理、对象管理、时间管理等 | 开发成本低,功能实现度高,易与 Ada 模拟集成 | 所有权管理未实现,时间管理需分布式优化 |
| 网络协调语言(Klada) | 基于 Klaim,支持代码移动性,通过元组空间通信 | 减少网络流量,语法灵活 | 可进一步优化性能和功能 |

graph LR
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;

    A([开始]):::startend --> B(MarketPlaceClient 请求店铺列表):::process
    B --> C(MarketPlace 构造并返回店铺列表):::process
    C --> D(MarketPlaceClient 接收列表并评估 ShopAgent):::process
    D --> E(ShopAgent 访问店铺并比较价格):::process
    E --> F{是否还有店铺}:::decision
    F -->|是| D
    F -->|否| G([结束]):::startend

这个流程图展示了整个电子商务应用程序的执行流程,从 MarketPlaceClient 发起请求,到 MarketPlace 响应并提供店铺列表,再到 ShopAgent 逐个访问店铺并比较价格,直到所有店铺都被访问完。通过这个流程,我们可以更直观地理解 Klada 语言在实际应用中的使用方式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值