使用 Jolie 存储工作流状态
Storing workflow state with Jolie
我想了解 Jolie 如何实现工作流程的弹性。
- Jolie 是否存储 运行 工作流程的状态?
- 它是通过数据库还是文件系统实现的?
您可以将 Jolie 语言的三个组件混合到 save/load 工作流状态和程序故障恢复代码中:
- 朱莉变量,是树;
- 一些标准库支持 Jolie 树的编组和解组以及 file/database 交互;
- 用于处理异常行为的语言fault handling mechanisms。
Jolie 微服务实例的状态是一棵树(类似于 XML 和 JSON 结构)。实际上,虽然在 Jolie a = 5
中回忆起在其他语言中发现的熟悉的变量赋值,但实际发生的是,在实例执行赋值的状态下,我们创建了一个节点 a
并赋值给 a
值 5
。反之亦然,当我们在 Jolie 程序中编写 a
时,我们正在访问存储在节点 a
下的值。同理,a.b = 6
表示在a
下创建子节点b
,并赋值6
.
在发送和接收结构化数据时,使用语言中的原生树数据结构非常有用,因为 Jolie 通过其自动将其树形变量转换为用于与某些外部 client/server 通信的格式端口。然而,树形变量也相当容易marshal/unmarshal。例如,我们可以通过调用 JSON (or XML) library and either use the File or Database 持久化库来转换 Jolie 树变量的当前状态。
我在下面组装了一个简单的例子来说明我的观点。在示例中,我使用过程 saveState
和 loadState
来保存和加载存储在变量 process_state
下的值,该变量是包含工作流中使用的所有相关值的根变量。工作流从 main
块开始,我们在其中保存一些数据并打印出来以供参考(操作 valueToPrettyString
和 println
)。然后,我们保存当前状态 (saveState
) 并继续 stage1
。由于变量 process_state.c
等于 "bad"
我们抛出一个错误 (MyFault
)。 install
块捕获错误并执行过程 recv_stage1
。该过程丢弃程序先前的错误状态,恢复保存在文件中的状态和 "repairs" 变量 process_state.c
。完成后,我们再次执行 stage1
。
include "console.iol"
include "json_utils.iol"
include "string_utils.iol"
include "file.iol"
define saveState
{
getJsonString@JsonUtils( process_state )( marshalled_state.content );
writeFile@File( marshalled_state )();
undef( marshalled_state.content )
}
define loadState {
undef( process_state );
readFile@File( marshalled_state )( marshalled_state.content );
getJsonValue@JsonUtils( marshalled_state.content )( process_state );
undef( marshalled_state.content )
}
define recv_stage1 {
scope( recv_stage1 ){
loadState;
process_state.c = "fine";
valueToPrettyString@StringUtils( process_state )( state_pretty_print );
println@Console( state_pretty_print )()
}
}
define stage1 {
scope( stage1 ){
install( MyFault =>
println@Console( "MyFault, loading saved state" )(); recv_stage1; stage1 );
if ( process_state.c == "bad" ){
throw( MyFault )
} else {
println@Console( "Everything went " + process_state.c )()
}
}
}
main
{
marshalled_state.filename = "instance_XXX.json";
with ( process_state ){
.a = 42;
.b << "I" { .love = "very", .much = "jolie" };
valueToPrettyString@StringUtils( process_state )( state_pretty_print );
println@Console( state_pretty_print )();
saveState;
.c = "bad";
stage1
}
}
这种分级也可用于从崩溃中恢复(例如,通过指示一个变量是到达的最后一个阶段)。
Jolie 还提供了一些高级结构来处理 termination and compensation 工作流,有助于避免保存损坏的阶段并强制执行交易行为。
参考资料
- Fabrizio Montesi、Claudio Guidi 和 Gianluigi Zavattaro。 (2014)。与 Jolie 一起进行面向服务的编程。在 A. Bouguettaaya、Q. Z. Sheng 和 F. Daniel(编辑),Web 服务基础(第 81-107 页)中。施普林格 https://doi.org/10.1007/978-1-4614-7518-7_4
- Fabrizio Montesi、Claudio Guidi、Ivan Lanese 和 Gianluigi Zavattaro。 (2008)。面向服务的应用程序的动态故障处理机制。 https://doi.org/10.1109/ECOWS.2008.20
我想了解 Jolie 如何实现工作流程的弹性。
- Jolie 是否存储 运行 工作流程的状态?
- 它是通过数据库还是文件系统实现的?
您可以将 Jolie 语言的三个组件混合到 save/load 工作流状态和程序故障恢复代码中:
- 朱莉变量,是树;
- 一些标准库支持 Jolie 树的编组和解组以及 file/database 交互;
- 用于处理异常行为的语言fault handling mechanisms。
Jolie 微服务实例的状态是一棵树(类似于 XML 和 JSON 结构)。实际上,虽然在 Jolie a = 5
中回忆起在其他语言中发现的熟悉的变量赋值,但实际发生的是,在实例执行赋值的状态下,我们创建了一个节点 a
并赋值给 a
值 5
。反之亦然,当我们在 Jolie 程序中编写 a
时,我们正在访问存储在节点 a
下的值。同理,a.b = 6
表示在a
下创建子节点b
,并赋值6
.
在发送和接收结构化数据时,使用语言中的原生树数据结构非常有用,因为 Jolie 通过其自动将其树形变量转换为用于与某些外部 client/server 通信的格式端口。然而,树形变量也相当容易marshal/unmarshal。例如,我们可以通过调用 JSON (or XML) library and either use the File or Database 持久化库来转换 Jolie 树变量的当前状态。
我在下面组装了一个简单的例子来说明我的观点。在示例中,我使用过程 saveState
和 loadState
来保存和加载存储在变量 process_state
下的值,该变量是包含工作流中使用的所有相关值的根变量。工作流从 main
块开始,我们在其中保存一些数据并打印出来以供参考(操作 valueToPrettyString
和 println
)。然后,我们保存当前状态 (saveState
) 并继续 stage1
。由于变量 process_state.c
等于 "bad"
我们抛出一个错误 (MyFault
)。 install
块捕获错误并执行过程 recv_stage1
。该过程丢弃程序先前的错误状态,恢复保存在文件中的状态和 "repairs" 变量 process_state.c
。完成后,我们再次执行 stage1
。
include "console.iol"
include "json_utils.iol"
include "string_utils.iol"
include "file.iol"
define saveState
{
getJsonString@JsonUtils( process_state )( marshalled_state.content );
writeFile@File( marshalled_state )();
undef( marshalled_state.content )
}
define loadState {
undef( process_state );
readFile@File( marshalled_state )( marshalled_state.content );
getJsonValue@JsonUtils( marshalled_state.content )( process_state );
undef( marshalled_state.content )
}
define recv_stage1 {
scope( recv_stage1 ){
loadState;
process_state.c = "fine";
valueToPrettyString@StringUtils( process_state )( state_pretty_print );
println@Console( state_pretty_print )()
}
}
define stage1 {
scope( stage1 ){
install( MyFault =>
println@Console( "MyFault, loading saved state" )(); recv_stage1; stage1 );
if ( process_state.c == "bad" ){
throw( MyFault )
} else {
println@Console( "Everything went " + process_state.c )()
}
}
}
main
{
marshalled_state.filename = "instance_XXX.json";
with ( process_state ){
.a = 42;
.b << "I" { .love = "very", .much = "jolie" };
valueToPrettyString@StringUtils( process_state )( state_pretty_print );
println@Console( state_pretty_print )();
saveState;
.c = "bad";
stage1
}
}
这种分级也可用于从崩溃中恢复(例如,通过指示一个变量是到达的最后一个阶段)。
Jolie 还提供了一些高级结构来处理 termination and compensation 工作流,有助于避免保存损坏的阶段并强制执行交易行为。
参考资料
- Fabrizio Montesi、Claudio Guidi 和 Gianluigi Zavattaro。 (2014)。与 Jolie 一起进行面向服务的编程。在 A. Bouguettaaya、Q. Z. Sheng 和 F. Daniel(编辑),Web 服务基础(第 81-107 页)中。施普林格 https://doi.org/10.1007/978-1-4614-7518-7_4
- Fabrizio Montesi、Claudio Guidi、Ivan Lanese 和 Gianluigi Zavattaro。 (2008)。面向服务的应用程序的动态故障处理机制。 https://doi.org/10.1109/ECOWS.2008.20