当skynet启动的时候,会依据配置文件制定的日志文件来创建一个logger context。详细过程就是找到logger.so动态链接文件。而后调用其logger_create函数(參数是配置的日志文件),而后构建这个服务相应的context(重要的是里面注冊了该服务的回调函数_logger())和消息队列,最后运行logger_init函数。把logger的消息队列放入global
queue.关键代码例如以下:
handle = skynet_handle_register(ctx);    // 注冊得到一个服务句柄
struct message_queue * queue = ctx->queue = skynet_mq_create(ctx->handle);
// init function maybe use ctx->handle, so it must init at last
context_inc(); // 这个skynet节点服务数加1 CHECKCALLING_BEGIN(ctx)
int r = skynet_module_instance_init(mod, inst, ctx, param);
CHECKCALLING_END(ctx)
if (r == 0) {
// xxx_init 成功返回。刚才的 ref-1 = 1
struct skynet_context * ret = skynet_context_release(ctx);
if (ret) {
ctx->init = true; // 初始化成功
}
// 放入全局消息队列,能够接受其它服务的消息
skynet_globalmq_push(queue);
if (ret) {
skynet_error(ret, "LAUNCH %s %s", name, param ? param : "");
}
return ret;
} else {
skynet_error(ctx, "FAILED launch %s", name);
uint32_t handle = ctx->handle;
skynet_context_release(ctx);
skynet_handle_retire(handle);
struct drop_t d = { handle };
skynet_mq_release(queue, drop_message, &d);
return NULL;
}


代码中错误处理中的skynet_error() 就是日志输出函数,会将错误字符串构造为一个skynet_mssage,放入到logger的消息队列中。msg中会保存消息的来源handle。关键代码例如以下:
struct skynet_message smsg;
if (context == NULL) {
smsg.source = 0;
} else {
// msg source 是ctx的handle号
smsg.source = skynet_context_handle(context);
}
smsg.session = 0;
smsg.data = data;
// sz低24位保存的是数据大小
smsg.sz = len | (PTYPE_TEXT << HANDLE_REMOTE_SHIFT);
// 把这个消息放到logger的队列中
skynet_context_push(logger, &smsg);



那些消息何时输出呢?skynet启动时会新起一定的worker线程,它们的工作就是消费这些消息,运行相应的回调函数,对于logger来说就是把信息输出到相应的文件句柄中。代码例如以下:
static void
_dispatch_message(struct skynet_context *ctx, struct skynet_message *msg) {
assert(ctx->init);
CHECKCALLING_BEGIN(ctx)
pthread_setspecific(G_NODE.handle_key, (void *)(uintptr_t)(ctx->handle));
int type = msg->sz >> HANDLE_REMOTE_SHIFT;
size_t sz = msg->sz & HANDLE_MASK;
// 运行节点的回调接口_cb
if (!ctx->cb(ctx, ctx->cb_ud, type, msg->session, msg->source, msg->data, sz)) {
skynet_free(msg->data);
}
CHECKCALLING_END(ctx)
}






版权声明:本文博主原创文章,博客,未经同意不得转载。

skynet源代码学习 - logger工程和服务的更多相关文章

  1. skynet源代码学习 - 从全局队列中弹出/压入一个消息队列过程

    学习云风的skynet源代码,简单记录下. void skynet_globalmq_push(struct message_queue * queue) { struct global_queue ...

  2. WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) 七 WCF服务的Windows 服务程序寄宿 这种方式的服务寄宿,和IIS一样有一个一样 ...

  3. struts2源代码学习之初始化(一)

    看struts2源代码已有一段时日,从今天開始,就做一个总结吧. 首先,先看看怎么调试struts2源代码吧,主要是下面步骤: 使用Myeclipse创建一个webproject 导入struts2须 ...

  4. Spring boot学习1 构建微服务:Spring boot 入门篇

    Spring boot学习1 构建微服务:Spring boot 入门篇 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框 ...

  5. igmpproxy源代码学习——igmpProxyInit()

    igmpproxy源代码学习--igmpProxyInit()函数详解,igmpproxy初始化 在运行igmpproxy的主程序igmpproxyRun()之前需要对igmpproxy进行一些配置, ...

  6. Asp.Net Core 3.1学习-依赖注入、服务生命周期(6)

    1.前言 面向对象设计(OOD)里有一个重要的思想就是依赖倒置原则(DIP),并由该原则牵引出依赖注入(DI).控制反转(IOC)及其容器等概念.在学习Core依赖注入.服务生命周期之前,下面让我们先 ...

  7. WCF学习之旅—WCF服务部署到应用程序(十)

    上接  WCF学习之旅—WCF寄宿前的准备(八) WCF学习之旅—WCF服务部署到IIS7.5(九) 五.控制台应用程序宿主 (1) 在解决方案下新建控制台输出项目 ConsoleHosting.如下 ...

  8. WCF学习之旅—WCF服务的WAS寄宿(十二)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一) 八.WAS宿主 IIS ...

  9. WCF学习之旅—WCF服务的批量寄宿(十三)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一) WCF学习之旅—WCF ...

随机推荐

  1. 队列优化和斜率优化的dp

    可以用队列优化或斜率优化的dp这一类的问题为 1D/1D一类问题 即状态数是O(n),决策数也是O(n) 单调队列优化 我们来看这样一个问题:一个含有n项的数列(n<=2000000),求出每一 ...

  2. 黄聪:Microsoft Enterprise Library 5.0 系列教程(二) Cryptography Application Block (初级)

    原文:黄聪:Microsoft Enterprise Library 5.0 系列教程(二) Cryptography Application Block (初级) 企业库加密应用程序模块提供了2种方 ...

  3. App域名劫持之DNS高可用 - 开源版HttpDNS方案详解(转)

      http://mp.weixin.qq.com/s?__biz=MzAwMDU1MTE1OQ==&mid=209805123&idx=1&sn=ced8d67c3e2cc3 ...

  4. 简单的刷票系统(突破IP限制进行投票) (转)

    前言 相信大家平时肯定会收到朋友发来的链接,打开一看,哦,需要投票.投完票后弹出一个页面(恭喜您,您已经投票成功),再次点击的时候发现,啊哈,您的IP(***.***.***.***)已经投过票了,不 ...

  5. BestCoder Round#11div2 1003

    ----- 有时候如果枚举起点超时,那么试试枚举终点. 枚举每一个i为终点(0<= i < n),且维护起点下标startPos 对于终点i,cnt[str[i]] ++,   如果小于等 ...

  6. MySQL和Oracle开发差异

    1)  数据类型差异 Oracle MySQL 注释 单独创建序列来实现 自动增长的数据类型 varchar2 varchar number tinyint,smallint,mediumint,in ...

  7. log(n)在第一时间,以确定该阵列i小号码

    简介参考算法9.2 int partition(int *a,int p,int r){ int x=a[r]; int i=p-1; for(int j=p;j<=r-1;j++){ if(a ...

  8. MVC @Html控件

    传统的Html元素不能和服务端数据进行绑定 HtmlHelper类提供了一系列的方法来生成Html元素 并可以实现与数据绑定在一起 然后生成Html Html.BeginForm(actionName ...

  9. ORACLE触发特定的解释

    ORACLE PL/SQL编程八: 把触发器说透 本篇主要内容例如以下: 8.1 触发器类型 8.1.1 DML触发器 8.1.2 替代触发器 8.1.3 系统触发器 8.2 创建触发器 8.2.1 ...

  10. iOS:编译错误 linker command failed with exit code 1 (use -v to see invocation)

    将project不加入.m要求加入 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzI0MzQ2OQ==/font/5a6L5L2T/fontsi ...