Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

srpc与workflow如何无缝连接使用 #136

Open
heroinhell opened this issue Dec 4, 2021 · 6 comments
Open

srpc与workflow如何无缝连接使用 #136

heroinhell opened this issue Dec 4, 2021 · 6 comments
Labels
documentation Improvements or additions to documentation

Comments

@heroinhell
Copy link

heroinhell commented Dec 4, 2021

我想使用srpc做数据IO服务器,只使用workflow时,有现成的例子,照着做就行(参考http_file_server),但在使用srpc时不知道如何将workflow中的代码和srpc无缝衔接起来,具体问题描述如下:
我在server的Echo中函数体中设置了一个IO读任务,并设置了回调,代码大致如下:

void Echo(WWIORequest *request, WWIOResponse *response, srpc::RPCContext *ctx) override {
    WFFileIOTask *pread_task;
    pread_task = WFTaskFactory::create_pread_task(fd, buf, size, 0,
                                                          pread_callback);
    pread_task->user_data = response; 
}

如果参照http_file_server的代码 ,则应该将以下4行类似代码整合到Echo函数中:

pread_task->user_data = resp;   /* pass resp pointer to pread task. */
server_task->user_data = buf;   /* to free() in callback() */
server_task->set_callback([](WFHttpTask *t){ free(t->user_data); });
series_of(server_task)->push_back(pread_task);

但是,server_task在srpc的环境中是不存在的,所以有以下几个问题:
1)没有类似server_task对象,buf中的数据如何传递给pread_task的回调函数?
2)没有类似server_task对象,释放buf怎么释放?如果是使用ctx->get_series()->set_callback函数的话,在里面的lamda函数该如何写呢?
3)series_of(server_task)->push_back(pread_task);这一行在srpc语境中等效于workflow的语句是ctx->get_series()->push_back(pread_task)吗?

辛苦大佬回答。

@holmes1412
Copy link
Contributor

holmes1412 commented Dec 4, 2021

你好,这三个其实都是srpc中的series使用和上下文共享的经典问题:

  1. buf中的数据想要传给pread_task的回调,有很多种方法,比如把buf捕获到lambda中,或者把buf当作当前series的context也可以。捕获的方法如下:
pread_task = WFTaskFactory::create_pread_task(fd, buf, size, 0,
                                             [buf](WFFileIOTask *) {
                                                // 这里可以拿到捕获进来的buf指针
                                             });

设置到series上下文的做法:

ctx->get_series()->set_context(buf);
pread_task = WFTaskFactory::create_pread_task(fd, buf, size, 0,
                                             [](WFFileIOTask *task) {
                                               buf = series_of(task)->get_context();
                                             });
  1. 那么上边的两种写法同样适合第二个问题:把buf捕获进去或者设置到series的context上,这里演示下第二种写法:
ctx->get_series()->set_context(buf);
ctx->get_series()->set_callback([](const SeriesWork *series) {
                                   free(series->get_context());
                                });
  1. 你的写法ok~

@Barenboim
Copy link
Contributor

Barenboim commented Dec 4, 2021

是的呢。因为rpc里,server task用户无法直接接触到,所以,server task的信息在RPCContext里。RPCContext::get_series()就是得到server task所在的series。
如果反过来,想着http server里访问rpc,那么可以用Client::create_xxx_task的方式产生一个rpc任务,然后调用task->serialize_input的接口,序列化rpc任务,再调用series_of(http_server_task)->push_back(rpc_task)。rpc_task的user_data可以利用,done里也是通过RPCContext::get_user_data()拿回。
示例里这些用法都有。

@Barenboim
Copy link
Contributor

workflow里http_file_server示例用server_task的user_data存buf,不是一个很好的方法。rpc server task的user_data好像用户无法利用。所以,你可以利用series context来存放数据,或用fileio_task的user_data似乎也可以。

@heroinhell
Copy link
Author

感谢!非常详尽!

@heroinhell
Copy link
Author

感谢指导,get_series()和workflow自己还没理解特别清楚,不能流畅的使用。
自己再好好研究一下所有的示例和源码。

@Barenboim
Copy link
Contributor

我觉得你理解得挺对的啊:)总之就是一切运行中的task一定处于某个series,server task也不例外。rpc task的series是通过ctx->get_series()得到的。

@Barenboim Barenboim added the documentation Improvements or additions to documentation label Dec 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

3 participants