代码拉取完成,页面将自动刷新
Workflow的一个重要功能就是通讯与计算的结合。搜索引擎许多后端服务都是复杂的计算通讯结合的应用。协调好计算与通讯的关系,对于我们实现高性能服务至关重要。这个示例里,我们使用一种最为简单的计算任务呢,go任务,来实现一个计算型http server。server的功能是计算出第n个斐波那契数,并把整个计算过程返回给client。
#include <stdio.h>
#include <string.h>
#include "workflow/WFHttpServer.h"
void Fibonacci(int n, protocol::HttpResponse *resp)
{
unsigned long long x = 0, y = 1;
char buf[256];
int i;
if (n <= 0 || n > 94)
{
resp->append_output_body_nocopy("<html>Invalid Number.</html>",
strlen("<html>Invalid Number.</html>"));
return;
}
resp->append_output_body_nocopy("<html>", strlen("<html>"));
for (i = 2; i < n; i++)
{
sprintf(buf, "<p>%llu + %llu = %llu.</p>", x, y, x + y);
resp->append_output_body(buf);
y = x + y;
x = y - x;
}
if (n == 1)
y = 0;
sprintf(buf, "<p>The No. %d Fibonacci number is: %llu.</p>", n, y);
resp->append_output_body(buf);
resp->append_output_body_nocopy("</html>", strlen("</html>"));
}
void process(WFHttpTask *task)
{
const char *uri = task->get_req()->get_request_uri();
if (*uri == '/')
uri++;
int n = atoi(uri);
protocol::HttpResponse *resp = task->get_resp();
WFGoTask *go_task = WFTaskFactory::create_go_task("fib", Fibonacci, n, resp);
series_of(task)->push_back(go_task);
}
int main()
{
WFHttpServer server(process);
if (server.start(8888) == 0)
{
getchar();
server.stop();
}
return 0;
}
这个例子里我们用create_go_task产生一个最简单的计算任务。其中第一个参数是一个字符串,代表计算任务所在队列名。一般来讲同一种计算任务用一个队列名就可以(关于计算队列更多的知识请查看FAQ)。第二个参数是函数名,之后是函数的参数列表。go task的callback默认为空,但用户同样可以通过set_callback接口给go task设置一个callback。和之前两个示例类似,我们向server任务所在series添加一个任务,但这次我们添加的是一个计算任务。
默认情况下,框架产生一个与主机CPU数相同的计算线程用于执行计算任务,并且,我们有非常精巧的算法,来保证计算调度的高效与合理,一切都是通过一个计算队列名来解决。
现在通过浏览器输入URL:http://127.0.0.1:8888/n ,就可以看到Fibonacci的计算过程了(n的范围在1到94之间)。
大家会发现,如果我们只使用go task,整个WF框架退化成一个线程池。而通过计算队列名与series,我们又可实现了线程任务的调度控制与任务之间的依赖。
登录 后才可以发表评论