关于Erlang/OTP的application参数配置 erlang app 文件_sdsabc2000的博客-程序员秘密

技术标签: erlang  


应用的概念¶ 

当我们写了实现特定功能的代码之后,我们可能想将代码转成一个 应用 (application),这是可以作为一个单元启动和停止的组建,同时它也可以在其他系统中被重用。 

我们要创建一个 应用回调模块 ,其中描述了该应用应该如何被启动和停止。 

然后,需要一个应用规格,它被放在一个 应用资源文件 。我们还指定该应用由哪些模块组成,以及各个回掉模块的名字。 

如果我们使用 systools ——Erlang/OTP用于打包的代码(参见 发布 ),每个应用的代码都可以按照预定的 目录结构 放在单独的目录中。 

应用回调模块¶ 
如何启动和停止应用的代码,即监督树,由以下两个回掉函数来描述: 

start(StartType, StartArgs) -> {ok, Pid} | {ok, Pid, State} 
stop(State) 
当要通过启动顶层督程来创建监督树的时候,会调用 start 。它要返回顶层督程的pid和一个选项值 State ,默认为 []。这个值会原样传递给 stop 。 

StartType 通常是原子 normal 。只有在接管或故障转移中才会有其他值,参见 分布式应用 。 StartArgs 由 应用资源文件 中的键 mod 来定义。 

在应用被停止之后会调用 stop/1 来进行必须的清除工作。注意应用实际的停止过程,也就是监督树的关闭,是按照 启动和停止应用 中所描述的方式自动处理的。 

以下是一个例子,将来自 督程 一章中的督程打包为一个应用回调模块: 

-module(ch_app). 
-behaviour(application). 

-export([start/2, stop/1]). 

start(_Type, _Args) -> 
    ch_sup:start_link(). 

stop(_State) -> 
    ok. 
一个库应用——不能被启动或者停止——则无须任何应用回调模块。 

应用资源文件¶ 
我们通过创建一个放在应用资源文件——简称 .app 文件——中的应用规格来定义一个应用: 

{application, Application, [Opt1,...,OptN]}. 
Application 是一个代表应用的名称的原子。文件必须被命名成 Application.app 。 

每一个 Opt 都是一个定义了应用某种特性的元组 {Key, Value} 。所有的键都是可选。忽略的键会使用默认的值。 

例如,用于库应用 libapp 的最小化的 .app 文件的内容为: 

{application, libapp, []}. 
对于像 ch_app 这样的监督树应用的最小化 .app 文件的内容为: 

{application, ch_app, 
[{mod, {ch_app,[]}}]}. 
键 mod 定义了回调模块以及应用的启动参数,在这个例子中相应是 ch_app 和 []。这表示应用启动的时候会调用: 

ch_app:start(normal, []) 
而当应用被停止的时候会调用: 

ch_app:stop([]) 
当使用 systools 时,Erlang/OTP工具的打包代码(参见 发布 ),键 description、vsn、modules、registered 和 applications 则应该指定为: 

{application, ch_app, 
[{description, "Channel allocator"}, 
  {vsn, "1"}, 
  {modules, [ch_app, ch_sup, ch3]}, 
  {registered, [ch3]}, 
  {applications, [kernel, stdlib, sasl]}, 
  {mod, {ch_app,[]}} 
]}. 
description 
简短描述,字符串。默认为 “”。 
vsn 
版本号,字符串。默认为”“。 
modules 
由该应用引入的所有模块。当生成启动脚本和tar文件时, systools 将用到这个列表。一个模块必须被定义于且仅于一个应用。默认为[]。 
registered 
应用中所有注册进程的名称。 systools 使用这个列表来探测在应用之间是否有名称冲突。默认为 []。 
applications 
所有在此应用之前必须启动的应用。 systools 使用该列表来生成正确的启动脚本。默认为 [],但是注意任何应用都要至少依赖于 kernel 和 stdlib 。 
应用资源文件的语法和内容在 app(4) 中有详细的描述。 

目录结构¶ 
当使用 systools 对代码进行打包的时候,每个应用的代码都放在单独的目录中 lib/Application-Vsn ,其中 Vsn 是版本号。 

即便没有用到 systools ,最好也要了解它,因为Erlang/OTP其自身是按照OTP原则进行打包的所以才有了这个目录结构。如果存在一个应用的多个版本,那么代码服务器(见 code(3) )会自动使用来自目录中版本号最高的代码。 

应用目录结构当然也可以用于开发环境。版本号是可以忽略的。 

应用目录有以下子目录: 

•src 
•ebin 
•priv 
•include 
src 
包含Erlang源代码 
ebin 
包含Erlang目标代码—— beam 文件。 .app 文件也放在这里。 
priv 
用于应用专属文件。例如,C执行程序就放在这里。应该使用函数 code:priv_dir/1 来访问这个目录。 
include 
用于包含文件。 
应用控制器¶ 
当启动了Erlang运行时系统,作为Kernel应用的一些进程会被启动。其中一个进程是应用控制器进程,注册为 application_controller 。 

所有对应用的操作都由应用控制器来协调。它通过模块 application 里的函数来暴露接口, 请参考 application(3) 。尤其要了解,应用可以被加载、卸载、启动和停止。 

加载和卸载应用¶ 
在能启动一个应用之前,首先它必须被加载。应用控制器会读取在 .app 中的信息并存起来。 

1> application:load(ch_app). 
ok 
2> application:loaded_applications(). 
[{kernel,"ERTS  CXC 138 10","2.8.1.3"}, 
{stdlib,"ERTS  CXC 138 10","1.11.4.3"}, 
{ch_app,"Channel allocator","1"}]被停止的或者从未启动过的应用,可以被卸载。该应用相关的信息会从应用控制器的内部数据库中删除。 

3> application:unload(ch_app). 
ok 
4> application:loaded_applications(). 
[{kernel,"ERTS  CXC 138 10","2.8.1.3"}, 
{stdlib,"ERTS  CXC 138 10","1.11.4.3"}]Note: 
加载/卸载应用并不会加载/卸载该应用所使用的代码。代码加载是按照一般的方式进行的。 

启动和停止应用¶ 
启动应用要调用: 

5> application:start(ch_app). 
ok 
6> application:which_applications(). 
[{kernel,"ERTS  CXC 138 10","2.8.1.3"}, 
{stdlib,"ERTS  CXC 138 10","1.11.4.3"}, 
{ch_app,"Channel allocator","1"}]如果应用尚未被加载,那么应用控制器会首先使用 application:load/1 加载它。它会检查 applications 键对应的值,来确保要在该应用运行之前启动的应用都启动了。 

然后应用控制器为应用创建一个应用主程序。它是该应用中所有进程的队长。应用主程序通过调用应用模块中的回调函数 start/2 启动应用(会给出由在 .app 文件中的 mod 建定义的启动参数)。 

停止一个应用,但不卸载,可调用: 

7> application:stop(ch_app). 
ok 
配置应用¶ 
可以使用配置参数来对应用进行配置。它们在 .app 文件中是一个由键 env 指定的 {Par, Val} 元组列表。 

{application, ch_app, 
[{description, "Channel allocator"}, 
  {vsn, "1"}, 
  {modules, [ch_app, ch_sup, ch3]}, 
  {registered, [ch3]}, 
  {applications, [kernel, stdlib, sasl]}, 
  {mod, {ch_app,[]}}, 
  {env, [{file, "/usr/local/log"}]} 
]}. 
Par 必须是一个原子, Val 可以是任意值。应用可以通过调用 application:get_env(App, Par) 或一些其他类似函数来获取配置参数的值,参见 application(3) 。 

例如: 

% erl 
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0] 

Eshell V5.2.3.6  (abort with ^G) 
1> application:start(ch_app). 
ok 
2> application:get_env(ch_app, file). 
{ok,"/usr/local/log"}.app 文件中的值可以被系统配置文件中的值所覆盖。系统配置文件是一个包含相关应用的配置参数的文件。 

[{Application1, [{Par11,Val11},...]}, 
..., 
{ApplicationN, [{ParN1,ValN1},...]}]. 
系统配置要被命名为 Name.config 并且要使用命令行参数 -config Name 来启动Erlang。更多信息参见 config(4) 。 

例如:创建一个文件 test.config 包含一下内容: 

[{ch_app, [{file, "testlog"}]}]. 
file 的值将覆盖在 .app 文件中所定义的 file 的值: 

% erl -config test 
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0] 

Eshell V5.2.3.6  (abort with ^G) 
1> application:start(ch_app). 
ok 
2> application:get_env(ch_app, file). 
{ok,"testlog"}如果使用了 发布处理 ,那么只能使用一个系统配置文件同时该文件必须叫做 sys.config 。 

在 .app 文件中的值,也包括系统配置文件中的值,都可以直接在命令行中被覆盖: 

% erl -ApplName Par1 Val1 ... ParN ValN例如: 

% erl -ch_app file '"testlog"' 
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0] 

Eshell V5.2.3.6  (abort with ^G) 
1> application:start(ch_app). 
ok 
2> application:get_env(ch_app, file). 
{ok,"testlog"}应用启动类型¶ 
当启动应用的时候要定义一个启动类型。 

application:start(Application, Type) 
application:start(Application) 和调用 application:start(Application, temporary) 是一样的。类型还可以是 permanent 持久的或者 transient 过渡的: 

•如果一个持久应用终止了,所有其他的应用以及运行时系统都会被终止。 
•如果一个过渡应用以 normal 理由终止了,那么这个信息会被上报但是不会终止其他应用。如果一个过渡应用异常终止了——即以非 normal 的理由终止了——那么其他应用以及运行时环境也会被终止。 
•如果一个临时(temporary)应用终止了,那么会报告该信息但不会终止其他应用。 
我们总是可以通过明确调用 application:stop/1 来停止一个应用。无论是什么模式,都不会影响其他应用。 

注意在实践中很少使用过渡模式,因为当一个监督树终止了,退出理由会被设置为 shutdown ,而非 normal 。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sdsabc2000/article/details/41045255

智能推荐

动手实验 - TensorFlow和TensorBoard自然语言分析_weixin_33860722的博客-程序员秘密

通过这篇文章,你会了解如何在自然语言处理项目中运用TensorFlow这个强大的工具。并同时体验TensorBoard的一些基本用法。我会对文中涉及到的部分代码进行解释,而一些更基础运用需要你自己去补充了。这个项目中,我们会用到Kaggle (https://www.kaggle.com/c/word2vec-nlp-tutorial)中的数据。这个...

详解GC机制,gc机制,Android垃圾回收机制的底层描述_世界流浪者的博客-程序员秘密

GC概念: 什么是GC机制?字面是说是“垃圾收集”,更精确点就是“内存回收”,在一个对象不再被程序引用时,它所占用的堆空间就可以回收,以便分配给新对象使用。先认识三个英语:(Minor GC) vs (Major GC) vs (Full GC)Minor GC从年轻代空间(包括 Eden 和 Survivor 区域)回收内存被称为 Minor GC

基于HTML5的拓扑图编辑器(2)_weixin_30251587的博客-程序员秘密

继续来说编辑器的需求, 前面介绍了拖拽创建节点、以及连线的方法,并加入到了其后的 Qunee 类库,实际应用中需要更多功能,Qunee 的拓扑图编辑器也在逐渐完善,一方面增加多种编辑交互,一方面提供数据导入导出,同时也在摸索编辑器的整体界面设计和前端开发框架拖拽创建节点延续之前提供的功能,增加更多可配置选项(可设置节点类型,样式和属性),支持按住shift快捷键...

Android 中单选框或复选框点击其中一个,其余取消操作_苍白的咏叹调的博客-程序员秘密

利用setChecked(boolean flag)函数,当点击一个时,设置他为true,其余为false为每个设置监听事件,利用view.getId()来抓取你想要的id,代码如下所示:radioButton1=findViewById(R.id.radioButton);radioButton2=findViewById(R.id.radioButton2);radioButton1.se...

【软件工具】之下载微软官方正版 windows 系统_王廷云的博客的博客-程序员秘密_微软系统下载工具

1、进入微软官网微软官网地址:https://www.microsoft.com/zh-cn/,点击导航栏上的 Windows 按钮:2、进入WINDOWS支持页面进入 windows 页面后,拉倒页面的最底下,点击 WINDOWS支持 :3、进入安装和更新页面进入 【WINDOWS支持】 页面后面,点击 安装和更新 按钮:4、进入windows镜像下载页面在 【安装&更新】 页面中选择我们要下载安装的系统,这里我选择了 Windows10,然后在相应的下面点击 重新安装Wind

CQL and ECQL_「已注销」的博客-程序员秘密

本文讲述了如何使用CQL and ECQL查询语言,文章摘自GeoServer官网。在GeoServer的WMS和WFS动态渲染图层,并通过不同的例子具体说明。其中CQL and ECQL查询语言放置在定义WMS和WFS图层的params中,示例代码如下:var WMSsource = new ol.source.ImageWMS({ ratio: 1, url: 'http...

随便推点

summary6-使用摄像头中的数据来提取有关其环境的进一步信息 [Python]_努力奋斗的K崽的博客-程序员秘密

本课程结束时,您将能够:使用一系列ROS工具来查询ROS网络上的摄像头图像主题,并查看流式传输给他们的图像。使用计算机视觉库OpenCV和ROS,获取相机图像并实时处理。应用过滤过程来隔离图像中感兴趣的对象。开发目标检测节点,并利用这些过程产生的信息来控制机器人的位置。使用摄像头数据作为反馈信号,通过比例控制实现线路跟随行为。在ROS中使用摄像头和图像摄像机主题和数据我们可以使用许多工具来查看机器人在ROS中拍摄的实时图像。与所有机器人数据一样,这些流被发布到主题中,因此我们首先需要确定这些

【计算机网络】HTTP协议和web服务器_维欣~的博客-程序员秘密

1、浏览器与web服务器在应用层通信使用的是http协议(超文本传输协议),而http协议在传输层使用的是tcp协议。2、浏览器向服务器发起连接前,需要得到服务器的IP及端口。用户在浏览器中通常只输入网址(网站域名),浏览器会通过DNS服务查询获取到服务器的IP地址。对于端口来讲,使用http 协议的程序一般默认使用 80端口。面试题:如果在浏览器上输入网址,之后会发生什么?3、浏览器服务器建立连接后,如果两次以上的请求复用同一个tcp连接,则称之为长连接。如果浏览器发送一次请求报文,服务器回复

用Gen4消除电容触摸屏设计屏障【转】_weixin_33755649的博客-程序员秘密

转自:http://www.cntronics.com/sensor-art/80015498?page=2中心议题:电容式触摸屏设计到产品的各种挑战解决方案:用Gen4消除电容触摸屏设计屏障将电容式触摸屏设计到产品并不是一项简单的任务。这个复杂的机电系统面临着许多集成方面的严峻挑战。终端用户希望他们的产品轻薄,市场需要长电池寿命。对触摸性能...

基于Android Tiny4412平台---敦泰I2C接口FT5X06电容屏驱动原理及软件架构分析_Engineer-Bruce_Yang的博客-程序员秘密

关于I2C的原理可以参考以下博文:http://blog.csdn.net/morixinguan/article/details/78509764下面切入正题,我们从零开始认识电容屏的工作原理以及Android驱动的架构实现,下面是我写的一份PPT,如果想要原文档的话可以找我拿,或者到以下下载链接获取:http://download.csdn.net/download/morixinguan/1

如何使用postman传数组数据_weixin_33849215的博客-程序员秘密

如何使用postman传数组数据  在我们做api接口数据调试的时候,大部分是会用到postman的,一般请求数据的参数都是字符串,但是特殊情况下我们是需要传一个数组数据的,那么为了实现这种需求,究竟该怎么做呢?请看下文  看了网上的很多文档,试了一个网页的链接,没有一个实现我的需求,主要是解释文档重点模糊,导致读者不明所以,所以我又单独写这个文档出来释疑。请看重点  method...

依赖、关联、聚合和组合之间区别_木易不是楊的博客-程序员秘密_关联和聚合的区别

依赖、关联、聚合和组合之间区别耦合度依次增强:依赖、关联、聚合和组合1、依赖(Dependency)关系依赖关系表示一个类依赖于另一个类的定义。依赖关系中,可以简单的理解,就是一个类A使用到了另一个类B,而这种使用关系是具有偶然性的、临时性的、非常弱的,但是B类的变化会影响到A。一般而言,依赖关系在Java语言中体现为局域变量、方法的形参,或者对静态方法的调用。 class Car {.........

推荐文章

热门文章

相关标签