如何使用 KDB 实现动态订阅者?
How to implement dynamic subscribers with KDB?
我正在尝试在 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 通道的事件,即
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 是以下代码中使用的功能性 select 语句的条件参数:
.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]
};
由于批处理无法通过功能性 select 语句在非全局上下文中寻址,因此失败。
我想知道如何有效地实现此功能?
任何人都可以给我建议或指出与此问题陈述的解决方案有关的信息。
非常感谢您的建议。
如果这是一个新手问题,我们深表歉意。
谢谢
我认为您期望条件参数的字符串形式这一事实是您问题的一部分(这反过来又要求您 parse
一个字符串化的函数 select 并且解析假设全球)。
为什么不期待条件参数的列表形式呢?然后就不需要解析了,你可以创建一个本地功能select。例如
.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
我正在尝试在 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 通道的事件,即
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 是以下代码中使用的功能性 select 语句的条件参数:
.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]
};
由于批处理无法通过功能性 select 语句在非全局上下文中寻址,因此失败。 我想知道如何有效地实现此功能?
任何人都可以给我建议或指出与此问题陈述的解决方案有关的信息。 非常感谢您的建议。 如果这是一个新手问题,我们深表歉意。 谢谢
我认为您期望条件参数的字符串形式这一事实是您问题的一部分(这反过来又要求您 parse
一个字符串化的函数 select 并且解析假设全球)。
为什么不期待条件参数的列表形式呢?然后就不需要解析了,你可以创建一个本地功能select。例如
.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