website/docs/dev/garnet-api.md
The IGarnetApi interface contains the operators exposed to the public API, which ultimately perform operations over the keys stored in Garnet. It inherits from IGarnetReadApi (read-only commands interface) and IGarnetAdvancedApi (advanced API calls).
For adding a new operator or command to the API, add a new method signature to the IGarnetReadApi interface in case the command performs read-only operations, or IGarnetApi otherwise.
If you are trying to add a command for your specific Garnet server instance, see Custom Commands
To add a new command to Garnet, follow these steps:
[ObjectName]Operation enum in libs/server/Objects/[ObjectName]/[ObjectName]Object.csRespCommand enum in libs/server/Resp/Parser/RespCommand.cs.libs/server/Resp/Parser/RespCommand.cs: FastParseCommand provides a SIMD fast path for a fixed set of common commands, and any command that is not matched there falls through to ArrayParseCommand, which resolves the command name via HashLookupCommand. To make your command resolvable, add an entry for it to the primary hash table in RespCommandHashLookup.PopulatePrimaryTable() (libs/server/Resp/Parser/RespCommandHashLookupData.cs).libs/server/API/IGarnetApi.cs).libs/server/Resp/Objects/[ObjectName]Commands.cs, while others will reside under libs/server/Resp/[Admin|Array|Basic|etc...]Commands.cs, depending on the command type).libs/server/Resp/RespServerSession.cs, add the new command case to the ProcessBasicCommands or ProcessArrayCommands method respectively, calling the method that was added in step #4.MainSessionFunctions) for raw-string commands, the Object context (ObjectSessionFunctions) for data-structure-object commands, and the Unified context (UnifiedSessionFunctions) for type-agnostic commands (a record's ValueIsObject bit distinguishes inline string bytes from heap object references). A VectorSessionFunctions session also runs on the same store for the Vector Sets preview. The StorageSession class is divided across several .cs files: object-context operations reside under libs/server/Storage/Session/ObjectStore/[ObjectName]Ops.cs, string-context operations mainly reside under libs/server/Storage/Session/MainStore/MainStoreOps.cs, and type-agnostic operations reside under libs/server/Storage/Session/UnifiedStore/. The corresponding Tsavorite callbacks live under libs/server/Storage/Functions/{MainStore,ObjectStore,UnifiedStore}/.[Read|RMW]ObjectStoreOperation[WithOutput], which in turn will call the Operate method in libs/server/Objects/[ObjectName]/[ObjectName]Object.cs, where you will have to add a new case for the command and the object-specific command implementation in libs/server/Objects/[ObjectName]/[ObjectName]ObjectImpl.csTransactionManager instance). You can then operate on multiple objects (for instance using the GET & SET operations).Read or RMW methods via the string context. If you are calling RMW, you will need to implement the initialization and in-place / copy update functionality of the new command in libs/server/Storage/Functions/MainStore/RMWMethods.cs.KeySpecs in its command info metadata; the transaction layer then automatically acquires the appropriate key locks via TxnKeyManager.LockKeys(SimpleRespCommandInfo ...) (libs/server/Transaction/TxnKeyManager.cs).SE.Redis and LightClient, if applicable. For object commands, add tests to Garnet.test/Resp[ObjectName]Tests.cs. For other commands, add to Garnet.test/RespTests.cs or Garnet.test/Resp[AdminCommands|etc...]Tests.cs, depending on the command type.website/docs/commands/, and specify the command as supported in website/docs/commands/api-compatibility.md.:::tip Before you start implementing your command logic, add a basic test that calls the new command, it will be easier to debug and implement missing logic as you go along. :::
Each supported RESP command in Garnet should have an entry in libs/resources/RespCommandsInfo.json, specifying the command's info.
A command's info can be added manually, but we recommend using the CommandInfoUpdater tool to update the JSON file (can be found under playground/).
The CommandInfoUpdater tool calculates the difference between existing commands in libs/resources/RespCommandsInfo.json and commands specified in CommandInfoUpdater/SupportedCommands.cs. It then attempts to add/remove commands' info as necessary.
Info for Garnet-only commands is retrieved from CommandInfoUpdater/GarnetCommandsInfo.json, and info for other RESP commands is retrieved from an external RESP server (which you will need to run locally or have access to in order to run this tool).
To add command info to Garnet, follow these steps:
CommandInfoUpdater/SupportedCommands.cs.CommandInfoUpdater/GarnetCommandsInfo.json.-h or --help).cd playground/CommandInfoUpdater
dotnet run -- --output ../../libs/resources