• 272:1 Codegroup children at index "2" is not a codeblock

原子锁

原子锁,亦称 mutex,用于同步对共享资源的访问。换句话说,它防止多个进程或并发代码同时执行一段代码。

AdonisJS 团队创建了一个与框架无关的包,名为 Verrou@adonisjs/lock 包基于此包,因此请务必也阅读 Verrou 文档,该文档更为详细。

安装

使用以下命令安装并配置该包:

node ace add @adonisjs/lock
  1. 使用检测到的包管理器安装 @adonisjs/lock 包。

  2. adonisrc.ts 文件中注册以下服务提供者。

    {
    providers: [
    // ...其他提供者
    () => import('@adonisjs/lock/lock_provider')
    ]
    }
  3. 创建 config/lock.ts 文件。

  4. start/env.ts 文件中定义以下环境变量及其验证。

    LOCK_STORE=redis
  5. 如果使用 database 存储,可选择为 locks 表创建数据库迁移。

配置

锁的配置存储在 config/lock.ts 文件中。

import env from '#start/env'
import { defineConfig, stores } from '@adonisjs/lock'
const lockConfig = defineConfig({
default: env.get('LOCK_STORE'),
stores: {
redis: stores.redis({}),
database: stores.database({
tableName: 'locks',
}),
memory: stores.memory()
},
})
export default lockConfig
declare module '@adonisjs/lock/types' {
export interface LockStoresList extends InferLockStores<typeof lockConfig> {}
}

default

用于管理锁的默认存储。存储在同一配置文件中的 stores 对象下定义。

stores

你计划在应用程序中使用的存储集合。我们建议始终配置 memory 存储,以便在测试期间使用。


环境变量

默认锁存储通过 LOCK_STORE 环境变量定义,因此你可以在不同环境中切换不同的存储。例如,在测试期间使用 memory 存储,在开发和生产环境中使用 redis 存储。

此外,必须验证环境变量以允许预配置存储中的一个。验证在 start/env.ts 文件中使用 Env.schema.enum 规则定义。

{
LOCK_STORE: Env.schema.enum(['redis', 'database', 'memory'] as const),
}

Redis 存储

redis 存储对 @adonisjs/redis 包有对等依赖;因此,在使用 Redis 存储之前,你必须配置此包。

以下是 Redis 存储接受的选项列表:

{
redis: stores.redis({
connectionName: 'main',
}),
}
connectionName

connectionName 属性指的是在 config/redis.ts 文件中定义的连接。

数据库存储

database 存储对 @adonisjs/lucid 包有对等依赖,因此,在使用数据库存储之前,你必须配置此包。

以下是数据库存储接受的选项列表:

{
database: stores.database({
connectionName: 'postgres',
tableName: 'my_locks',
}),
}

connectionName

引用在 config/database.ts 文件中定义的数据库连接。如果未定义,我们将使用默认数据库连接。

tableName

用于存储速率限制的数据库表。

内存存储

memory 存储是一个简单的内存存储,可用于测试目的,但不仅限于此。有时,对于某些用例,你可能希望有一个仅对当前进程有效的锁,而不是在多个进程之间共享。

内存存储基于 async-mutex 包构建。

{
memory: stores.memory(),
}

锁定资源

配置好锁存储后,你可以在应用程序中的任何地方开始使用锁来保护资源。

以下是一个如何使用锁来保护资源的简单示例。