加入 CCR 中的 PortSet

发布于 2024-09-18 21:04:16 字数 432 浏览 0 评论 0原文

我有 4 个服务,每个服务都有一个具有如下签名的方法:

PortSet<Response1, Exception> GetData1(Request1 request);
PortSet<Response2, Exception> GetData2(Request2 request);
PortSet<Response3, Exception> GetData3(Request3 request);
PortSet<Response4, Exception> GetData4(Request4 request);

我需要同时运行它们,并分别连接来自每个端口的最终结果、处理结果和异常。你能建议我该怎么做吗?

我只能找到加入来自 Port 的结果的可能性,而不是来自 PortSet 的结果。

谢谢

I have 4 services, each has a method with the signature like this:

PortSet<Response1, Exception> GetData1(Request1 request);
PortSet<Response2, Exception> GetData2(Request2 request);
PortSet<Response3, Exception> GetData3(Request3 request);
PortSet<Response4, Exception> GetData4(Request4 request);

I need to run them concurrently and join the final result, processing result and exception that comes from each port separately. Could you please suggest how do I do this?

I was able to find only possibility to join the results from the Port's, not from PortSet's.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我们的影子 2024-09-25 21:04:16

您的解决方案在某种程度上受到所涉及的类数量的限制。我建议在每个 PortSet 上激活 Choice 接收器,并在每个处理程序中激活 Post 到完成端口。在完成端口上,当它们全部完成时,您可以使用Join。所以,我突然想到,假设您是从CcrServiceBase派生的(否则您将需要使用 Arbiter.Activate 而不是简洁的 Activate):

var cPort=new Port<EmptyValue>();
Activate(GetData1(myRequest1)
    .Choice(r1=>{
        Process(r1);
        cPort.Post(EmptyValue.SharedInstance);
    },ex=>{
        Process(ex);
        cPort.Post(EmptyValue.SharedInstance);
    }); //etc 4 times

Activate(cPort.Join(4,e=>{
    //all completed. Proceed here...
}));

如果您有一个通用的 Response 类型,则可以将您的调用构造为如下所示:

var PortSet<Response,Exception> ps=new PortSet<Response,Exception>();
GetData1(request1,ps);
GetData2(request2,ps);
GetData3(request3,ps);
GetData4(request4,ps);

因此,您无需使用 GetData 调用创建新的 PortSet,而是提供一个通用的 PortSet 并将其提供给 GetData方法。

现在,您可以执行多项接收:

ps.MultipleItemReceive(4,
    responses=> {
        foreach(var response in responses)
        {
            //process response
        }
    },
    exceptions=> {
        foreach(var exception in exceptions)
        {
            //process exception
        }
    })

Your solution is somewhat limited by the number of classes involved. I'd suggest activating Choice receivers on each PortSet, and in each handler to Post to a completion port. On the completion port, you could use a Join when they all complete.So, off the top of my head, and assuming you are deriving from CcrServiceBase (otherwise you'll need to use Arbiter.Activate instead of the terser Activate):

var cPort=new Port<EmptyValue>();
Activate(GetData1(myRequest1)
    .Choice(r1=>{
        Process(r1);
        cPort.Post(EmptyValue.SharedInstance);
    },ex=>{
        Process(ex);
        cPort.Post(EmptyValue.SharedInstance);
    }); //etc 4 times

Activate(cPort.Join(4,e=>{
    //all completed. Proceed here...
}));

If instead you had a common Response type, you could instead structure your calls as follows:

var PortSet<Response,Exception> ps=new PortSet<Response,Exception>();
GetData1(request1,ps);
GetData2(request2,ps);
GetData3(request3,ps);
GetData4(request4,ps);

so instead of the GetData call creating a new PortSet, you provide a common PortSet and supply it to the GetData methods.

Now, you can perform a multiple item receive:

ps.MultipleItemReceive(4,
    responses=> {
        foreach(var response in responses)
        {
            //process response
        }
    },
    exceptions=> {
        foreach(var exception in exceptions)
        {
            //process exception
        }
    })
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文