为什么在 Jolie 中不直接调用已安装的异常处理程序?
Why is the installed exception handler not called directly in Jolie?
我有一个想要刷新资源的场景,但我也希望能够终止刷新。
我有以下接口:
interface terminate{
OneWay: terminate(void)
}
interface refreshAll {
RequestResponse: refreshAll(void)(void)
}
以及资源:
include "interface.iol"
include "console.iol"
inputPort dummyInput {
Location: "socket://localhost:8002"
Protocol: sodep
Interfaces: refreshAll
}
init{
registerForInput@Console()()
}
main
{
refreshAll( number )( result ) {
println@Console("refresh")();
in(req);
result = void
}
}
如果我想终止服务 运行:
include "interface.iol"
outputPort term {
Location: "socket://localhost:8000"
Protocol: sodep
Interfaces: terminate
}
main
{
terminate@term()
}
程序协调一切:
include "interface.iol"
include "console.iol"
inputPort terminate {
Location: "socket://localhost:8000"
Protocol: sodep
Interfaces: terminate
}
outputPort resource {
Location: "socket://localhost:8002"
Protocol: sodep
Interfaces: refreshAll
}
main
{
scope(hej){
install(
hello => {
println@Console("terminate")()
}
);
{
refreshAll@resource()()
}|
{
terminate();
throw(hello)
}
}
}
为什么在接收到terminate
时没有直接抛出异常?
也就是说,在协调程序中,接收到terminate
时不会调用异常处理程序。 refreshAll@resource()()
完成后首先调用异常处理程序。
我怎样才能让 refreshAll
终止获得 terminate
?
在 Jolie 中,错误(您使用 throw 原语触发的错误)不会中断挂起的请求-响应调用(您的 refreshAll@resource()()
):如果尚未开始,则表示尚未开始完全没有,但是如果请求已发送到预期的接收者(此处为 resource
),那么 Jolie 将在将错误传播到封闭范围之前等待响应(或超时)(hej
这里)。那是因为请求响应的结果对于故障管理逻辑可能很重要。
如果您不关心故障处理程序中请求响应的结果(这里您不关心),那么您可以制作一个小适配器来分两步处理请求响应调用,有效地使其在应用程序级别异步(在实现级别,大多数 Jolie 东西无论如何都是异步的,但在这里你想明确地看到通信在你的程序逻辑中分两步发生)。
我修改了你的协调器程序如下,然后一切如你所愿:
include "interface.iol"
include "console.iol"
inputPort terminate {
Location: "socket://localhost:8000"
Protocol: sodep
Interfaces: terminate
}
outputPort resource {
Location: "socket://localhost:8002"
Protocol: sodep
Interfaces: refreshAll
}
// New stuff from here
interface RefreshAsyncAdapterIface {
OneWay:
refreshAllAsync(void)
}
interface RefreshAsyncClientIface {
OneWay:
refreshCompleted(void)
}
inputPort CoordinatorInput {
Location: "local://Coordinator"
Interfaces: RefreshAsyncClientIface
}
outputPort Coordinator {
Location: "local://Coordinator"
Interfaces: RefreshAsyncClientIface
}
// Adapter service to split the solicit-response in two steps
service RefreshAsyncAdapter {
Interfaces: RefreshAsyncAdapterIface
main {
refreshAllAsync();
refreshAll@resource()();
refreshCompleted@Coordinator()
}
}
main
{
scope(hej){
install(
hello => {
println@Console("terminate")()
}
);
{
// Split the call in send and receive steps
refreshAllAsync@RefreshAsyncAdapter();
refreshCompleted()
}|
{
terminate();
throw(hello)
}
}
}
这种模式经常出现,因此我们将来可能会使其变得更加简单。
参考文献:
- Jolie 关于故障处理的文档:https://jolielang.gitbook.io/docs/fault-handling/termination_and_compensation
- 描述我报告内容的论文:https://doi.org/10.1109/ECOWS.2008.20
- Jolie 中错误的形式语义:https://doi.org/10.3233/FI-2009-143
我有一个想要刷新资源的场景,但我也希望能够终止刷新。
我有以下接口:
interface terminate{
OneWay: terminate(void)
}
interface refreshAll {
RequestResponse: refreshAll(void)(void)
}
以及资源:
include "interface.iol"
include "console.iol"
inputPort dummyInput {
Location: "socket://localhost:8002"
Protocol: sodep
Interfaces: refreshAll
}
init{
registerForInput@Console()()
}
main
{
refreshAll( number )( result ) {
println@Console("refresh")();
in(req);
result = void
}
}
如果我想终止服务 运行:
include "interface.iol"
outputPort term {
Location: "socket://localhost:8000"
Protocol: sodep
Interfaces: terminate
}
main
{
terminate@term()
}
程序协调一切:
include "interface.iol"
include "console.iol"
inputPort terminate {
Location: "socket://localhost:8000"
Protocol: sodep
Interfaces: terminate
}
outputPort resource {
Location: "socket://localhost:8002"
Protocol: sodep
Interfaces: refreshAll
}
main
{
scope(hej){
install(
hello => {
println@Console("terminate")()
}
);
{
refreshAll@resource()()
}|
{
terminate();
throw(hello)
}
}
}
为什么在接收到terminate
时没有直接抛出异常?
也就是说,在协调程序中,接收到terminate
时不会调用异常处理程序。 refreshAll@resource()()
完成后首先调用异常处理程序。
我怎样才能让 refreshAll
终止获得 terminate
?
在 Jolie 中,错误(您使用 throw 原语触发的错误)不会中断挂起的请求-响应调用(您的 refreshAll@resource()()
):如果尚未开始,则表示尚未开始完全没有,但是如果请求已发送到预期的接收者(此处为 resource
),那么 Jolie 将在将错误传播到封闭范围之前等待响应(或超时)(hej
这里)。那是因为请求响应的结果对于故障管理逻辑可能很重要。
如果您不关心故障处理程序中请求响应的结果(这里您不关心),那么您可以制作一个小适配器来分两步处理请求响应调用,有效地使其在应用程序级别异步(在实现级别,大多数 Jolie 东西无论如何都是异步的,但在这里你想明确地看到通信在你的程序逻辑中分两步发生)。
我修改了你的协调器程序如下,然后一切如你所愿:
include "interface.iol"
include "console.iol"
inputPort terminate {
Location: "socket://localhost:8000"
Protocol: sodep
Interfaces: terminate
}
outputPort resource {
Location: "socket://localhost:8002"
Protocol: sodep
Interfaces: refreshAll
}
// New stuff from here
interface RefreshAsyncAdapterIface {
OneWay:
refreshAllAsync(void)
}
interface RefreshAsyncClientIface {
OneWay:
refreshCompleted(void)
}
inputPort CoordinatorInput {
Location: "local://Coordinator"
Interfaces: RefreshAsyncClientIface
}
outputPort Coordinator {
Location: "local://Coordinator"
Interfaces: RefreshAsyncClientIface
}
// Adapter service to split the solicit-response in two steps
service RefreshAsyncAdapter {
Interfaces: RefreshAsyncAdapterIface
main {
refreshAllAsync();
refreshAll@resource()();
refreshCompleted@Coordinator()
}
}
main
{
scope(hej){
install(
hello => {
println@Console("terminate")()
}
);
{
// Split the call in send and receive steps
refreshAllAsync@RefreshAsyncAdapter();
refreshCompleted()
}|
{
terminate();
throw(hello)
}
}
}
这种模式经常出现,因此我们将来可能会使其变得更加简单。
参考文献:
- Jolie 关于故障处理的文档:https://jolielang.gitbook.io/docs/fault-handling/termination_and_compensation
- 描述我报告内容的论文:https://doi.org/10.1109/ECOWS.2008.20
- Jolie 中错误的形式语义:https://doi.org/10.3233/FI-2009-143