为什么在 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)
            }

    }
}

这种模式经常出现,因此我们将来可能会使其变得更加简单。

参考文献: