MIX OTP——依赖项和总体项目

news2024/7/4 20:05:44

在本章中,我们将讨论如何管理 Mix 中的依赖项。

我们的 kv 应用程序已经完成,现在是时候实现处理我们在第一章中定义的请求的服务器了:

但是,我们不会向 kv 应用程序添加更多代码,而是将 TCP 服务器构建为另一个应用程序,即 kv 应用程序的客户端。由于整个运行时和 Elixir 生态系统都面向应用程序,因此将我们的项目拆分为可以协同工作的较小应用程序而不是构建一个庞大的单片应用程序是有意义的。

在创建新应用程序之前,我们必须讨论 Mix 如何处理依赖项。实际上,我们通常使用两种依赖项:内部依赖项和外部依赖项。Mix 支持同时处理这两种依赖项的机制。

外部依赖项

外部依赖项是与您的业务领域无关的依赖项。例如,如果您需要分布式 KV 应用程序的 HTTP API,则可以将 Plug 项目用作外部依赖项。

安装外部依赖项很简单。最常见的是,我们使用 Hex 包管理器,通过在我们的 mix.exs 文件中的 deps 函数内列出依赖项:

此依赖项指的是已推送到 Hex 的 1.x.x 版本系列中的最新版本的 Plug。这由版本号前面的 ~> 表示。有关指定版本要求的更多信息,请参阅 Version 模块的文档。

通常,稳定版本会推送到 Hex。如果您想依赖仍在开发中的外部依赖项,Mix 也能够管理 Git 依赖项:

您会注意到,当您向项目添加依赖项时,Mix 会生成一个 mix.lock 文件,以确保可重复构建。必须将锁定文件签入到您的版本控制系统中,以保证使用该项目的每个人都使用与您相同的依赖项版本。

Mix 提供了许多处理依赖项的任务,可在 mix 帮助中查看:

最常见的任务是 mix deps.get 和 mix deps.update。一旦获取,依赖项就会自动为您编译。您可以通过输入 mix help deps 以及 Mix.Tasks.Deps 模块的文档来了解有关 deps 的更多信息。

内部依赖项

内部依赖项是特定于您的项目的依赖项。它们通常在您的项目/公司/组织范围之外没有意义。大多数时候,您都希望将它们保密,无论是出于技术、经济还是商业原因。

如果您有内部依赖项,Mix 支持两种方法来处理它们:Git 存储库或伞状项目。

例如,如果您将 kv 项目推送到 Git 存储库,则需要将其列在您的 deps 代码中才能使用它:

但是,如果存储库是私有的,您可能需要指定私有 URL git@github.com:YOUR_ACCOUNT/kv.git。无论如何,只要您有适当的凭据,Mix 就能为您获取它。

在 Elixir 中,不鼓励使用 Git 存储库来处理内部依赖项。请记住,运行时和 Elixir 生态系统已经提供了应用程序的概念。因此,我们希望您经常将代码分解为可以按逻辑组织的应用程序,即使在单个项目中也是如此。

但是,如果您将每个应用程序作为单独的项目推送到 Git 存储库,您的项目可能会变得非常难以维护,因为您将花费大量时间管理这些 Git 存储库,而不是编写代码。

出于这个原因,Mix 支持“umbrella projects”。umbrella projects用于构建在单个存储库中一起运行的应用程序。这正是我们将在下一节中探讨的风格。

让我们创建一个新的 Mix 项目。我们将其创造性地命名为 kv_umbrella,这个新项目将包含现有的 kv 应用程序和新的 kv_server 应用程序。目录结构将如下所示:

这种方法的有趣之处在于,Mix 为处理此类项目提供了许多便利,例如,只需一个命令即可编译和测试应用程序内的所有应用程序。但是,即使它们都在应用程序内一起列出,它们仍然彼此分离,因此您可以根据需要单独构建、测试和部署每个应用程序。

让我们开始吧!

Umbrella projects

让我们使用 mix new 开始一个新项目。这个新项目将被命名为 kv_umbrella,我们需要在创建它时传递 --umbrella 选项。不要在现有的 kv 项目中创建这个新项目!

从打印的信息中,我们可以看到生成的文件少了很多。生成的 mix.exs 文件也不同。让我们看一看(注释已被删除):

这个项目与前一个项目的不同之处在于项目定义中的 apps_path:“apps”条目。这意味着这个项目将充当一个命名空间。这样的项目没有源文件也没有测试,但它们可以有自己的依赖项。每个子应用程序都必须在 apps 目录中定义。

让我们进入 apps 目录并开始构建 kv_server。这一次,我们将传递 --sup 标志,它将告诉 Mix 自动为我们生成一个监督树,而不是像前面章节那样手动构建一个:

生成的文件与我们第一次为 kv 生成的文件类似,但有一些不同。

首先,由于我们在 kv_umbrella/apps 中生成了这个项目,Mix 自动检测到了树状结构并在项目定义中添加了四行:

因为我们传递了 --sup 标志,Mix 自动添加了 mod: {KVServer.Application, []},指定 KVServer.Application 是我们的应用程序回调模块。KVServer.Application 将启动我们的应用程序监督树。

事实上,让我们打开 lib/kv_server/application.ex:

请注意,它定义了应用程序回调函数 start/2,而不是定义使用 Supervisor 模块的名为 KVServer.Supervisor 的主管,而是方便地内联定义了主管!您可以通过阅读 Supervisor 模块文档来了解有关此类主管的更多信息。

我们已经可以尝试我们的第一个umbrella子项了。我们可以在 apps/kv_server 目录中运行测试,但那没什么意思。相反,转到umbrella project的根目录并运行 mix test:

成功了!

由于我们希望 kv_server 最终使用我们在 kv 中定义的功能,因此我们需要将 kv 作为依赖项添加到我们的应用程序中。

Umbrella Project中的依赖关系

umbrella project中应用程序之间的依赖关系仍必须明确定义,而 Mix 可轻松实现此目的。打开 apps/kv_server/mix.exs 并将 deps/0 函数更改为以下内容:

上面的行使 :kv 可用作 :kv_server 中的依赖项,并在服务器启动之前自动启动 :kv 应用程序。

最后,将我们迄今为止构建的 kv 应用程序复制到新umbrella project中的 apps 目录中。最终的目录结构应与我们之前提到的结构相匹配:

我们现在需要修改 apps/kv/mix.exs 以包含我们在 apps/kv_server/mix.exs 中看到的umbrella条目。打开 apps/kv/mix.exs 并添加到 project/0 函数:

现在,您可以使用 mix test 从umbrella根目录运行两个项目的测试。太棒了!

合理使用Umbrella

umbrella project是一种便利,可帮助您组织和管理多个应用程序。虽然它在应用程序之间提供了一定程度的分离,但这些应用程序并未完全解耦,因为它们共享相同的配置和相同的依赖项。

将多个应用程序保存在同一个存储库中的模式称为“mono-repo”。umbrella project通过提供同时编译、测试和运行多个应用程序的便利来最大化这种模式。

如果您发现自己处于想要在每个应用程序中为相同的依赖项使用不同的配置或使用不同的依赖项版本的位置,那么您的代码库很可能已经超出了umbrella所能提供的范围。

好消息是,拆分umbrella非常简单,因为您只需将应用程序移出umbrella project的 apps/ 目录并更新项目的 mix.exs 文件以不再设置 build_path、config_path、deps_path 和 lockfile 配置。您可以通过多种方式依赖umbrella project之外的私有项目:

1.将其移动到同一存储库中的单独文件夹,并使用路径依赖项(mono-repo 模式)指向它
2.将存储库移动到单独的 Git 存储库并依赖它
3.将项目发布到私有 Hex.pm 组织

总结

在本章中,我们学习了更多关于 Mix 依赖项和umbrella project的知识。虽然我们可以在没有服务器的情况下运行 kv,但我们的 kv_server 直接依赖于 kv。通过将它们分解为单独的应用程序,我们可以更好地控制它们的开发和测试方式。

使用umbrella application时,在它们之间划出明确的界限非常重要。我们即将推出的 kv_server 必须仅访问 kv 中定义的公共 API。将您的umbrella application视为任何其他依赖项,甚至是 Elixir 本身:您只能访问公共和记录的内容。触及依赖项中的私有功能是一种不好的做法,最终会导致您的代码在新版本发布时崩溃。

umbrella application还可以用作最终从代码库中提取应用程序的垫脚石。例如,想象一个必须向其用户发送“推送通知”的 Web 应用程序。整个“推送通知系统”可以作为umbrella application中的单独应用程序进行开发,具有自己的监督树和 API。如果您遇到另一个项目需要推送通知系统的情况,则可以将该系统移至私有存储库或 Hex 包。

最后,请记住,umbrella project中的应用程序都共享相同的配置和依赖项。如果umbrella中的两个应用程序需要以截然不同的方式配置相同的依赖项,甚至使用不同的版本,那么您可能已经超出了umbrella带来的好处。请记住,您可以打破umbrella,同时仍能利用“mono-repos”背后的好处。

随着我们的umbrella project启动并运行,是时候开始编写我们的服务器了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1886292.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux系统之安装Firefox浏览器

Linux系统之安装Firefox浏览器 一、Firefox浏览器介绍1.1 Firefox浏览器介绍1.2 Firefox浏览器特点 二、环境介绍二、本次实践环境介绍2.1 环境规划2.2 本次实践介绍 三、安装firefox浏览器3.1 安装epel3.2 检查yum仓库状态3.3 安装Firefox浏览器3.4 查看Firefox版本 四、在命令…

win11电源设置

把钩子去掉以后 win11的电脑关机才有用 否则,关机了,电脑也实际上一直在运行

partition()方法——分割字符串为元组

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 语法参考 partition()方法根据指定的分隔符将字符串进行分割。如果字符串中包含指定的分隔符,则返回一个3元的元组,第一个为…

HarmonyOS(38) UIAbility里icon和label的作用

UIAbility里icon和label的作用 icon和label实际效果测试代码传送门参考资料 icon和label 为使应用能够正常使用UIAbility,需要在module.json5配置文件的abilities标签中声明UIAbility的名称、入口、标签等相关信息: {"module": {..."ab…

3.3prometheus命令行参数讲解

本节重点介绍 : target页面flags页面status页面tsdb-status页面 访问地址 $ip:9090 target页面 flags页面 展示命令行参数的,没设置的取默认值 status页面 描述运行信息和编译的信息 tsdb-status页面 打印存储的运行状态信息帮我们定位重查询的 服务发现页面…

怎么把录音转文字?推荐几个简单易操作的方法

在小暑这个节气里,炎热的天气让人分外渴望效率up!Up!Up! 对于那些在会议或课堂中急需记录信息的朋友们,手写笔记的速度往往难以跟上讲话的节奏。此时,电脑录音转文字软件就像一阵及时雨,让记录…

深度学习原理与Pytorch实战

深度学习原理与Pytorch实战 第2版 强化学习人工智能神经网络书籍 python动手学深度学习框架书 TransformerBERT图神经网络: 技术讲解 编辑推荐 1.基于PyTorch新版本,涵盖深度学习基础知识和前沿技术,由浅入深,通俗易懂&#xf…

动态顺序表实现通讯录

系列文章目录 【数据结构】顺序表 文章目录 系列文章目录前言一、通讯录的功能要求二、通讯录的代码实现1. 新建文件2. 创建通讯录的结构体3. 对顺序表文件进行修改4. 通讯录具体功能实现4.1. 通讯录的初始化和销毁4.2. 增加联系人信息(尾插)4.3. 查找指…

无污染的独立海域-第13届蓝桥杯省赛Python真题精选

[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第90讲。 无污染的独立海域…

余承东在母校西工大毕业典礼演讲:定位决定地位,眼界决定境界。

添加图片注释,不超过 140 字(可选) 【6月29日,西北工业大学2024届本科生毕业典礼暨学位授予仪式隆重举行。典礼上,华为常务董事、终端BG 董事长、智能汽车解决方案BU 董事长余承东作为校友代表致辞,为毕业生…

项目实战--Spring Boot实现三次登录容错功能

一、功能描述 项目设计要求输入三次错误密码后,要求隔段时间才能继续进行登录操作,这里简单记录一下实现思路 二、设计方案 有几个问题需要考虑一下: 1.是只有输错密码才锁定,还是账户名和密码任何一个输错就锁定?2…

gz格式文件16进制分析

接上篇长虹55D3P (海思平台)kernel分区解包ramdisk重新打包-CSDN博客深入研究下gz格式 上篇说到分割得到的ramdisk会有垃圾数据,对于ramdisk无用的垃圾数据可能有其他用途。我们只需要修改ramdisk,就必须准确知道ramdisk的起始地址和结束地址&#xff0…

刚入行的测试新人,应该如何规划自己的职业发展路径?

作为一个刚入行的测试新人,应该如何规划自己的职业发展路径?如何规划自己的技术路线?软件测试的段位都有哪些?他们之间的薪资差异如何? 听说这些问题,是目前想要入行软件测试的同学们最关心的。那么我们今天…

钡铼BL104智慧环保多个485采集转MQTT无线传输

PLC物联网关BL104是一款专为工业环境设计的先进协议转换网关,其集成了钡铼智能技术和环保多个485采集转MQTT无线传输功能,为工业控制系统提供了高效的数据采集、传输和管理解决方案。 技术规格与功能特点 PLC物联网关BL104采用钡铼智能技术&#xff0c…

k8s部署单节点redis

一、configmap # cat redis-configmap.yaml apiVersion: v1 kind: ConfigMap metadata:name: redis-single-confignamespace: redis data:redis.conf: |daemonize nobind 0.0.0.0port 6379tcp-backlog 511timeout 0tcp-keepalive 300pidfile /data/redis-server.pidlogfile /d…

顺序表实现——通讯录

前言: 通过对数据结构--顺序表的学习,了解了顺序表的增加数据,删除数据等功能;我们就可以基于顺序表来实现通讯录,接下来就一起来实现通讯录。 首先我们需要存储通讯录中联系人信息,这里创建一个结构体&…

Vue报错:Module not found: Error: Can‘t resolve ‘less-loader‘ in ‘文件地址‘

原因&#xff1a;Webpack无法找到 less-loader 模块&#xff0c;但在<style langless></style>中进行使用。less-loader 是一个Webpack的加载器&#xff0c;它用于将less文件编译成CSS。如果Webpack无法解析这个加载器&#xff0c;它就无法处理less文件&#xff0c…

【C语言内存函数】

目录 1.memcpy 使用 模拟实现 2.memmove 使用 模拟实现 3.memset 使用 4.memcmp 使用 1.memcpy 使用 void * memcpy ( void * destination, const void * source, size_t num );目的地址 源地址 字节数 destination&#xff1a;指向要复制内…

EDA 虚拟机 Synopsys Sentaurus TCAD 2017.09 下载

下载地址&#xff08;制作不易&#xff0c;下载使用需付费&#xff0c;不能接受的请勿下载&#xff09;&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1327I58gvV1usWSqSrG7KXw?pwdo03i 提取码&#xff1a;o03i

heic图片怎么转成jpg格式,这6个方法亲测有用(超简单)

heic图片怎么转成jpg&#xff1f;现在我们都喜欢用手机来拍摄记录生活中的美好瞬间&#xff0c;照片太多的话我们为了不占用手机内存&#xff0c;会把照片导入电脑进行储存。但是苹果手机用户在导入相册照片时可能会遇到以下问题&#xff1a;因为苹果手机拍摄照片格式默认为hei…