我想要刷新资源,但我也想终止刷新。
我有以下界面:
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
?
答案 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)
}
}
}
这种模式经常出现,因此将来我们可能会使其变得更加容易。
参考文献: