设为首页 收藏本站
查看: 2822|回复: 0

[经验分享] deno深入揭秘及未来展望

[复制链接]
发表于 2018-9-21 08:38:41 | 显示全部楼层 |阅读模式
deno
  node.js之父Ryan Dahl在一个月前发起了名为deno的项目,项目的初衷是打造一个基于v8引擎的安全的TypeScript运行时,同时实现HTML5的基础API。所谓的安全运行时,是将TS代码运行在一个沙盒里,访问受限的文件系统、网络功能,这比较类似于web里的iframe sandbox。
  现阶段,deno的变化可谓翻天覆地。Ryan的项目一个月前提供了golang版本的deno简易源码,而如今不仅仅重构了项目,底层语言都切换为c++,接口也做了很大的更新,这源自于社区内热情的讨论,有太多太多的开发者、协作人员提出了太多的优化以及改进意见,这也就导致接下来未来几个月deno仍然会出现大改变,这在后文会提及。现在,我就带领大家进入最初的deno微观世界探索deno最初的设计。

架构

  q 本文讲解deno的golang版本,当前最新的deno由于性能问题放弃了golang的实现,但这不影响我们分析deno的原理。未来在七月deno估计会释放出基于Rust的底层特权级实现,性能更优。


  q 由于deno涉及之处是为了直接运行TS,因此下文会用TS来代指JS(现阶段TS没有自己的运行时,仍是基于编译为JS在运行在v8)

  deno的设计初期来看比较简单,宏观上看包括三部分:deno的go运行时、v8引擎以及连接go运行时和v8的v8worker2库。
  
DSC0000.png
  
go运行时是deno的特权级,它负责deno对系统资源的申请、使用、释放;v8引擎此处不仅仅执行JS代码,同时也负责TypeScript的编译;而v8worker2负责go与v8的全双工通信,通过ArrayBuffer传输数据,传输的协议规范为protobuf。
  深入到go运行时里,目前deno对TS层提供了几种能力:Console、fetch、fs、module、timer、stack trace,虽然有些功能没有提供用户端API,不过golang的接口已完成,扩展很容易。
  
DSC0001.png

go运行时
  deno在特权级代码执行了3端逻辑:


  • 初始化go运行时环境
  • 初始化TS运行时环境
  • 启动go这一侧的事件循环(该事件循环不同于node的基于libuv的event loop,下文会提到)
初始化go运行时环境
  

    // HOME目录下创建 cache和src目录  createDirs()
  // 利用 afero 库创建虚拟fs对象;同时订阅 v8端的 os事件,在go端实现 文件抓取、获取缓存、磁盘I/O,同时返回 proto序列化数据 给v8
  InitOS()
  // 心跳
  InitEcho()
  // 接受v8消息,进行 timeout、interval和clear
  InitTimers()
  // 订阅 fetch 事件,代理服务器。当代理请求结束时,返回两个消息:第一个为状态码;第二个为body体
  InitFetch()
  

  // recv为 v8->go 的回调函数,处理v8的消息
  worker = v8worker2.New(recv)
  

  // 初始化ts的相关环境,和go端对应
  main_js = stringAsset("main.js")
  err := worker.Load("/main.js", main_js)
  exitOnError(err)
  

  依次执行以下任务:
  
- 创建缓存目录,存储TS文件编译后的JS文件
  
- 订阅 os 事件,处理来自v8层的操作,如fs等
  
- 订阅 timer 事件,处理来自v8的定时器操作
  
- 订阅 fetch 事件,处理来自v8的http request
  
- 初始化v8worker2实例,实现go与v8的绑定
  
- 加载js入口文件main.js,该文件定义了js的全局接口、初始化逻辑和与go运行时通信的方法,等待下一阶段的执行。

初始化js运行时环境
  

// v8端执行 denoMain函数,在main.ts中定义  
deno.Eval("deno_main.js", "denoMain()")
  

  上一步v8已经加载并执行了main.js文件,现在该执行denoMain方法了。denoMain是在main.js中定义的初始化方法,它定义了deno在js层的API以及v8worker实例,也是开发者密切相关的一层。
  关于ts层的逻辑留在下文讲述。

启动事件循环
  

    var resChan = make(chan *BaseMsg, 10)  var doneChan = make(chan bool)
  var wg sync.WaitGroup
  wg.Add(1)
  first := true
  

  // In a goroutine, we wait on for all goroutines to complete (for example
  // timers). We use this to signal to the main thread to exit.
  // wg.Add(1) basically translates to uv_ref, if this was Node.
  // wg.Done() basically translates to uv_unref
  go func() {
  wg.Wait()
  doneChan

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-599167-1-1.html 上篇帖子: C# 指定http请求使用Tls1.2 下篇帖子: 搭建web定时任务管理平台
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表