PipyJS - 函数式网络编程语言

这篇文章主要介绍 Pipy 以及强大的 PipyJS - 没有垃圾回收开销、轻量级的函数式 JavaScript 解释引擎。
Pipy 概览
Pipy 是一个开源的、轻量级、高性能、模块化、可编程的云原生网络流处理器,适用于边缘路由、负载均衡和代理解决方案、API 网关、静态 HTTP 服务器、服务网格边车、策略即代码等应用场景。
技术术语有点多,我们继续深入了解一下。
轻量级
Pipy 的可执行文件只有 10MB 左右,没有任何外部依赖,仅需很少的内存就可以运行。
高性能
Pipy 是使用 C++ 并基于异步 I/O 库 Asio 开发的。
模块化
Pipy 的核心使用了模块化设计,提供了大量可复用的小模块(过滤器)。这些过滤器可以组装成管道,网络数据流经这些管道并被处理。
流处理器
Pipy 将网络流数据字节抽象成事件,以事件驱动的方式来操作网络流。提供了事件驱动管道的抽象,管道使用输入流、执行用户定义的转换并输出流。
可编程
Pipy 对外屏蔽了底层的细节,提供了类似拼图的编程方式来实现业务目标。Pipy 是通过强大的 PipyJS 实现的,也是接下来我们要详细介绍的。
为什么使用 JavaScript
就像标题介绍的,PipyJS 是基于 JavaScript 的。Pipy 决定使用类似 JavaScript 脚本语言是有原因的:
JavaScript 可能是世界上最广泛使用的语言
它的语法有 C 和 Java 的影子,因此对大多数程序员不陌生
Pipy 作为流处理器,意味着有大量的数据转换和重组的工作。通过 JavaScript 提供的很多强大的语法糖可以轻松搞定,比如展开语法、解构赋值、以及数组的 map()、reduce() 等操作
JSON 作为网络上最广泛使用的数据格式,JavaScript 提供了原生支持可以轻松操作
最后也是最最重要的,JavaScript 包含了“函数式编程”范式
Pipy 就像是一些彼此相连的管道一样。每个管道由一系列的过滤器组成,每个过滤器就像接收输入并返回特定结果的函数。对于这种设计模式,假如你的目标是保持连贯和简单,函数式编程语言是最适合 Pipy 的。
PipyJS 介绍
Pipy 通过自研的 PipyJS 组件来解析 JavaScript,该组件是 Pipy 代码库的一部分,但不依赖它。
PipyJS 是一个小且可嵌入的 JavaScript 引擎,专为高性能而设计,没有垃圾回收开销。它支持 ECMAScript 标准的子集,并且在某些方面进行了大胆的扩展。Pipy 拥抱纯函数式 JavaScript,在 PipyJS 中,万物皆表达式。
数据类型
与标准 JavaScript 一样, PipyJS 支持 4 种基本类型和结构数据的 对象 类型。
基本类型 Undefined:变量未初始化时的唯一值
undefinde。布尔类型 Boolean:true和false。数字类型 Number:64 位双精度浮点数,如123、0xabc、3.1415926、1e6。字符串类型 String:Unicode 字符序列。结构化数据类型 Null 对象:唯一值
null。用户定义的 POD(plain old data) ,如{ x: 1.2, y: 300 }内置对象:比如 Array、RegExp。函数:比如(a, b) => a * a + b * b。
操作符
PipyJS 支持所有的标准 JavaScript 操作符,包括一些在 ES2020 才引入的,比如 可选链操作符 和 空值合并运算符。
全局变量
全局变量在 PipyJS 中也叫做 上下文变量。这里的上下文概念等同于高并发网络编程中的连接,每个连接都有彼此独立的状态。在 PipyJS 中,为方便起见这些隔离的状态保存在全局变量中,这也是为什么有时我们称其上下文变量。这也很好理解为什么 PipyJS 全局变量与标准 JavaScript 不同,简单说就是在不同的连接中值不相同。这点上,有点像线程本地存储
全局变量通过内置的函数 pipy() 来定义,它通常是脚本中第一个调用的函数。
为了方便起见,全局变量使用下划线作为变量名的首字符,尽管不是语言强制的。
全局变量的作用范围是单个文件或者模块,多个模块间可通过 export() 和 import() 来共享。
为了方便起见,导出的全局变量名使用双下划线开头,但不强制。
本地变量
在 PipyJS 中,我们使用嵌套在局部变量函数范围内的函数参数作为本地变量。
假如想要上面的表达式执行后返回结果,则需要删除开头的
void
分支
在 PipyJS 中,万物皆表达式。不存在代码块或者流程控制,不能写 if 或者 for 语句。但这并不是说就不能写分支和循环了,而只是换了种形式:函数式。
简单分支可以使用逻辑运算符 &&。
注意:上面是 PipyJS 分支语法,下面是标准 JavaScript 语法(下同)。
多选择分支可以将逻辑运算符 && 和 || 组合使用。
循环
可以使用 Array.forEach() 来实现简单有界的循环。
或者,对于通用条件循环,可以使用内置的函数 repeat()。
派生 ECMAScript
PipyJS 专为速度设计,其结构对于编写高性能网络流处理逻辑至关重要。下面重点介绍 PipyJS 与标准 ECMAScript 的不同或者未实现的:
面向对象编程(OOP)结构 - 没有用户定义类型或者会构造器,没有原型系统
控制流
关键字
break,case,catch,continue,debugger,default,do,else,finally,function,for,if,return,switch,throw,try,while,with,yield,class,import,export,extends,static,super类型系统 BigInt and SymbolStrings 内部存储为 UTF-8,在脚本中可以作为 UTF-32 来访问。比如
"😀".length在标准 JavaScript 中是 2,但在 PipyJS 中是 1变量 - 没有用来声明变量的关键词
var或者let
尽管 PipyJS 派生自标准 ECMAScript,但是通过函数式机制来填补空白。
如何使用
现在你应该对 PipyJS 有了一定的了解,接下来我们看下如何编写代码并运行。
首先下载对应平台的二进制文件,将下面的代码保存为 ”hello.js“。
然后使用刚刚下载的二进制文件执行该脚本。
这段脚本会监听 8080 端口,并返回信息 Hi, there!。
总结
Pipy 是有 Flomesh 开源的、极其快速且轻量级的网络流量处理器,适用于多种场景。Pipy 正由全职的提交者和贡献者积极地开发和维护中,尽管还还是早期的版本,但已经过多个商业客户生产环境的实战测试。它的创建者和维护者 Flomesh.cn 提供了以 Pipy 为核心的商业级解决方案。
这篇文章对 Pipy 进行了简短的概述和高阶的介绍。在 GitHub 页面上可以找到教程和文档,也可以通过 Pipy 的管理控制台界面来访问。Pipy 社区非常欢迎贡献开发、尝试特定场景、或者提供简介和反馈。
版权声明: 本文为 InfoQ 作者【Flomesh】的原创文章。
原文链接:【http://xie.infoq.cn/article/4adbeaed8973a2442b96e31bb】。文章转载请联系作者。










评论