可以使用先前的状态更新订阅消息吗?

huangapple go评论53阅读模式
英文:

Is it possible to update subscription message using previous state?

问题

假设我有这样一个订阅查询:

queryGateway.subscriptionQuery(
    FetchListOfBookQuery,
    ResponseTypes.multipleInstancesOf(Book::class.java),
    ResponseTypes.multipleInstancesOf(Book::class.java)
)

那么它将订阅数据库中的 Book 列表。如果我想要添加一个新书,我会在我的投影中有类似以下的内容:

fun on(event: BookAddedEvent){
    var book = repo.save(Book(event.bookId)).block()
    queryUpdateEmitter.emit(
        FetchListOfBookQuery::class.java, 
        { it.bookId ==  book.bookId }, 
        book
    )
}

问题在于,由于我只得到了一个新添加的 Book 实例,为了更新订阅查询,我需要同时拥有之前的 Book 列表。是否有一种方法可以获取订阅查询的先前更新状态,比较更改,最后进行更新呢?

英文:

Suppose I have this subscription query like this:

queryGateway.subscriptionQuery(
    FetchListOfBookQuery,
    ResponseTypes.multipleInstancesOf(Book::class.java),
    ResponseTypes.multipleInstancesOf(Book::class.java)
)

So, it will subscribe to list of the Books in databsae and If I want to add a new book I would have something like this in my projection:

fun on(event: BookAddedEvent){
    var book = repo.save(Book(event.bookId)).block()
    queryUpdateEmitter.emit(
        FetchListOfBookQuery::class.java, 
        { it.bookId ==  book.bookId }, 
        book
    )
}

The problem is, since I only got one instance of a new Book which has been added, in order to update to the subscription query I need to have previous list of Books as well. Is there a way to get the previous update state of the subscription query and compare changes and finally update it?

答案1

得分: 1

Axon Framework提供的Subscription Query逻辑允许您检索初始响应和更新。在代码中,这首先表现为触发一个@QueryHandler注解的方法,然后通过QueryUpdateEmitter发送更新。

被发送的内容完全取决于您。因此,如果您决定发送新添加的Book与之前的所有Book的组合,那完全可以。但正如您可能已经注意到的,QueryUpdateEmitter本身不存储更新,查询分发端的SubscriptionQueryResult也不存储更新。

因此,如果您需要逻辑来过滤掉以前更新中发送的内容,您将不得不自己构建这个逻辑。为此,您可以选择构建一个专用的逻辑部分,也许是一个服务,来执行这项工作。或者,您可以创建自己的QueryUpdateEmitter,以增强其行为以简化发送的更新内容。

我认为后者将是最清晰的方法,我建议包装SimpleQueryUpdateEmitter。然而,这可能需要相当多的自定义代码,所以我建议首先检查是否有其他方式可以满足您所提出的要求:

... 但为了更新订阅查询,我需要先获得以前的书籍列表。

如果您最终确实需要采取这个路径,那么我会很感兴趣看到结果,或者可能会提供有关此问题的建议。

这是我的建议,希望对您有所帮助,@Patrick!

英文:

The Subscription Query logic provided by Axon Framework allows you to retrieve an initial response and updates. In code, this translates itself to firstly hitting an @QueryHandler annotated method and secondly emitting the updates through the QueryUpdateEmitter.

What is being emitted is completely up to you. So if you decide to send the newly added Book in combination with all the previous Books, that is perfectly fine. As you have likely noticed though, the QueryUpdateEmitter does not store the updates itself, neither does the SubscriptionQueryResult on the query dispatching end.

Thus if you need logic to filter out what has been send with a previous update, you will have to build this yourself. To that end you could take the route of building a dedicated piece of logic, a service maybe, which does the job. Or, you could create your own QueryUpdateEmitter which enhances the behaviour to simplify the update being send.

I'd argue the latter would be the cleanest approach, for which I'd recommend wrapping the SimpleQueryUpdateEmitter. However, this could be quite some custom code, so I'd first check whether there is a different way around this requirement you are stating:

> ... but in order to update to the subscription query I need to have previous list of the books.

If you do end up on that route through bare necessity, I would be interested to see the outcome, or potentially help out with suggestions on the matter.

That's my two cents, hope this helps you out @Patrick!

huangapple
  • 本文由 发表于 2020年7月30日 14:31:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/63167409.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定