为什么直接在Jolie中调用已安装的异常处理程序?

时间:2018-02-15 08:20:34

标签: 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

1 个答案:

答案 0 :(得分:2)

在朱莉中,错误(使用throw原语触发的错误)不会中断待处理的请求响应调用(您的refreshAll@resource()()):如果尚未启动,则根本不会启动,但是如果请求已发送到预期的接收者(此处为resource),则朱莉将等待响应(或超时),然后再将错误传播到封闭范围(此处为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)
            }

    }
}

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

参考文献: