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档案。

为了避免重复升级指令,允许使用正则表达式来指定UpFromVsnDownToVsn.要被视为正则表达式,版本标识符必须指定为二进制。例如,以下内容匹配所有版本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_servergen_fsmgen_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

的描述PrePurgePostPurge,见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使用低级别的指令removepurge

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_applicationadd_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,4relup生成文件。中的其余指令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)