Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 为自定义数据库解决方案创建Microsoft Bot Framework状态存储适配器的指南_Typescript_Redis_Botframework_Azure Cosmosdb - Fatal编程技术网

Typescript 为自定义数据库解决方案创建Microsoft Bot Framework状态存储适配器的指南

Typescript 为自定义数据库解决方案创建Microsoft Bot Framework状态存储适配器的指南,typescript,redis,botframework,azure-cosmosdb,Typescript,Redis,Botframework,Azure Cosmosdb,在为上述数据库创建一个自定义适配器时,它将与Microsoft Bot框架一起正常工作,我计划在Bot框架中创建类似于cosmosDBPartitionedStorage类的东西 据我所见,有3种读、写和删除操作是从botbuilder存储中继承/实现的 从数据库的角度来看,在创建这个适配器时,是否有一些在阅读两层源代码时看不到的地方需要考虑。例如initialization()。这是宇宙特有的,对于我需要的解决方案,我应该如何解释它 我计划使用两个数据库,其中一个是redis。我可以在本地开发

在为上述数据库创建一个自定义适配器时,它将与Microsoft Bot框架一起正常工作,我计划在Bot框架中创建类似于cosmosDBPartitionedStorage类的东西

据我所见,有3种读、写和删除操作是从botbuilder存储中继承/实现的

从数据库的角度来看,在创建这个适配器时,是否有一些在阅读两层源代码时看不到的地方需要考虑。例如initialization()。这是宇宙特有的,对于我需要的解决方案,我应该如何解释它

我计划使用两个数据库,其中一个是redis。我可以在本地开发的Azure redis实例中测试这一点,我认为这是一个开始的好地方。因此,简而言之,这将是一个redis适配器最初


更新:我使用了一个只有Redis的集群解决方案,它是可靠的。我无法实现并发检查,因为这必须是一个服务器端脚本,我正在使用它进行CRUD操作,这将更多地涉及到v2更新

@mrichardson在下面的答案中提供的帮助对于创建您自己的数据存储非常宝贵。我也能够在我的TypeScript实现的单元测试中获得大多数重要的基本测试!除了并发性测试之外,其他所有测试都将进行

在使用Redis时,我能够创建一个适配器,该适配器通过。这是一个必须通过cmd或conf文件配置安装的Redis模块

我使用的库是,学习曲线很陡峭,不一定是他的库,但是与Redis与他的库的集成,作为一个集群和使用RedisJson模块集成是一个很好的挑战

由于使用RedisJson模块,我必须使用LUA脚本
load
EVALSHA
来执行每个CRUD操作,如果脚本未加载或由于任何原因丢失,则返回到
EVAL
。它还会在失败时重新建立脚本

我不确定在读写操作中使用EVALSHA-LUA脚本是否能获得很好的性能提升,但Redis文档似乎建议这样做

脚本的一大优点是,它能够以最小的延迟同时读取和写入数据,使得读取、计算和写入等操作非常快(在这种情况下,管道无法帮助,因为客户端需要读取命令的回复才能调用写入命令)

然而,更重要的是,我首先使用脚本的原因更多地与IORedis客户机有关。它进行管道化,但由于RedisJson命令没有本机支持,因此我必须执行自定义脚本(在IORedis中,它不允许管道化,但为您执行evalhas回退),或者创建我自己的
EVALSHA
EVAL
回退场景

似乎工作相当棒

代码库用于RedisCluster,一旦我完成了一些调整,我将通过github和npm将其作为typescript npm包发布

输入还采用TTL设置,这是消息传递应用程序(如Microsoft bot框架)的良好安全性和性能抽象

据我所见,有3种读、写和删除操作是从botbuilder存储中继承/实现的

对。这就是你真正需要的。只要你能成功地做到这些,它就会很好地工作

从数据库的角度来看,在创建这个适配器时,是否有一些在阅读两层源代码时看不到的地方需要考虑。例如initialization()。这是宇宙特有的,对于我需要的解决方案,我应该如何解释它

也对。这是宇宙特有的。基本上,它:

  • 如果数据库不存在,则创建该数据库
  • 将现有/创建的数据库存储为类的属性,以便在以后检查数据库是否存在时,只查找类属性,而不需要发出HTTP请求
  • 执行上述操作时锁定类以防止并发问题
  • 如果要在尝试任何类型的读/写之前首先检查数据库是否存在,则需要类似于
    initialization()
    函数的功能。如果您更改/添加了数据库或其他东西,那么最好使用类似于这样的东西来保护您的bot(如果您更改/添加了数据库或其他东西),但这不是必需的

    这最初是针对redis适配器的

    不幸的是,我们没有任何Redis存储适配器,但这里有一些额外的存储适配器,您可以在构建您的存储适配器时查看:

    • (不要在生产中使用)
    • (不要在生产中使用)
    在编写您的测试时,如果您想确保它正常工作,我们有一组存储基础测试供您使用。您的适配器应通过所有测试


    太棒了。只有一个问题。这与这个问题有关。当循环通过对话框并将状态写入存储时,它是否会在每次完成后覆盖该用户节点。如果我转向另一个对话框并最终完成一个对话框路径,会不会仍然发生重写,从而不会淹没节点您应该在每个回合后保存
    DialogState
    /
    ConversationState
    ,否则用户将无法完成对话框步骤。但是,在BotState中进行了一些状态缓存,以确保它仅在发生更改时写入
    UserState
    有点不同,您可以随时手动保存。您可以让分支对话框向roo返回一个值