`
white_crucifix
  • 浏览: 96663 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Ghost blog 源码分析(一)Config

阅读更多
    Ghost blog的由来,曾经有位wordpress的兄弟,觉得wordpress越来越不简洁,一气之下跑出来自创门户,于是诞生了一个新的开源博客系统ghost,用时下非常时髦的Node.js编写,前几天刚刚发布,一时间赚足眼球。主页在这 https://ghost.org/ ,然后很奇葩的在官方论坛上发现好多中国同学发中文贴,虽然没什么不对,不过总觉得有些违和感。
    闲来无事就download了源码看了下,顺便也学习下Node,一直以来看到的Node的资料都是各种入门材料,这次有大神的源码就很乐呵的读一下。
    看了俩文件,比较简单,随便写一下
    整个blog系统启动入口是index.js,而index.js里主要就是调用了load config相关的方法。
configLoader.loadConfig().then(function () {
    // The server and its dependencies require a populated config
    require('./core/server');
}).otherwise(error.logAndThrowError);

所以就进入loadConfig方法实现去看一下,是在core/目录下的config-loader.js文件,内部主要有三个方法,两个private方法writeConfigFile 和 validateConfigEnvironment, 以及一个public方法loadConfig,因此index.js调用的就是这个public方法。
    先说明一下两个private方法。
function writeConfigFile() {
    var written = when.defer();
    /* Check for config file and copy from config.example.js
        if one doesn't exist. After that, start the server. */
    fs.exists('config.example.js', function checkTemplate(templateExists) {
        var read,
            write;
        if (!templateExists) {
            return errors.logError(new Error('Could not locate a configuration file.'), process.cwd(), 'Please check your deployment for config.js or config.example.js.');
        }
        // Copy config.example.js => config.js
        read = fs.createReadStream('config.example.js');
        read.on('error', function (err) {
            return errors.logError(new Error('Could not open config.example.js for read.'), process.cwd(), 'Please check your deployment for config.js or config.example.js.');
        });
        read.on('end', written.resolve);
        write = fs.createWriteStream('config.js');
        write.on('error', function (err) {
            return errors.logError(new Error('Could not open config.js for write.'), process.cwd(), 'Please check your deployment for config.js or config.example.js.');
        });
        read.pipe(write);
    });

    return written.promise;
}

    该方法作用是将一份模板配置文件config.example.js的内容写进系统所需的config.js中,防止不存在config.js,特别是第一次启动时是不存在config.js的。另外你也可以手动创建config.js。当然如果你两个文件都没有……那也不行
    具体实现,使用到了node的file system模块fs,基本的读/写流
   
function validateConfigEnvironment() {
    var envVal = process.env.NODE_ENV || 'undefined',
        hasHostAndPort,
        hasSocket,
        config,
        parsedUrl;
    try {
        config = require('../config')[envVal];
    } catch (ignore) {

    }

    // Check if we don't even have a config
    if (!config) {
        errors.logError(new Error('Cannot find the configuration for the current NODE_ENV'), "NODE_ENV=" + envVal, 'Ensure your config.js has a section for the current NODE_ENV value');
        return when.reject();
    }

    // Check that our url is valid
    parsedUrl = url.parse(config.url || 'invalid');
    if (!parsedUrl.protocol || !parsedUrl.host) {
        errors.logError(new Error('Your site url in config.js is invalid.'), config.url, 'Please make sure this is a valid url before restarting');
        return when.reject();
    }

    // Check that we have database values
    if (!config.database) {
        errors.logError(new Error('Your database configuration in config.js is invalid.'), JSON.stringify(config.database), 'Please make sure this is a valid Bookshelf database configuration');
        return when.reject();
    }

    hasHostAndPort = config.server && !!config.server.host && !!config.server.port;
    hasSocket = config.server && !!config.server.socket;
    // Check for valid server host and port values
    if (!config.server || !(hasHostAndPort || hasSocket)) {
        errors.logError(new Error('Your server values (socket, or host and port) in config.js are invalid.'), JSON.stringify(config.server), 'Please provide them before restarting.');
        return when.reject();
    }

    return when.resolve();
}

   该方法用来检验配置文件的合法性,检验host&port和socket至少得有一项,以满足服务访问需求。

   这两个方法本身逻辑很简单,不过其中有一个东西比较特殊,那就是when模块的使用。简单介绍一下,when模块主要用来实现更简洁的同步编程。我们都知道,在nodejs里绝大部分方法都是异步执行的,如果你需要两个方法顺序的同步执行,就必须将方法B作为参数出入方法A中,作为回掉函数。如此一来,复杂的逻辑会使得代码的嵌套极为凶残。很多人都提供了一些同步代码编写的工具,其中when就是一个。
   于是我们结合第一个方法来看一下when的用法。首先需要定义一个defer变量,var written = when.defer();当read结束,即end事件触发时,会执行written.resolve(),resolve表示执行成功,暂时理解为是一个成功标志。方法的最后需要返回written.promise;。那么这个resolve有什么作用呢,请看第三个方法
exports.loadConfig = function () {
    var loaded = when.defer();
    /* Check for config file and copy from config.example.js
        if one doesn't exist. After that, start the server. */
    fs.exists('config.js', function checkConfig(configExists) {
        if (configExists) {
            validateConfigEnvironment().then(loaded.resolve).otherwise(loaded.reject);
        } else {
            writeConfigFile().then(validateConfigEnvironment).then(loaded.resolve).otherwise(loaded.reject);
        }
    });
    return loaded.promise;
};


writeConfigFile().then(validateConfigEnvironment),也就是说,当resolve后,就会继续执行then传入的方法。代码风格上写成链式,当然要比传参更直观。那么除了执行成功,必然还有执行失败,即reject方法。参考validateConfigEnvironment方法,凡是判断配置invalid后,都会执行when.reject(),然后会怎么样呢,表面上看似乎应该进入otherwise而不是then,这样也很明了。但事实上它依然会进入then方法。这是为什么呢,因为then方法有三个参数,其中前两个就是resolve及reject后的回掉函数,哪种结果就调用哪种回掉函数。而上文中的then只提供了一个参数即第一个参数,所以可以理解为执行成功后续。同时,otherwise方法其实是then的一个变种,即不提供第一个参数的then方法,因此可以理解为执行失败后续。

   when了解以后,最后来过loadConfig方法,首先判断配置文件是否存在,存在就直接判断合法性最后判断状态resolve还是reject,不存在就先拷贝再验证合法性,最后也要判断状态。这里最后达成的状态作用于index.js的调用。成功继续加载server,错误就结束系统。

   加载配置的逻辑基本就是这样了
分享到:
评论
2 楼 white_crucifix 2013-10-27  
是的,它的介绍就是A lightweight Promises/A+ and when() implementation, plus other async goodies.
1 楼 lzyzsd 2013-10-27  
其实就是js中的promise的实现,写起来比callback hell可读性要好很多

相关推荐

    ghost 3.6 源码 VC6.0+SDK

    《Ghost 3.6 源码分析与VC6.0+SDK开发环境搭建》 Ghost,全称为General Hosted Object-Oriented Software Toolkit,是一款著名的软件开发工具,尤其在系统克隆、备份和恢复领域有着广泛的应用。Ghost 3.6版本的源码...

    ghost远控源码详讲2

    【标题】:Ghost远控源码详讲2 在IT领域,远程控制软件是一种非常重要的工具,它允许用户在一个设备上操作另一个设备,仿佛亲临其境。Ghost远控是其中的经典代表,深受程序员和安全研究人员的喜爱。对于那些希望...

    功能完善的Ghost3.6源码

    Ghost3.6源码是基于开源项目Ghost的一款高级版本,Ghost是一个流行的开源博客平台,以其简洁的Markdown编辑器和响应式设计而闻名。这个3.6版本进一步增强了其功能性和稳定性,为用户提供了更加完善的博客发布和管理...

    Ghost远控源码免杀详讲

    Ghost远控软件,作为一款知名的RCS,其源码分析与免杀技术是黑客与安全研究人员关注的焦点。免杀技术,即防止反病毒软件检测到恶意软件的技术,对于理解网络犯罪的手段和防御策略具有重要意义。 1. Ghost远控软件...

    ghost3.75源码

    "Ghost 3.75源码"是一个针对老版本Ghost软件的开源代码集合,这个版本在IT领域中具有一定的历史意义。Ghost,全称为“Ghost for Windows”,最初由Symantec公司开发,是一款广泛用于系统备份与恢复的工具。Ghost ...

    ghost3.6源码

    Ghost 3.6源码的分析首先可以从其架构入手。这个版本采用了模块化设计,每个模块负责不同的功能,如用户管理、游戏状态跟踪、聊天系统等。这种设计使得代码结构清晰,便于维护和扩展。源码中的核心部分包括网络通信...

    Ball版GHOST3.6源码

    通过分析源码,我们可以了解到软件的工作原理、功能实现以及可能的优化空间。 【标签】:“Ball版GHOST3.6源码”标签明确了这个话题的核心内容,即关于特定开发者Ball对GHOST3.6的源代码修改。 【压缩包子文件的...

    ghOst3.6源码修改后过大多数杀软

    ghOst3.6源码修改后过大多数杀软ghOst3.6源码修改后过大多数杀软ghOst3.6源码修改后过大多数杀软ghOst3.6源码修改后过大多数杀软ghOst3.6源码修改后过大多数杀软

    牛精 ghost远控源码

    【标题】"牛精 ghost远控源码"指的是一个基于Ghost技术的远程控制软件的源代码,该软件可能被命名为“牛精Ghost”。Ghost在IT领域通常是指一种克隆或备份系统的工具,但在这种上下文中,它可能是指一种用于远程监控...

    c语言ghost远控源码

    【标题】"C语言Ghost远控源码"指的是一个基于C语言编写的远程控制软件——Ghost的源代码。Ghost在IT行业中通常被视为一种高级的、隐蔽的远程访问工具,允许用户远程控制其他计算机,进行各种操作,如文件管理、监控...

    GHOST3.75源码

    GHOST3.75,作为一款历史悠久的系统克隆与恢复工具,其源码的公开无疑为开发者和技术爱好者提供了一个宝贵的参考资料。通过深入研究GHOST3.75的源码,我们可以洞察其工作原理,了解数据备份与恢复的核心技术,并从中...

    ghost2012远控源码

    【标题】"ghost2012远控源码"指的是Ghost 2012远程控制软件的源代码,这是在编程领域中一个重要的研究对象,尤其是对于那些对网络安全、恶意软件分析以及逆向工程感兴趣的开发者和安全专家。Ghost 通常指的是能够...

    ghost干净源码

    【标题】"ghost干净源码"所指的GHOST,全称为Generic Hackers Organized Network Tool,是一款知名的远程控制软件,常被黑客用于非法活动。然而,这里的“干净源码”可能是指经过优化或修改的版本,去除了可能触发...

    GHOST源码,很好的源码

    GHOST源码作为一个开放的工具,对于学习系统监控、远程控制技术的开发者而言是一份宝贵的资料。通过研究源码,开发者可以深入理解相关技术,提高自己的编程能力,并能将这些技术应用到自己的项目中,实现定制化的...

    ghost源码欢迎下载

    ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控ghost远控...

    饭客VIP远控GHOST编译源码.rar

    1. **代码结构**:分析源码的组织方式,理解模块化设计,学习如何划分功能组件。 2. **算法和数据结构**:查看源码中的关键算法,学习如何高效地处理数据和执行任务。 3. **错误处理**:研究源码如何处理异常情况...

    Ghost博客 v2.22.0.zip

    对于计算机专业的学生,Ghost博客源码是一个很好的学习和实践项目,可以作为毕业设计或论文的实例,研究如何构建一个完整的Web应用程序,理解前后端交互,以及如何利用Node.js和Markdown实现内容管理系统。...

    ghost源码免杀-2

    在网络安全领域,Ghost是一种常见的恶意软件,其源码免杀技术是黑客和安全研究人员关注的重点。本教程将深入探讨Ghost源码免杀的全套流程,帮助读者理解免杀技术的核心原理,并提供实用的技巧和方法。 一、Ghost...

    ghost 无错编译源码

    总之,"Ghost无错编译源码"是一个涉及系统备份、DDoS攻击和免杀技术的综合性IT知识点,对于深入理解这些领域有着重要的学习价值。然而,值得注意的是,任何涉及到非法活动的技术探索都是不被鼓励的,应当遵守法律...

Global site tag (gtag.js) - Google Analytics