appup
应用程序
档案
应用程序
文件摘要
应用程序升级文件
描述
大应用程序升级文件
定义应用程序如何在运行的系统中升级或降级。
systools
生成发行版升级文件时,该文件由功能使用relup
。
文件语法
应用程序升级文件将被调用Application.appup
,在哪里Application
是应用程序的名称。文件位于ebin
应用程序的目录。
大.appup
文件包含一个Erlang术语,它定义了用于升级或降级应用程序的指令。该文件具有以下语法:
{Vsn,
[{UpFromVsn, Instructions}, ...],
[{DownToVsn, Instructions}, ...]}.
Vsn = string()
当前应用程序版本。
UpFromVsn = string() | binary()
要升级的早期应用程序版本。如果它是一个字符串,它将被解释为一个特定的版本号。如果它是二进制,则解释为可以匹配多个版本号的正则表达式。
DownToVsn = string() | binary()
要降级的早期应用程序版本。如果它是一个字符串,它将被解释为一个特定的版本号。如果它是二进制,则解释为可以匹配多个版本号的正则表达式。
Instructions
一份清单发布升级指令
,见Release Upgrade Instructions
建议只使用高级指令。这些自动转换为低级指令。systools
创建relup
档案。
为了避免重复升级指令,允许使用正则表达式来指定UpFromVsn
和DownToVsn
.要被视为正则表达式,版本标识符必须指定为二进制。例如,以下内容匹配所有版本2.1.x
,在哪里x
是任何数字:
<<"2\\.1\\.[0-9]+">>
请注意,正则表达式必须与完整版本字符串匹配,所以此示例适用于,例如2.1.1
,但不适用于2.1.1.1
。
发布升级指令
升级或降级时,发布升级指令由发布处理程序解释。有关释放处理的详细信息,请参阅OTP Design Principles
在系统文档
。
据说一个过程使用
模块Mod
如果Mod
列在Modules
用于启动进程的子规范的一部分,请参见supervisor(3)
.如属gen_event
,事件管理器进程被称为使用
Mod
如果Mod
已安装的事件处理程序。
高级指令
{update, Mod}
{update, Mod, supervisor}
{update, Mod, Change}
{update, Mod, DepMods}
{update, Mod, Change, DepMods}
{update, Mod, Change, PrePurge, PostPurge, DepMods}
{update, Mod, Timeout, Change, PrePurge, PostPurge, DepMods}
{update, Mod, ModType, Timeout, Change, PrePurge, PostPurge, DepMods}
Mod = atom()
ModType = static | dynamic
Timeout = int()>0 | default | infinity
Change = soft | {advanced,Extra}
Extra = term()
PrePurge = PostPurge = soft_purge | brutal_purge
DepMods = [Mod]
使用模块对进程进行同步代码替换Mod
。
所有这些进程都暂停使用sys:suspend
,新模块版本被加载,然后使用恢复进程sys:resume
。
Change
默认为soft
并定义代码更改的类型。如果它被设置为{advanced,Extra}
使用,实现的过程gen_server
,gen_fsm
,gen_statem
,或者gen_event
通过调用回调函数变换其内部状态code_change
。特殊进程调用回调函数system_code_change/4
。在这两种情况下,该术语Extra
都作为参数传递给回调函数。
PrePurge
默认为brutal_purge
。它控制在加载新模块版本之前执行旧代码时采取的操作。如果值是brutal_purge
,则进程被终止。如果该值是soft_purge
,则release_handler:install_release/1
返回{error,{old_processes,Mod}}
。
PostPurge
默认为brutal_purge
它控制在加载新模块版本时对正在执行旧代码的进程采取什么操作。如果值是brutal_purge
,当发布永久化,进程被终止时,代码就会被清除。如果值是soft_purge
,当没有剩余进程执行代码时,发布处理程序将清除旧代码。
DepMods
默认为[]
并定义了其他模块Mod
依赖于。在relup
文件,使用Mod
中使用模块挂起进程的说明之前。DepMods
当升级时,反之则是降级时。在循环依赖的情况下,appup
档案是保存的。
Timeout
定义挂起进程时的超时。如果没有价值或default
的默认值。sys:suspend
被使用了。
ModType
默认为dynamic
它指定代码是否是“动态的”,也就是说,如果使用模块的进程自发地切换到新代码,或者是“静态的”。在进行高级更新和升级时,动态模块的新版本将在进程被要求更改代码之前加载。降级时,会要求流程在加载新版本之前更改代码。对于静态模块,在进程被要求更改代码之前加载新版本,无论是升级还是降级。回调模块是动态的。
update
有论点supervisor
在更改主管的启动规范时使用。
{load_module, Mod}
{load_module, Mod, DepMods}
{load_module, Mod, PrePurge, PostPurge, DepMods}
Mod = atom()
PrePurge = PostPurge = soft_purge | brutal_purge
DepMods = [Mod]
简单的代码替换模块Mod
。
的描述PrePurge
和PostPurge
,见update
上面。
DepMods
默认为[]
并定义了其他哪些模块Mod
依赖于。在relup
文件中,加载这些模块的指令在加载指令之前。Mod
当升级时,反之则是降级时。
{add_module, Mod}
{add_module, Mod, DepMods}
Mod = atom()
DepMods = [Mod]
加载一个新模块Mod
。
DepMods
默认为[]
并定义了其他哪些模块Mod
依赖于。在relup
文件,与这些模块相关的指令在加载指令之前。Mod
当升级时,反之则是降级时。
{delete_module, Mod}
{delete_module, Mod, DepMods}
Mod = atom()
删除模块Mod
使用低级别的指令remove
和purge
。
DepMods
默认为[]
并定义了其他哪些模块Mod
依赖于。在relup
文件,与这些模块相关的指令在删除指令之前。Mod
当升级时,反之则是降级时。
{add_application, Application}
{add_application, Application, Type}
Application = atom()
Type = permanent | transient | temporary | load | none
添加应用程序意味着文件中的modules
键定义的模块.app
使用加载add_module
。
Type
默认为permanent
并指定应用程序的开始类型。如果Type = permanent | transient | temporary
,则应用程序将以相应的方式加载和启动,请参见application(3)
.如果Type = load
,应用程序只加载。如果Type = none
,应用程序没有加载,也没有启动,尽管加载了其模块的代码。
{remove_application, Application}
Application = atom()
删除应用程序意味着停止应用程序,然后使用delete_module
,然后从应用程序控制器卸载应用程序规范。
{restart_application, Application}
Application = atom()
重新启动应用程序意味着应用程序被停止,然后再次启动,类似于使用指令。remove_application
和add_application
按顺序。
低级指令
{load_object_code, {App, Vsn, [Mod]}}
App = Mod = atom()
Vsn = string()
读每一个Mod
从目录App-Vsn/ebin
作为二进制。它不加载模块。该指令将首先放在脚本中,从文件中读取所有新代码,以减少挂起加载恢复周期的时间。
point_of_no_return
如果在此指令之后发生崩溃,系统将无法恢复,并将从旧版本重新启动。指令只能在脚本中发生一次。它终究是要放置的。load_object_code
指示。
{load, {Mod, PrePurge, PostPurge}}
Mod = atom()
PrePurge = PostPurge = soft_purge | brutal_purge
在这条指令发生之前,Mod
一定是用load_object_code
此指令加载模块。PrePurge
被忽视了。的描述PostPurge
,见高级指令。update
早些时候。
{remove, {Mod, PrePurge, PostPurge}}
Mod = atom()
PrePurge = PostPurge = soft_purge | brutal_purge
使当前版本的Mod
老了。PrePurge
被忽视了。的描述PostPurge
,见高级指令。update
早些时候。
{purge, [Mod]}
Mod = atom()
清除每个模块Mod
也就是说,删除旧代码。注意,执行清除代码的任何进程都会被杀死。
{suspend, [Mod | {Mod, Timeout}]}
Mod = atom()
Timeout = int()>0 | default | infinity
尝试使用模块挂起所有进程。Mod
如果一个进程没有响应,它就会被忽略。这可能导致进程死亡,因为当它自动切换到新代码时,它会崩溃,或者是由于清除操作的结果。如果没有Timeout
指定或default
的默认值。sys:suspend
被使用了。
{resume, [Mod]}
Mod = atom()
使用模块恢复所有暂停的进程Mod
。
{code_change, [{Mod, Extra}]}
{code_change, Mode, [{Mod, Extra}]}
Mod = atom()
Mode = up | down
Extra = term()
Mode
默认为up
并指定它是升级还是降级。此指令发送code_change
使用一个模块向所有进程发送系统消息Mod
通过调用函数sys:change_code
,通过学期Extra
作为争论。
{stop, [Mod]}
Mod = atom()
使用模块停止所有进程。Mod
打电话supervisor:terminate_child/2
当更改代码的最简单方法是停止并重新启动运行代码的进程时,此指令非常有用。
{start, [Mod]}
Mod = atom()
Mod
通过调用模块启动所有停止的进程supervisor:restart_child/2
。
{sync_nodes, Id, [Node]}
{sync_nodes, Id, {M, F, A}}
Id = term()
Node = node()
M = F = atom()
A = [term()]
apply(M, F, A)
必须返回节点列表。
此指令将发布安装与其他节点同步。各Node
必须用相同的值计算此命令。Id
本地节点等待所有其他节点在继续执行之前对指令进行评估。如果一个节点发生故障,则它被认为是一个不可恢复的错误,并且本地节点将从旧版本重新启动。这条指令没有时间,这意味着它可以永远挂起。
{apply, {M, F, A}}
M = F = atom()
A = [term()]
评估apply(M, F, A)
。
如果指令出现在指令之前point_of_no_return
,则会发生故障。release_handler:install_release/1
然后返回{error,{'EXIT',Reason}}
,除非{error,Error}
被抛出或返回。然后它返回{error,Error}
。
如果指令出现在指令之后point_of_no_return
如果函数调用失败,系统将重新启动。
restart_new_emulator
此指令用于升级应用程序ERTS、内核、STDLIB或SASL。它关闭当前的模拟器并启动一个新的模拟器。所有进程都会优雅地终止,当模拟器重新启动时,将使用ERTS、Kernel、STDLIB和SASL的新版本。只有一个restart_new_emulator
中的指令是允许的。relup
文件,它必须放在第一个位置。systools:make_relup/3,4
当relup
生成文件。中的其余指令relup
文件在重新启动后作为引导脚本的一部分执行。
升级完成后会写入信息报告。要以编程方式确定升级是否完成,请调用release_handler:which_releases/0,1
并检查预期版本是否具有状态current
。
升级完成后,新版本仍必须永久化,否则,如果重新启动模拟器,将启动旧的模拟器。
警告
如前所述,指示restart_new_emulator导致使用ERTS>、Kernel、STDLIB和SASL的新版本重新启动模拟器。但是,所有其他应用程序在启动时都会在这个新模拟器中运行它们的旧版本。这通常是没有问题的,但核心应用程序不时会发生不兼容的更改,这可能会在此设置中造成麻烦。当函数被删除时,这种不兼容的更改%28通常在两个主要版本之前加上一个不推荐的内容。要确保应用程序不会因不兼容的更改而崩溃,请始终尽快删除对不推荐函数的任何调用。
restart_emulator
此指令类似于restart_new_emulator
,除非它必须放在relup
档案。它与仿真器或核心应用程序的升级无关,但在需要系统完全重新启动时,任何应用程序都可以使用它。
生成relup
档案,systools:make_relup/3,4
确保只有一个restart_emulator
指令中的最后一条指令。relup
档案。
另见
release_handler(3), relup(4), supervisor(3), systools(3)