pomelo源码解析之模块解析(一)

pomelo是网易基于Node.js实现的一套完整的服务器引擎。

官方中文wiki:https://github.com/NetEase/pomelo/wiki/Home-in-Chinese

最近开始使用该引擎,做一个源码阅读的笔记

 

学习pomelo源码之前还需要学习一下Node.js的基础知识

http://nodejs.cn/api/modules.html 官方文档,可以先学一下Node.js的加载模块机制

 

一、根据官方wiki安装pomelo

       https://github.com/NetEase/pomelo/wiki/%E5%AE%89%E8%A3%85pomelo

二、创建一个pomelo项目

      https://github.com/NetEase/pomelo/wiki/pomelo%E7%9A%84HelloWorld

三、开始正式分析pomelo的一些基础模块

     game-server中的文件目录如下:

     在node_modules中找到pomelo模块


这里先分析一些简单模块:

  • pomelo-loader

源码路径就在lib下,可以看到只有一个文件,非常简单。

这个模块的功能就是加载一个文件夹下(不递归)的所有js文件,并返回以名字做key,模块做value的一个map

记载的时候会清除掉require中相应的模块缓存

  • pomelo-logger

基于log4js的一个日志系统

https://github.com/log4js-node/log4js-node

  • pomelo-protocol

将字串封装为byte数组。两种封装方式Package和Message。数组前几个字节有特定意义,也规定好了消息类型。

详见代码pomelo-protocol/lib/protocol.js

  • pomelo-scheduler

调度器。根据传入的时间开启任务,根据间隔执行任务,可以设置执行次数

pomelo-scheduler/README.md 有详细使用方法

使用方式schedule.scheduleJob 第一个参数支持两种形式

1)  简单模式 simpleTrigger.js // 按毫秒的间隔执行一定次数

入参为 object = {

             start: number, // Date.now(); 毫秒

              period: number, // 执行粒度 毫秒

              count: number, // 执行次数 -1就是无限次数

              };

     

2)   复杂模式 cronTrigger.js // 按所传参数区间最小间隔执行

   入参为字符串 支持格式'xx xx xx xx xx xx' // 年月日时分秒用空格隔开

   每一个字段中 ,代表包含 -代表范围 /代表间隔 a/b:从a开始间隔b

   入参: '2018 12 1/3 20 15,16-20,50 20'

   解释: 2018年12月(1,4,7,10,13,16,19,22,25,28,31)日20时(15,16,17,18,19,20,50)分20秒

   最终存入cronTrigger中的cronTimes中:

   cronTrigger = [

              [2018],

              [12],

              [1,4,7,10,13,16,19,22,25,28,31],

              [20],

              [15,16,17,18,19,20,50],

              [20]

         ];

 

schedule.js内部的任务队列priorityQueue是一个最小堆队列

查看schedule.js源码可以发现,只会对任务列表中最靠前的设置一个定时器

在schedule.js中的excuteJob中处理具体任务。当执行一个任务时会做一个判断

           

默认是10ms,也就是每次执行时会查找当前任务队列中10ms之内要执行的任务并执行

考虑到函数调用开销等,这里无法做到毫秒级的精确。

 设置accuracy=0之后,setTimeout参数还可能为负,这里做个简单测试:

setTimeout(() => {
    console.log('-10 : ', Date.now());
}, -10);

setTimeout(() => {
    console.log('0 : ', Date.now());
}, 0);

setTimeout(() => {
    console.log('1 : ', Date.now());
}, 1);

setTimeout(() => {
    console.log('2 : ', Date.now());
}, 2);

setTimeout(() => {
    console.log('10 : ', Date.now());
}, 10);

setTimeout(() => {
    console.log('100 : ', Date.now());
}, 100);

输出结果如下:

可以发现setTImeout本身就有一些毫秒级的损失,所以这里的10ms检测对调度的影响不大,已经实现了秒级的精确,足够应对游戏服务器的日常使用

猜你喜欢

转载自blog.csdn.net/qq_37543025/article/details/85222101