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参考的更多相关文章

  1. Google地图接口API之Google地图 API 参考手册(七)

    Google 地图API 参考手册 地图 构造函数/对象 描述 Map() 在指定的 HTML 容器中创建新的地图,该容器通常是一个DIV元素. 叠加层 构造函数/对象 描述 Marker 创建一个标 ...

  2. Google Chart API 参考 中文版

    Google Chart API 参考 中文版 文档信息 翻译: Cloudream ,最后修改:02/22/2008 06:11:08 英文版版权归 Google , 转载此中文版必须以链接形式注明 ...

  3. Zepto Api参考

    zepto API参考 简介 Zepto是一个轻量级的针对现代高级浏览器的JavaScript库, 它与jquery有着类似的api. 如果你会用jquery,那么你也会用zepto. 设计目的 ze ...

  4. PJSUA2开发文档--第十二章 PJSUA2 API 参考手册

    12 PJSUA2 API 参考手册 12.1 endpoint.hpp PJSUA2基本代理操作.  namespace pj PJSUA2 API在pj命名空间内. 12.1.1 class En ...

  5. Dubbo -- 系统学习 笔记 -- API参考手册

    Dubbo -- 系统学习 笔记 -- 目录 API参考手册 配置API 注解API 模型API 上下文API 服务API API参考手册 Dubbo的常规功能,都保持零侵入,但有些功能不得不用API ...

  6. nvGRAPH API参考分析(二)

    nvGRAPH API参考分析(二) nvGRAPH Code Examples 本文提供了简单的示例. 1. nvGRAPH convert topology example void check( ...

  7. nvGRAPH API参考分析(一)

    nvGRAPH API参考分析(一) 本文通过描述nvGRAPH库函数的输入/输出参数,数据类型和错误代码来指定其行为. 1.    返回值nvgraphStatus_t 除以下内容外,所有nvGRA ...

  8. Django,数据模型创建之数据库API参考(转载)

    一旦 数据模型 创建完毕, 自然会有存取数据的需要.本文档介绍了由 models 衍生而来的数据库抽象API,及如何创建,得到及更新对象. 贯穿本参考, 我们都会引用下面的民意测验(Poll)应用程序 ...

  9. 阿里云API网关(7)开发指南-API参考

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

随机推荐

  1. [Linked List]Convert Sorted List to Binary Search Tree

    Total Accepted: 57775 Total Submissions: 198972 Difficulty: Medium Given a singly linked list where ...

  2. Visual Studio宏注释模板

    前言 有时写代码需要写注释的时候 甚是苦恼 写吧 怕麻烦 不写吧 似乎这代码估计自己都看不懂 权衡之下 似乎找一个自动写注释的方法最靠谱 一直在VS下开发 偶尔听人说过有一个宏工具可以帮助开发者快速注 ...

  3. 求double类型的n次方

    剑指offer系列面试题 package com.study; /* * 数值的整数次方 * 要求:实现函数 double Power(double base, int exponent) 求base ...

  4. optimize table 表优化问题

    语法: optimize table '表名' 一,原始数据 1,数据量 2,存放在硬盘中的表文件大小 3,查看一下索引信息 索引信息中的列的信息说明. Table :表的名称.Non_unique: ...

  5. Java程序读取tomcat下的properties配置文件

    代码如下: //找到tomcat/etc/wx文件夹    private static String getPropFolderPath()    {  /* Properties p = Syst ...

  6. Android进程

    android进程等级 1.前台进程 2.可视进程 3.服务进程 4.后台进程 5.空进程 让应用退出方式 finish();让应用成为空进程 Process.killProcess();杀进程 sy ...

  7. 如何用EXCEL表计算今天是本年的第几周?

    单元格内输入如下代码计算出来的数字即是当日在本年度的第几周,如下: =INT((TODAY()-DATE(YEAR(TODAY()),1,1)-WEEKDAY(DATE(YEAR(TODAY()),1 ...

  8. javascript中可处理的浮点数的最高精度(和小数的一些小特性)

    1.之前在度娘那找了一下关于javascript中可处理的浮点数的最高精度的问题,但找了好久也找不到,于是自己 小小的研究了一下,之前以为是17,后来测到18,再后来又测到19,经过一系列的改写,得到 ...

  9. ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小 错误分析

    目录(?)[+] 1. 问题起因 最近在进行Oracle的一些操作时,总会遇到这个错误:  ORA-06502: PL/SQL: 数字或值错误 :  字符串缓冲区太小,错误如下: ORA-00604: ...

  10. Oracle EBS-SQL (BOM-14):检查工艺路线明细.sql

    select msi.segment1                                         装配件编码,       msi.description             ...