skynet newservice API参考
local skynet = require("skynet")
skynet.start(start_func)
c服务snlua启动后执行的第一个lua文件里面的主逻辑必定是skynet.start(start_func),由此开始运行lua服务的逻辑
start_func是当前lua服务的初始化函数,也是当前服务的第一个协程的函数
之后在收到非response消息时dispatch_message会创建更多的协程来做逻辑
而调用skynet.start(start_func)的主线程会调度上述这些协程(yield)
dispatch_message(...)
这就是ctx的消息处理函数(skynet_context.skynet_cb, 返回零(假)时释放消息的内存.那么lua层如何控制呢?c.callback(dispatch_message,false)就是释放内存,c.callback(dispatch_message,true)不释放内存,具体参见vim -t _callback.那么lua层如何控制发消息时不做复制呢?我看skynet.send/call/rawcall都不支持对复制的控制,参见vim -t _send. 底层的默认处理是:对于Lua string直接复制,对于lightuserdata不复制,对于其他类型报错)
dispatch_message将是本服务的发动机(消息驱动机),也就是底层工作线程拿到本服ctx.mq中的一个消息后执行的消息处理函数(vim -t _dispatch_message, 底层由worker thread取到消息后调用这个函数而触发lua函数的调用),也就是本lua服的主线程(虽然线程ID不固定)
dispatch_message每处理完mq中的一个消息都要遍历并执行消息处理过程中fork而没运行的新协程(遍历fork_queue并coroutine.resume())
对于收到的每个非response(prototype!=skynet.PTYPE_RESPONSE)消息启动一个新协程X,用该协程来运行协议类型对应的dispatch函数来处理消息
对于收到的每个response消息,根据session从session_id_coroutine取出协程并恢复执行
协程X运行业务逻辑时可能会“对其他服务做请求并等待结果”或者“睡眠几秒”,这时协程X用yield抛出“CALL”/“SLEEP”等返回值并挂起,主线程根据yield抛出的值对协程做不同处理
CALL -> 协程X已对其他服务发出请求并等待回应 -> 主线程把协程X记录到session_id_coroutine中,下次收到对应的response消息(sessionID一致)时唤醒
SLEEP -> 协程X[已调用skynet.sleep(ti)等定时器返回]或[已调skynet.wait()等其他服务返回,这种情况一般需要用skynet.wakeup()来唤醒,否则协程可能永远沉睡下去了] -> 主线程把协程X记录到session_id_coroutine,并记录sleep_session,对于sleep_session需要用skynet.wakeup(co)唤醒 (session_id_coroutine和sleep_session两者怎么维持数据一致,这个细节还需要结合实例再看看 markbyxds )
skynet.newservice(name,...)
创建lua服务 skynet.rawcall(".launcher", "lua" , skynet.pack("LAUNCH", "snlua", name, ...))
其实是skynet_context_new(module_name("snlua"), param("cmaster"))
即,用snlua服跑着一个lua逻辑服(service/cmaster.lua),snlua创造了一个lua环境的沙盒
除了service/launch.lua自身以外,其他lua服务一般都是由service/launch.lua这个lua服负责创建的
当然,launch服最终还是调用的skynet.launch("snlua","xxx")来创建服务
skynet.launch
创建c服务, lualib-src/lua-skynet.c -> skynet_command(CTX,"LAUNCH",..) -> skynet_context_new(mod,args)
对于skynet.launch("snlua","xxx"),这是创建c服务snlua然后在它上面跑lua服务xxx
skynet.monitor(service, query) 监控服务退出,细节还没仔细看 markbyxds
skynet.uniqueservice(global,...)
创建一个唯一的服务,调用多次service/***.lua也只启一个实例,比如clusterd和multicastd
global=true时,在所有节点之间是唯一的
其实是用skynet.call(异步变同步)的方式让service_mgr服务创建目标服务(类似于通知launch服创建服务一样)
service_mgr这边如已创建则直接返回服务地址;如没则创建;如正在创建则等结果
skynet.queryservice(global,...) global=true时
如果还没有创建过目标服务则一直等下去,直到目标服务被(其他服务触发而)创建
skynet.rawcall
向目标服发送无协议的消息并返回response,协程挂起等返回,用同步代码的样式实现异步逻辑
当 A call B 时,如果 B 在回应前就退出了,A 会收到一条异常,并正确的传播到 A 里的 call 调用处;
当 A call B ,而 B 在回应前,A 自己退出了,B 也会收到一条异常,提示 A 已经不在了。但不会影响 B 的执行流程,只是让框架回收一些必要的相关资源。
skynet.call 跟skynet.rawcall的区别是向目标服发送指定协议的消息
skynet.send 跟skynet.call的区别是仅仅发消息而已,不关心返回值也不会让当前协程挂起(非request-response模式)
skynet.wait()
把当前协程挂起放入session_id_coroutine/sleep_session
当收到等待的消息(会把消息对应的正在等待session放入wakeup_session中)后该协程恢复执行
skynet.sleep(ti)
类似于skynet.wait(),只是要事先通知底层定时器
等定时器(在ti时间达到后)发来消息时该协程恢复执行
skynet.wakeup(co)
如果协程co正处于挂起等待的状态(在sleep_session中)则把它加入wakeup_session
本服务的主协程会在调度过程中把wakeup_session中的协程唤醒执行
skynet.ret 在当前协程(为处理请求方消息而产生的协程)中给请求方(消息来源)的消息做回应
skynet.retpack 跟skynet.ret的区别是向请求方作回应时要用skynet.pack打包
skynet.register_protocol
注册协议:
协议名(name)
协议ID(id)
发送消息的打包函数(pack)
接收消息的拆包函数(unpack)
接收消息的(分发)处理函数(dispatch)
已注册的协议记录在lualib/skynet.lua:proto这个数据结构上
每个服务会默认初始化lua/response/error这几种协议
skynet.dispatch(typename, func)
修改以typename为协议名的协议:用func这个函数来作为协议的dispatch函数(默认的lua协议没提供dispatch,需要使用者根据业务需要写)
skynet.fork
创建一个新的协程
这里有做协程对象池来加速,类似于我们项目中的线程池,创建一堆协程并挂起,接到业务后拿协程跑业务逻辑
skynet.register(name)
注册当前服务的名字(默认用:%x作为name,本地服务的自定义名以.打头)
把<handleId + name>记录到handle_storage->name,参数必须符合本地服务的命名规范
skynet.self() 返回当前服务的handleID,如果还没注册就先注册(类似于skynet.register)
skynet.harbor(addr) return “addr(ctx的handleID)对应的harborID",boolean(是否远端节点)
skynet.address(addr) return "addr(ctx的handleID或者name)对应的name(string,:%x或者自定义名)"
skynet newservice API参考的更多相关文章
- Google地图接口API之Google地图 API 参考手册(七)
Google 地图API 参考手册 地图 构造函数/对象 描述 Map() 在指定的 HTML 容器中创建新的地图,该容器通常是一个DIV元素. 叠加层 构造函数/对象 描述 Marker 创建一个标 ...
- Google Chart API 参考 中文版
Google Chart API 参考 中文版 文档信息 翻译: Cloudream ,最后修改:02/22/2008 06:11:08 英文版版权归 Google , 转载此中文版必须以链接形式注明 ...
- Zepto Api参考
zepto API参考 简介 Zepto是一个轻量级的针对现代高级浏览器的JavaScript库, 它与jquery有着类似的api. 如果你会用jquery,那么你也会用zepto. 设计目的 ze ...
- PJSUA2开发文档--第十二章 PJSUA2 API 参考手册
12 PJSUA2 API 参考手册 12.1 endpoint.hpp PJSUA2基本代理操作. namespace pj PJSUA2 API在pj命名空间内. 12.1.1 class En ...
- Dubbo -- 系统学习 笔记 -- API参考手册
Dubbo -- 系统学习 笔记 -- 目录 API参考手册 配置API 注解API 模型API 上下文API 服务API API参考手册 Dubbo的常规功能,都保持零侵入,但有些功能不得不用API ...
- nvGRAPH API参考分析(二)
nvGRAPH API参考分析(二) nvGRAPH Code Examples 本文提供了简单的示例. 1. nvGRAPH convert topology example void check( ...
- nvGRAPH API参考分析(一)
nvGRAPH API参考分析(一) 本文通过描述nvGRAPH库函数的输入/输出参数,数据类型和错误代码来指定其行为. 1. 返回值nvgraphStatus_t 除以下内容外,所有nvGRA ...
- Django,数据模型创建之数据库API参考(转载)
一旦 数据模型 创建完毕, 自然会有存取数据的需要.本文档介绍了由 models 衍生而来的数据库抽象API,及如何创建,得到及更新对象. 贯穿本参考, 我们都会引用下面的民意测验(Poll)应用程序 ...
- 阿里云API网关(7)开发指南-API参考
网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...
随机推荐
- delphi按钮控件的default属性
delphi按钮控件的default属性用于设置默认命令按钮,.设置为true时,按[Enter键]相当于用鼠标单击了该按钮 .窗口中如果有多个按钮的default是true的话,就根据tabinde ...
- AngularJS之Factory vs Service vs Provider
原文 http://www.linuxeden.com/html/news/20140509/151538.html 当你初试 Angular 时,很自然地就会往 controller 和 scop ...
- 纯css改变下拉列表select框的默认样式
下列CSS就可以解决,原理是将浏览器默认的下拉框样式清除,然后应用上自己的,再附一张向右对齐小箭头的图片即可. select { /*Chrome和Firefox里面的边框是不一样的,所以复写了一下* ...
- %hd %d %ld %u ......
%d 有符号10进制整数 %ld 长整型 %hd短整型%md,m指定的是输出字段的宽度,默认左补空格, 如果数据的位数小于m,则左端补以空格,若大于m,则 按实际位数输出,如: printf(&quo ...
- 资源回收 left
select DISTINCT human.tid,log_pv_change.systafftid from human left join human_user on human.tid=huma ...
- python学习day12
目录 html结构与标签 css样式 html结构之head <head> 标签用于定义文档的头部,它是所有头部元素的容器.<head> 中的元素可以引用脚本.指示浏览器在 ...
- 一个失误导致微信下载图片接口Token失效
公司的应用调了一个微信上传下载图片的接口,本来在线上跑的好好的,什么问题没有,但是这两天总是不定时的出现下载下来的图片损坏,拿着Token和serverid去接口测试网页验证,返回的是Token失效了 ...
- MySQL 5.6 中 TIMESTAMP 的变化
http://www.williamsang.com/archives/818.html
- 开源日志库log4cplus+VS2008使用
一.简介 log4cplus是C++编写的开源的日志系统,功能非常全面.本文介绍如何在Windows+VS2008中使用该日志库. 二.下载 可从网站[url]http://log ...
- C# 线程池异步调用
许多应用程序使用多个线程,但这些线程经常在休眠状态中耗费大量的时间来等待事件发生.其他线程可能进入休眠状态,并且仅定期被唤醒以轮询更改或更新状态信息,然后再次进入休眠状态.为了简化对这些线程的管理,. ...