您的位置:首页 > 游戏 > 游戏 > 页面设计上边距在哪里找_做网站可以赚钱吗_怎么做app推广代理_网络公司取什么名字好

页面设计上边距在哪里找_做网站可以赚钱吗_怎么做app推广代理_网络公司取什么名字好

2025/2/25 5:11:12 来源:https://blog.csdn.net/puss0/article/details/144253353  浏览:    关键词:页面设计上边距在哪里找_做网站可以赚钱吗_怎么做app推广代理_网络公司取什么名字好
页面设计上边距在哪里找_做网站可以赚钱吗_怎么做app推广代理_网络公司取什么名字好

Application 是用于处理应用和定义应用回调的模块。

应用是 Erlang/OTP 中打包软件的惯用方式。为了理解这个概念,它类似于其他编程语言中常见的“库”的概念,但又有一些额外的特性。

应用是一个实现特定功能的组件,具有标准化的目录结构、配置和生命周期。应用程序可以被加载、启动和停止 。每个应用程序还有自己的环境,它提供了一个统一的API来配置每个应用。

开发人员通常与应用环境及其回调模块打交道。因此,我们首先讨论它们,然后再深入应用资源文件和生命周期的细节。

应用环境

每个应用都有自己的环境。环境是一个关键字列表。请注意,此环境与操作系统环境无关。

默认情况下,应用的环境是一个空列表。在Mix项目的 mix.exs 文件中,你可以通过在 application/0 函数中设置 :env 键来配置它:

def application do[env: [db_host: "localhost"]]
end

现在,在你的应用中,你可以使用诸如 fetch_env!/2 及其变体函数来读取此环境:

defmodule MyApp.DBClient dodef start_link() doSomeLib.DBClient.start_link(host: db_host())enddefp db_host doApplication.fetch_env!(:my_app, :db_host)end
end

在Mix项目中,应用及其依赖的环境可以通过 config/config.exsconfig/runtime.exs 文件覆盖。前者用于构建时,在编译之前加载,后者用于运行时,在应用启动之前加载。例如,使用你的应用的人可以覆盖 :db_host 环境变量如下:

import Config
config :my_app, :db_host, "db.local"

有关更多信息,请参见 Mix 模块中的“配置”部分。你还可以使用 put_env/3delete_env/2 等函数动态更改应用环境。

库的环境
配置文件 config/config.exsconfig/runtime.exs 很少被库使用。库通常在其 mix.exsapplication/0 函数中定义环境。配置文件更多地被应用用来配置它们的库。

读取其他应用的环境
每个应用只应该负责自己的环境。不要使用此模块中的函数直接访问或修改其他应用的环境。当你更改应用环境时,Elixir的构建工具只会重新编译属于该应用的文件。所以如果你读取了另一个应用的环境,就有可能依赖于过时的配置,因为你的代码不会随着它的变化被重新编译。

编译时环境

在前面的示例中,我们在运行时读取应用环境:

defmodule MyApp.DBClient dodef start_link() doSomeLib.DBClient.start_link(host: db_host())enddefp db_host doApplication.fetch_env!(:my_app, :db_host)end
end

换句话说,应用 :my_app 的环境 :db_host 只有在 MyApp.DBClient 实际启动时才会被读取。虽然在运行时读取应用环境是首选的方法,但在某些罕见的情况下,你可能会在编译阶段访问应用环境。然而,如果你尝试在函数外部访问 Application.fetch_env!/2 函数 :

defmodule MyApp.DBClient do@db_host Application.fetch_env!(:my_app, :db_host)def start_link() doSomeLib.DBClient.start_link(host: @db_host)end
end

你可能会看到警告和错误:

warning: Application.fetch_env!/2 is discouraged in the module body,
use Application.compile_env/3 insteadiex:3: MyApp.DBClient** (ArgumentError) could not fetch application environment :db_host
for application :my_app because the application was not loaded nor
configured

这是因为在定义模块时,应用环境尚不可用。幸运的是,警告告诉了我们应用使用 Application.compile_env/3 来解决这个问题:

defmodule MyApp.DBClient do@db_host Application.compile_env(:my_app, :db_host, "db.local")def start_link() doSomeLib.DBClient.start_link(host: @db_host)end
end

这里的不同之处在于 compile_env 需要提供默认值作为参数,而不是使用 mix.exs 中的 def application 函数。此外,通过使用 compile_env/3 ,像Mix这样的工具会存储在编译期间使用的值,并在系统启动时将其与运行时的值进行比较,如果它们不同,会抛出错误。

总之,应避免使用编译时环境。只要有可能,运行时读取应用环境都应该是首选。

应用回调模块

应用可以被加载、启动和停止。通常,像Mix这样的构建工具会为你启动应用及其所有依赖项,但你也可以手动执行

{:ok, _} = Application.ensure_all_started(:some_app)

当应用启动时,开发人员可以配置一个回调模块来执行自己的代码。开发人员也是使用此回调来启动应用的监督树。

首先,你需要在 mix.exs 文件的 application/0 定义中添加一个 :mod 键。它需要一个元组,包含应用回调模块和启动参数(通常是空列表):

def application do[mod: {MyApp, []}]
end

提供给 :modMyApp 模块需要实现 Application 行为。我们可以通过在该模块中使用 use Application 并实现 start/2 回调来完成,例如:

defmodule MyApp douse Applicationdef start(_type, _args) dochildren = []Supervisor.start_link(children, strategy: :one_for_one)end
end

当你 use Application 时, Application 模块会设置 @behaviour Application 并定义一个可重写的 stop/1 函数,这是 Erlang/OTP 所需要的。

start/2 回调必须派生并链接一个监督者,并返回 {:ok, pid}{:ok, pid, state} ,其中 pid 是监督者的PID, state 是可选的应用状态。 args 是传递给 :mod 选项的元组的第二个元素。

传递给 start/2type 参数通常是 :normal ,除非是在配置了应用接管和故障转移的分布式设置中。分布式应用程序超出了此文档的范围。

当应用关闭时,其 stop/1 回调会在监督树被运行时停止后被调用。这个回调允许应用进行最后的清理工作。它的参数是 start/2 返回的状态,如果有的话,或者 []stop/1 的返回值会被忽略。

use Application 为模块定义了一个默认的 stop/1 实现,它会忽略其参数并返回 :ok ,但它可以被重写。

应用回调模块还可以实现可选回调 prep_stop/1 。如果存在, prep_stop/1 会在监督树终止之前被调用。其参数是 start/2 返回的状态,如果有的话,或者 [] ,其返回值会传递给 stop/1

应用资源文件

在上述部分中,我们在 mix.exs 文件的 application/0 部分配置了一个应用。最终,Mix会使用此配置创建一个名为 APP_NAME.app 的应用资源文件。例如,OTP应用 ex_unit 的应用资源文件就叫做 ex_unit.app

你可以在 Mix.Tasks.Compile.App 的文档中了解更多关于生成应用资源文件的信息,也可以通过运行 mix help compile.app 来获取帮助。

应用生命周期

加载应用

应用被加载,意思就是运行时找到并处理它的资源文件:

Application.load(:ex_unit)
#=> :ok

当应用被加载时,资源文件中指定的环境会与配置文件中的合并。

加载应用不会加载它的模块,只是加载应用资源文件。

实际上,你很少需要手动加载应用,因为这是启动过程的一部分。

启动应用

应用也会被启动:

Application.start(:ex_unit)
#=> :ok

一旦应用编译完成,运行系统就是启动当前的应用及其依赖项的问题。与其他语言不同,Elixir 没有负责启动系统的 main 函数。相反,你会启动一个或多个应用,每个应用都有自己的初始化和终止逻辑。

当应用启动时, Application.load/1 会自动被调用,如果没有调用过的话。然后,它会检查资源文件中 applications 键列出的依赖项是否已经启动。只要有一个依赖项未启动都会报错。像 ensure_all_started/1 这样的函数会为你启动应用及其所有依赖项。

如果应用没有配置回调模块,启动在这里就完成了。否则,会调用其 start/2 回调。此函数返回的顶级监督者的PID由运行时存储以备后用,返回的应用状态也会被保存。

停止应用

天下没有不散的筵席,启动的应用最终也会被停止:

Application.stop(:ex_unit)
#=> :ok

如果没有定义 stop 回调,停止应用实际上没有什么操作,除了一些系统跟踪。

停止一个有回调模块的应用有三个步骤:

  1. 调用可选的 prep_stop/1 回调,如果有的话。
  2. 终止顶级监督者。
  3. 调用 stop/1 回调。

传递给回调的参数与 start/2 可选返回的状态有关,如上文关于回调模块的部分所述。

需要特别强调的是,第二步是一个阻塞步骤。终止监督者会触发递归终止子进程,有序关闭所有后代进程。 stop/1 回调仅在终止整个监督树之后被调用。

通过调用 System.stop/1 可以干净的关闭系统 。它会以与启动相反的顺序关闭每个应用。

默认情况下,来自操作系统的 SIGTERM 会自动转换为 System.stop/0 。你还可以通过 :os.set_signal/2 函数对操作系统信号进行更多的显式控制。

工具

Mix 构建工具自动化了大多数应用管理任务。例如, mix test 在你的测试运行之前自动启动应用依赖和应用本身。 mix run --no-halt 启动当前工程,可以用来启动一个长期运行的系统。参见 mix help run

开发人员还可以使用 mix release 构建发布包。发布包能够将你的所有源代码以及 Erlang VM 打包到一个目录中。发布包还可以让你控制每个应用如何启动以及启动顺序。它还提供了一个更流畅的机制,用于启动和停止系统、调试、日志记录以及系统监控。

最后,Elixir 还提供了诸如 escripts 和归档工具,用来打包你的应用。这些通常用于工具必须在开发人员之间共享时,而不是作为部署选项。有关更多详细信息,请参阅 mix help archive.buildmix help escript.build

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com