如何检查NATS请求是否已取消

时间:2018-06-29 21:23:18

标签: go nats.io

当用户点击路线时,我会发出NATS请求,然后等待回复:

ctx := r.Context()
reply, err := natsConnection.RequestWithContext(ctx, "Subject", payload)

订阅者将执行一项资源密集型任务:

natsConnection.Subscribe("Subject", func(m *nats.Msg) {
    //do consuming task and cancel if the request was cancelled. 
    natsConnection.Publish(m.Reply, []byte("Reply"))
})

如果请求被取消,如何通知订户停止工作。

我想为工作人员收到的每条消息创建一个context,然后给发件人一个新的inbox,以等待发件人的答复,或向其发送取消通知:

contextMap := map[string]func(){}
natsConnection.Subscribe("Subject", func(m *nats.Msg) {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)

    //create new inbox
    inbox := nats.NewInbox()

    //subscribe to the new inbox and cancel and clean up the current task is something is recived
    newSub, err := natsConnection.Subscribe(inbox, func(m *nats.Msg) {
        contextMap[inbox]()
    })

    contextMap[inbox] = func() {
        fmt.Println("recived")
        cancel()
        delete(contextMap, inbox)
        newSub.Unsubscribe()
    }

    //tell the requester to wait for reply in this inbox
    natsConnection.Publish(m.Reply, []byte(inbox))

    //do the work and send the reply when finished
    tick(ctx)
    natsConnection.Publish(inbox, []byte("done"))
})

在请求者端,我发送第一个请求,并在指定的inbox中等待答复,或者取消context,在这种情况下,我向inbox发送消息让收款人知道:

ctx := r.Context()
inbox, _ := natsConnection.RequestWithContext(ctx, "Subject", []byte("Payload"))

reply := make(chan *nats.Msg, 1)
natsConnection.ChanSubscribe(string(inbox.Data), reply)

select {
case <-ctx.Done():
    fmt.Println("Canceled")
    natsConnection.Publish(string(inbox.Data), []byte(""))
    return
case r := <-reply:
    fmt.Println(string(r.Data))
}

tick只是一个勾选的函数:

func tick(ctx context.Context) {
    ticker := time.NewTicker(time.Millisecond * 500)
    for {
        select {
        case <-ctx.Done():
            ticker.Stop()
            fmt.Println("context was canceled", ctx.Err())
            return
        case <-ticker.C:
            fmt.Println("Tick")
        }
    }
}

现在这行得通,但是我想知道是否有更简单的方法来实现,或者如果不行,我该如何使这段代码更好?

2 个答案:

答案 0 :(得分:1)

如果响应非常强烈并且需要花费几秒钟的时间,那么可以发送一条单独的消息来终止请求。但是,大多数体系结构都允许响应者继续操作并丢弃结果。

答案 1 :(得分:0)

您要从取消请求中保存什么?您知道的有关请求的工作或答复的传送将不会使用?