【问题标题】:How to implement dynamic subscribers with KDB?如何使用 KDB 实现动态订阅者?
【发布时间】:2021-02-07 07:28:41
【问题描述】:

我正在尝试在 kdb-tick 系统中实现动态订阅者,从而根据消费者提供的查询将事件的子集传递给给定的消费者。

例如给定一批事件,即:

flip `source`channel`value!(10?`a`b`c;10?`a`b`c;10?10)

source channel value
--------------------
a      a       4
b      b       5
a      c       4
b      a       2
c      c       7
c      b       8
c      a       5
a      c       6
b      a       4
b      a       1

tickerplant 应该只发送没有`c i.e.通道的事件

source channel value
--------------------
a      a       4
b      b       5 
b      a       2 
c      b       8
c      a       5 
b      a       4
b      a       1

我试图通过解析如下动态条件来实现这一点:

q).tp.subscribers

hp        | host isOpen port   h   subs
----------| --------------------------------------------------
:test:5000| test 0      5000   6   "enlist(not;(in;`channel;enlist`c))"

其中 subs 是功能选择语句的条件参数,用于以下代码:

.tp.send:{neg[x] y};

.tp.reval:{[batch;subscriber]
  .tp.send[raze .subscriber`h] reval[parse["?[batch;",raze[subscriber`subs],";0b;()]"]]
  };

// Called with event batch 
.tp.broadcast:{[batch]
   .tp.reval[batch]'[select from .tp.subscribers where isOpen] 
  };

由于批处理无法通过功能选择语句在非全局上下文中寻址而失败。 我想知道如何有效地实现此功能?

谁能给我建议或指出与此问题陈述的解决方案有关的信息。 您的建议将不胜感激。 抱歉,如果这是一个新手问题。 谢谢

【问题讨论】:

    标签: kdb


    【解决方案1】:

    我认为您期望条件参数的字符串形式这一事实是您的问题的一部分(这反过来又要求您 parse 一个字符串化的函数选择并且该解析假定为全局)。

    为什么不期望条件参数的列表形式呢?然后就不需要解析了,你可以创建一个本地函数选择。例如

    .tp.subscribers:([hp:1#`:test:5000]subs:enlist(not;(in;`channel;1#`c)))
    
    q){[batch] reval ?[batch;(0!.tp.subscribers)`subs;0b;()]}flip `source`channel`value!(10?`a`b`c;10?`a`b`c;10?10)
    source channel value
    --------------------
    a      a       4
    b      b       5
    b      a       2
    c      b       8
    c      a       5
    b      a       4
    b      a       1
    

    或者让用户指定一个 lambda 并运行它(虽然我猜在这种情况下你会失去使用 reval 的能力):

    .tp.subscribers:([hp:1#`:test:5000]subs:enlist{select from x where not channel=`c})
    
    q){[batch] @[first(0!.tp.subscribers)`subs;batch;()]}flip `source`channel`value!(10?`a`b`c;10?`a`b`c;10?10)
    source channel value
    --------------------
    a      b       9
    c      b       0
    b      b       0
    b      a       9
    b      a       3
    b      a       9
    

    【讨论】:

    • 嗨@terrylynch,感谢您的回答。这两种情况都应该是可行的,尽管如您所提到的,使用reval(考虑用户输入)会更好。有什么方法可以简洁地将 enlist(not;(in;channel;1#c)) 的字符串版本,即“enlist(not;(in;channel;1#c))”转换为 q 中的类似表示?我在使用 parse 时遇到问题,即 ?[batch;enlist(not;(in;channel;1#c));0b;()] ?[batch;parse[subs];0b;()] where subs = "enlist(not;(in;channel;1#c)) "。谢谢
    • q) parse"enlist(not;(in;channel;1#c))" = enlist (enlist;~:;(enlist;in;,channel;(#;1;,c)))
    • 我相信你应该可以value这个字符串,又名value"enlist(not;(in;`channel;enlist`c))"
    猜你喜欢
    • 2016-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-09
    相关资源
    最近更新 更多