StackExchange.Redis 命令扩展

Intro

在之前的文章中有简单介绍过 StackExchange.Redis 直接调用 Redis 命令来实现调用 Stream 的根据消息 Id 来控制消息长度,因为 StackExchange.Redis 目前还不支持根据消息 Id 控制 Stream 消息长度,目前有很多 6.2 以后带来的新特性大多还不支持。

前段时间,给 StackExchange.Redis 提了一个 PR 支持了一个 Redis 6.2 的新命令 GETDEL,给大家分享一下,有想去蹭贡献的也可以尝试贡献一下

GETDEL

GETDEL 是 Redis 6.2 中引入的新功能中的其中一个,是针对 String 类型的数据的命令,如同命令名称一样,先 GET 并删除某一个 key,返回 key 的内容,如下面示例一样

redis> SET mykey "Hello"

"OK"

redis> GETDEL mykey

"Hello"

redis> GET mykey

(nil)

Implement

命令比较简单,不会造成产生破坏性的变更,实现起来也是比较简单,主要是新增下面两个 API:

RedisValue StringGetDelete(RedisKey key, CommandFlags flags = CommandFlags.None);
Task<RedisValue> StringGetDeleteAsync(RedisKey key, CommandFlags flags = CommandFlags.None);

分别定义在 IDatabase/IDatabaseAsync

对于其实现来说,会增加一个 Redis 命令的枚举定义,需要在 RedisCommand 中增加一个新命令 GETDEL

enum RedisCommand:
+  GETDEL,

实现需要修改的地方有三个:

RedisDatabase,新增的 API 实现如下

public RedisValue StringGetDelete(RedisKey key, CommandFlags flags = CommandFlags.None)
{var msg = Message.Create(Database, flags, RedisCommand.GETDEL, key);return ExecuteSync(msg, ResultProcessor.RedisValue);
}public Task<RedisValue> StringGetDeleteAsync(RedisKey key, CommandFlags flags = CommandFlags.None)
{var msg = Message.Create(Database, flags, RedisCommand.GETDEL, key);return ExecuteAsync(msg, ResultProcessor.RedisValue);
}

DatabaseWrapper:

public RedisValue StringGetDelete(RedisKey key, CommandFlags flags = CommandFlags.None)
{return Inner.StringGetDelete(ToInner(key), flags);
}

WrapperBase:

public Task<RedisValue> StringGetDeleteAsync(RedisKey key, CommandFlags flags = CommandFlags.None)
{return Inner.StringGetDeleteAsync(ToInner(key), flags);
}

单元测试的变更如下:

tests/StackExchange.Redis.Tests/DatabaseWrapperTests.cs:

[Fact]
public void StringGetDelete()
{wrapper.StringGetDelete("key", CommandFlags.None);mock.Verify(_ => _.StringGetDelete("prefix:key", CommandFlags.None));
}

tests/StackExchange.Redis.Tests/WrapperBaseTests.cs:

[Fact]
public void StringGetDeleteAsync()
{wrapper.StringGetDeleteAsync("key", CommandFlags.None);mock.Verify(_ => _.StringGetDeleteAsync("prefix:key", CommandFlags.None));
}

tests/StackExchange.Redis.Tests/Strings.cs: 实际使用也可以参数这两个测试用例

[Fact]
public void GetDelete()
{using (var muxer = Create()){Skip.IfMissingFeature(muxer, nameof(RedisFeatures.GetDelete), r => r.GetDelete);var conn = muxer.GetDatabase();var prefix = Me();conn.KeyDelete(prefix + "1", CommandFlags.FireAndForget);conn.KeyDelete(prefix + "2", CommandFlags.FireAndForget);conn.StringSet(prefix + "1", "abc", flags: CommandFlags.FireAndForget);Assert.True(conn.KeyExists(prefix + "1"));Assert.False(conn.KeyExists(prefix + "2"));var s0 = conn.StringGetDelete(prefix + "1");var s2 = conn.StringGetDelete(prefix + "2");Assert.False(conn.KeyExists(prefix + "1"));Assert.Equal("abc", s0);Assert.Equal(RedisValue.Null, s2);}
}[Fact]
public async Task GetDeleteAsync()
{using (var muxer = Create()){Skip.IfMissingFeature(muxer, nameof(RedisFeatures.GetDelete), r => r.GetDelete);var conn = muxer.GetDatabase();var prefix = Me();conn.KeyDelete(prefix + "1", CommandFlags.FireAndForget);conn.KeyDelete(prefix + "2", CommandFlags.FireAndForget);conn.StringSet(prefix + "1", "abc", flags: CommandFlags.FireAndForget);Assert.True(conn.KeyExists(prefix + "1"));Assert.False(conn.KeyExists(prefix + "2"));var s0 = conn.StringGetDeleteAsync(prefix + "1");var s2 = conn.StringGetDeleteAsync(prefix + "2");Assert.False(conn.KeyExists(prefix + "1"));Assert.Equal("abc", await s0);Assert.Equal(RedisValue.Null, await s2);}
}

More

主要的变更就是这些了,是不是看起来也简单的,除了上面的基本实现就是要增加一些测试用例以及本地进行一下测试,看是不是可以按预期工作,有一些功能可能会要求集成测试

除了上面还有一个小点,就是如果不是只读命令需要声明命令是 MasterOnly 的,在 src/StackExchange.Redis/Message.cs 中的 public static bool IsMasterOnly(RedisCommand command) 声明即可,除此之外,StackExchange.Redis 会建议增加 ReleaseNote

如果你愿意也可以尝试去贡献一下 https://github.com/StackExchange/StackExchange.Redis/issues

References

  • https://github.com/StackExchange/StackExchange.Redis/pull/1840

  • https://github.com/StackExchange/StackExchange.Redis/issues/1729

  • https://redis.io/commands/getdel

  • https://github.com/StackExchange/StackExchange.Redis/issues

StackExchange.Redis 命令扩展相关推荐

  1. php7.2 安装phpredis扩展,以及phpredis操作redis命令列表

    phpredis是redis的php的一个扩展,效率是相当高有链表排序功能,对创建内存级的模块业务关系;以下是redis官方提供的命令使用技巧: 下载安装地址如下: PHP7.2 安装Redis扩展 ...

  2. Linux下安装Redis php-redis扩展 redis重启shell脚本 超详细!

    前言 前面刚写过nosql其中三款热门产品的对比,这次主要写关于Redis的一些事情,Redis的介绍.安装以及扩展(php-redis,因为我是phper)安装等等.同时是写给我的朋友(cccjjj ...

  3. Redis 命令参考

    Redis 命令参考 本文档是 Redis Command Reference 和 Redis Documentation 的中文翻译版, 阅读这个文档可以帮助你了解 Redis 命令的具体使用方法, ...

  4. StackExchange.Redis 使用-配置

    Configuration redis有很多不同的方法来配置连接字符串 , StackExchange.Redis 提供了一个丰富的配置模型,当调用Connect 或者 ConnectAsync 时需 ...

  5. StackExchange.Redis 访问封装类

    最近需要在C#中使用Redis,在Redis的官网找到了ServiceStack.Redis,最后在测试的时候发现这是个坑,4.0已上已经收费,后面只好找到3系列的最终版本,最后测试发现还是有BUG或 ...

  6. StackExchange.Redis学习笔记(五) 发布和订阅

    StackExchange.Redis学习笔记(五) 发布和订阅 原文:StackExchange.Redis学习笔记(五) 发布和订阅 Redis命令中的Pub/Sub Redis在 2.0之后的版 ...

  7. StackExchange.Redis 官方文档(二) Configuration

    配置 有多种方式可以配置redis,StackExchange.Redis提供了一个丰富的配置模型,在执行Connect (or ConnectAsync) 时被调用: var conn = Conn ...

  8. StackExchange.Redis 使用 (一)

    在StackExchange.Redis中最重要的对象是ConnectionMultiplexer类, 它存在于StackExchange.Redis命名空间中. 这个类隐藏了Redis服务的操作细节 ...

  9. 【BCVP更新】StackExchange.Redis 的异步开发方式

    有哪些习惯 坚持 LESS IS MORE,SIMPLER IS BETTER THAN MORE 你一定会有很大的收获 各种小问题? 如果你之前用过Redis的话,肯定会使用过StackExchan ...

最新文章

  1. 关于如何在pc端使用github
  2. Python的学习过程中not enough values to unpack (expected 2, got 1)解决方案
  3. Kali Linux软件更新日报20190622
  4. Linux 操作系统原理 — 内核态与用户态
  5. 计算机●编程语言●JAVA
  6. 临时配置网络(ip,网关,dns)+永久配置
  7. tf 如何进行svd_Tensorflow快餐教程(6) - 矩阵分解
  8. 运行Hadoop自带的wordcount单词统计程序
  9. Filecoin网络目前总质押量约为3570万枚FIL
  10. 【渝粤教育】电大中专测量学 (4)作业 题库
  11. Coolite Toolkit学习笔记七:常用控件TreePanel
  12. android信息实现,Android 信息分享实现
  13. java 图片处理工具类(图片简单处理 java原生)
  14. 实时音频编解码之十一Opus编码
  15. 2021国内软件开发培训机构排名,避坑必看!
  16. 去掉win7快捷方式箭头及修复锁定到任务栏失效
  17. [b2g] firefoxOS 移植记录
  18. 前端测试系列---静态页面测试
  19. cache line对内存访问的影响
  20. 一个关于中国省市区的字典,数组嵌套使用

热门文章

  1. 微博自媒体,一个新的生态
  2. 再读《精通css》02:选择器
  3. 配置Windows 2008 R2 防火墙允许远程访问SQL Server 2008 R2 更改端口 连接字符串 IP+逗号+端口号...
  4. 使用string.Format需要注意的一个性能问题
  5. docker 修改服务器,docker-修改容器挂载目录的3种方法小结
  6. 用树莓派和PC机搭建多节点私人以太坊网络
  7. Jenkins忘记admin密码处理方法
  8. SSH整合注解版(Spring+Struts2+Hibernate)
  9. 设计模式——享元模式具体解释
  10. 《sql语句练习1》