跳到主要内容

Garnet 自定义命令

概述

Garnet 支持注册用 C# 实现的自定义命令和事务,既可以通过服务器端的编程方式实现,也可以通过在客户端运行专用的 REGISTERCS 命令实现。

支持的自定义命令类型

  1. 自定义原始字符串命令:要实现自定义原始字符串命令,请实现一个继承自 CustomRawStringFunctions 基类的类(请参阅示例:main\GarnetServer\Extensions\DeleteIfMatch.cs
  2. 自定义对象命令:要实现自定义对象命令,请实现您的自定义对象类,该类继承自 GarnetObjectBase 基类,以及一个创建您的对象类型并继承自 CustomObjectFactory 基类的工厂(请参阅示例:main\GarnetServer\Extensions\MyDictObject.cs
  3. 自定义事务:要实现自定义事务,请实现一个继承自 CustomTransactionProcedure 基类的类(请参阅示例:main\GarnetServer\Extensions\ReadWriteTxn.cs
  4. 自定义过程:要实现非事务性过程,请实现一个继承自 CustomProcedure 基类的类(请参阅示例:main\GarnetServer\Extensions\Sum.cs

服务器端命令注册

要从服务器端注册新的自定义命令,请使用 GarnetServer 实例的 RegisterApi,并根据您要注册的自定义命令类型调用 NewCommandNewTransactionProc

  1. 自定义原始字符串命令:要使用实现 CustomRawStringFunctions 的具体类注册新命令,请调用 RegisterApi.NewCommand(string name, int numParams, CommandType type, CustomRawStringFunctions customFunctions, RespCommandsInfo commandInfo = null, long expirationTicks = 0),其中 customFunctions 是新具体类的实例。
  2. 自定义对象命令:要使用实现 CustomObjectFactory 的具体类注册新命令,请调用 RegisterApi.NewCommand(string name, int numParams, CommandType commandType, CustomObjectFactory factory, RespCommandsInfo commandInfo = null),其中 factory 是新具体类的实例。
  3. 自定义事务:要使用实现 CustomTransactionProcedure 的具体类注册新事务,请调用 NewTransactionProc(string name, int numParams, Func<CustomTransactionProcedure> proc, RespCommandsInfo commandInfo = null),其中 proc 是返回新具体类实例的 Func
  4. 自定义过程:要使用实现 CustomProcedure 的具体类注册新过程,请调用 RegisterApi.NewProcedure(string name, CustomProcedure customProcedure, RespCommandsInfo commandInfo = null, RespCommandDocs commandDocs = null),其中 customProcedure 是该过程具体类的实例。

请注意,对 RegisterApi 的每次调用都有一个可选的 RespCommandsInfo commandInfo 参数。此参数允许您为 Garnet 提供有关自定义命令的元数据,当运行 COMMANDCOMMAND INFO 命令时,客户端将可以看到这些元数据。

客户端命令注册

要从客户端注册新的自定义命令,请在客户端应用程序中使用专用的 REGISTERCS 命令(注意:这是一个管理命令)。
REGISTERCS 命令接受存在于服务器上并包含任何受支持的自定义命令类实现的程序集,并根据客户端提供的参数在服务器上注册自定义命令。
REGISTERCS 命令支持从包含 C# 二进制文件(*.dll / *.exe)的多个文件和/或目录中注册多个命令和/或事务。

启用客户端命令注册

要启用客户端自定义命令注册,您必须指定一个允许加载程序集的路径列表,并启用模块命令。这可以通过设置配置参数 EnableModuleCommandExtensionBinPaths 来完成。示例(在 garnet.config 中)

"EnableModuleCommand": "local",
"ExtensionBinPaths": ".\first\path\,..\..\second\path\"

注意 #1:程序集可以从这些指定路径下的任何目录级别加载
注意 #2:默认情况下,Garnet 只允许加载数字签名的程序集。要删除该要求(不推荐),请将配置参数 ExtensionAllowOnlySignedAssemblies 设置为 false

REGISTERCS 命令

要运行 REGISTERCS 命令,请运行 REGISTERCS 关键字,后跟一个或多个新命令子命令,然后是可选的 INFO 关键字,后跟指向包含 RespCommandsInfo 对象序列化数组的 JSON 文件的路径,该文件包含命令元数据(*.json),然后是 SRC 关键字,后跟一个或多个 C# 二进制文件或包含 C# 二进制文件(*.dll / *.exe)的目录的路径。

完整命令语法:

REGISTERCS cmdType name numParams className [expTicks] [cmdType name numParams className [expTicks] ...] [INFO path] SRC path [path ...]

您打算注册的每个新命令都由命令类型关键字之一指定,后跟其参数。

新命令子命令语法:

cmdType name numParams cmdType className [expTicks]

命令类型
以下关键字是 cmdType 的合法值

  • READ(新读取命令)
  • READMODIFYWRITERMW(新读-修改-写命令)
  • TRANSACTIONTXN(新事务)

参数

  • name:新命令的名称
  • numParams:新命令接受的参数数量
  • className:实现 CustomRawStringFunctionsCustomObjectFactory 的具体类的类名,用于新的 READ / RMW 命令,或用于新的 TXN 命令的 CustomTransactionProcedure(必须存在于路径列表中引用的程序集中)
  • expTicks:命令过期时间(以 tick 为单位)(仅与自定义原始字符串命令相关,否则忽略)
    • -1:删除现有过期元数据;
    • 0:保留当前状态(如果这是新条目,则不设置过期时间)- 这是默认值;
    • >0:=> 将过期时间设置为给定值。

注意:如果服务器无法注册指定的一个或多个命令/事务,或者无法加载或枚举 REGISTERCS 命令中指定的一个或多个文件或目录,则不会采取任何操作(即不会注册任何命令),并且命令执行将失败并显示相应的错误消息。

RESP 回复

成功时返回 +OK,否则返回 --ERR 消息(如果有)

REGISTERCS 错误

  • ERR malformed REGISTERCS command - REGISTERCS 命令解析错误
  • ERR unable to access command info file. - 访问 INFO 关键字后指定的命令信息文件时出错
  • ERR command info file is not contained in allowed paths. - 命令信息文件不包含在根据服务器配置(garnet.config 中的 ExtensionBinPaths)允许的路径列表中
  • ERR malformed command info JSON. - 反序列化命令信息 JSON 文件时出错
  • ERR unable to access one or more binary files - 访问或枚举路径列表中指定的一个或多个文件或文件夹时出错
  • ERR one or more binary file are not contained in allowed paths - 指定的一个或多个二进制路径不包含在根据服务器配置(garnet.config 中的 ExtensionBinPaths)允许的路径列表中
  • ERR unable to load one or more assemblies - 从路径列表中检索到的二进制文件加载一个或多个程序集时出错(尝试加载指定或在目录中找到的所有 *.dll / *.exe 文件)
  • ERR one or more assemblies loaded is not digitally signed - 加载的一个或多个程序集未进行数字签名。当服务器配置设置为只允许加载数字签名程序集(garnet.conf 中的 ExtensionAllowOnlySignedAssemblies)时,尝试加载未签名程序集会发生此错误
  • ERR unable to instantiate one or more classes from given assemblies - 使用加载的程序集创建指定的一个或多个类的实例时出错(请注意,每个类都应该有一个空构造函数)
  • ERR unable to register one or more unsupported classes - 注册一个或多个不受支持的类时出错,即一个或多个类没有实现预期的基类之一