Clark To Do The blog of Clark

Undertow 请求生命周期

之前项目是采用Spring Boot作为应用整体的框架, 其内置的应用容器是Tomcat, 后来在Spring Boot文档内发现了Undertow, 经过一段时间的理解和试用, 效率上较之前有了一定幅度的提升.

因此将Undertow对于Web端请求的生命周期总结如下.

当连接建立, XNIO会调用io.undertow.server.HttpOpenListener. 这个监听器用于创建一个全新的io.undertow.server.HttpServerConnection, 创建出的连接负责保持这个连接的状态, 进而调用io.undertow.server.HttpReadListener.

HttpReadListener负责解析请求, 并创建io.undertow.server.HttpServerExchange来存储请求状态.exchange对象同时包含请求和响应的状态.

这时候, 请求和响应的信道包装器会进行初始化, 它会负责对于请求和相应数据的编解码.

接下来, 根处理器会通过io.undertow.server.HttpHandlers#executeRootHandler被执行. 处理器间调用为链式结构, 每个处理器都可以修改exchange对象, 发送响应或者代理给其他处理器. 这个阶段会发生:

  • exchange的终止. 这会在请求和响应的信道被关闭时发生. 如果设置了content length, 那么当所有数据被写入后, 信道会被自动关闭. 也可以通过调用HttpServerExchange.endExchange()来强制关闭. 如果还没有数据被写入, 任一注册了exchange的默认的响应监听器会有机会去生成一个默认的响应, 比如: 错误页面. 一旦当前exchange终止, 结束监听器ExchangeCompletionListener就会被执行. 最后一个监听器通常会在连接上开启下一个请求的处理, 并会初始化HttpReadListener.

  • exchange通过调用HttpServerExchange.dispatch进行调度. 这个方法与startAsync()方法类似. 当调用栈返回, 调度任务(如果存在)会在提供好的执行器内执行(如果没提供执行器, 就会在XNIO worker内支线). 调度最常见的用法就是从在一个IO线程内执行(不允许阻塞操作)移动到一个可阻塞的worker线程. 这个模式类似:

public void handleRequest(final HttpServerExchange exchange) throws Exception {
    if (exchange.isInIoThread()) {
      exchange.dispatch(this);
      return;
    }
    //handler code
}
  • 读/写可以在一个请求或响应的信道上被恢复. 在内部, 这类似一次调度, 一旦调用栈返回, 相关联的信道会通过IO事件被通知. 直到调用栈返回操作才生效的原因是确保永远不会有多个线程参与到相同的exchange里.

  • 调用栈可以不返回正在被调度的exchange. 当这种情况出现, HttpServerExchange.endExchange()会被调用, 并且请求将会结束.

  • 异常可以被抛出. 如果异常一路被传播到调用栈顶, exchange会以一个500响应结束.

参见

[1] Undertow Online Docs-1.3.0

JavaScript 函数式编程

这篇文章将介绍 JavaScript 的函数式编程的理论. 其中有属于语言内置的内容, 其他均为额外实现, 但是所有内容都是类似于 Haskell 的很通用的”纯函数式语言”. 首先, 我想先说明一下”纯函数式语言”的含义. 这类语言都是”安全”的, 它们不会产生任何副作用, 例如: 执行表达式不会改变内部状态, 从而导致在下一次调用同一个表达式时产生不同的结果. 这看起来似乎很怪异并且没什么用, 但实际上是有一些列好处的:

  1. 并发. 不会有死锁或者竞争条件, 因为根本不需要锁 - 数据是不可变的. 看起来还是很有前途的吧…
  2. 单元测试. 可以尽情编写单元测试而无需担心状态, 因为根本不存在这个东西. 我们只需要关心测试函数的参数.
  3. 调试. 堆栈信息绝对够用了.
  4. 扎实的理论基础. 函数式语言基于数学形式系统中的λ演算. 这个理论基础使得证明程序的正确性是很直截了当的(例如: 使用归纳法).

希望上述参数足够促使你阅读接下来的部分. 下面, 我会描述 JavaScript 内的函数式要素, 并且提供一些不是原生但是代价很小的实现.

前端导出文件方式

我们在日常开发中, 经常会遇到需要将查询结果导出为Excel, PDF等等文件的需求. 下面, 我将为大家介绍一下几种比较常见的导出方式.

1. 服务器转发方式

这种方式应该是应用的最普遍的方式了, 通常我们会将页面元素收集起来发送给服务端, 或者干脆直接调用服务端接口, 由服务端直接获取数据并拼装为对应的文件格式, 最后将数据拼入 HTTP Response 中并对 Header 处理, 最后返回给客户端, 实现文件下载.

Java 8 Method References

Method References 是什么?

它是与 Lambda 表达式相关的一个功能. 它允许我们引用构造函数或者方法而无需执行. Method references 与 Lambda 非常相似, 因为它们都需要一个含有兼容的函数式接口的目标类型.

Method Reference 的类型

一共存在4种 Method Reference, 请参考表格:

类型 例子 语法
1. 静态方法 ContainingClass::staticMethodName Class::staticMethodName
2. 构造方法 ClassName::new ClassName::new
3. 特定类型的任意对象的实例方法 ContainingType::methodName ContainingType::methodName
4. 特定对象的实例方法 containingObject::instanceMethodName object::instanceMethodName

ASCII, Unicode 汉字转换

首先, 将汉字转换为 ASCII 的函数:

function ascii(str) {
    return str.replace(/[^\u0000-\u00FF]/g, function($0) {
        return escape($0).replace(/(%u)(\w{4})/gi, "\&#x$2;")
    });
}

7个让你爱上 CDN 的原因

内容分发网络(CDNs) 在过去几年间彻底改革了网络主机. 取代了单个服务器托管网站的方式, 你可以跨多个系统和负载分发文件。

理解同源策略, 限制, 目的与替代方案

每个程序员都或多或少会向不同的域获取/发送数据. 最近, 我在开发一个书签工具, 需要在公司的站点与其他域间进行信息交互. 当两个域之间需要进行交互时, 理解一下同源策略就很有必要了. 维基百科是这么描述同源策略的:

“同源策略允许运行在同一网站上的脚本可以毫无限制的访问双方的方法与属性, 但是会组织不同网站间的大多数方法与属性的访问”

需要了解的是: 存在2中同源策略. “DOM 同源策略” 负责在不同窗口下通过 DOM 进行读写的部分. ““XmlHttpRequest 同源策略”负责不同窗口间的 Ajax 通信.

Git Merge 的内部流程

首先要说明的一点是, Git 本身有一套内部的合并系统, 而不是通过外部比较工具来进行代码合并. 但是可以通过给 git merge 命令添加 -s 选项来指定合并策略(resolve, recursive, octopus, ours, subtree):

-s <strategy>
--strategy=<strategy>

本质上来说, 在 Git 中, 每个 merge 都会被视为冲突, 冲突内含有一个索引, 该索引内的每个文件保留三个版本: 当前分支, 合并分支, 基础分支. 然后, 各种的 Resolver 就会在这个索引上开始执行了, 这些 Resolver 将会针对每个独立的文件来解决冲突.

过度设计的有趣想法

最近在阅读一篇关于过度设计的文章I BET YOU OVER-ENGINEERED YOUR STARTUP时, 我看到这样一个有趣的评论.

原文:

I agree, I can’t keep up, I just finished learning backbone.js and now I’m found out on that it’s old news, and I should use ember.js, cross that, it has opinions, I should use Meteor, no, AngularJS, no, Tower.js (on node.js), and for html templates I need handlebars, no mustache, wait, DoT.js is better, hang on, why do I need an HTML parser inside the browser? isn’t that what the browser for? so no HTML templates? ok, DOM snippets, fine, Web Components you say? W3C are in the game too? you mean write REGULAR JavaScript like the Google guys? yuck, oh, I just should write it with CofeeScript and it will look ok, not Coffee? Coco? LiveScript? DART? GWT? ok, let me just go back to Ruby on Rails, oh it doesn’t scale? Grails? Groovy? Roo? too “Springy?” ok, what about node.js? doesn’t scale either?? but I can write client side, server side and mongodb side code in the same language? (but does it have to be JavaScript?) ok, what about PHP, you say it’s not really thread safe? they lie?? ok, let me go back to server coding, it’s still Java right? no? Lisp? oh it’s called Clojure? well, it has a Bridge / protocol buffers / thrift implementation so we can be language agnostic, so we can support our Haskell developers. Or just go with Scala/Lift/Play it’s the BEST framework (Foresquare use it, so it has to be good). of course we won’t do SOAP and will use only JSON RESTful services cause it’s only for banks and Walmart, and god forbid to use a SQL database it will never scale I’ve had it, I’m going to outsource this project… they will probably use a wordpress template and copy paste jQuery to get me the same exact result without the headache and in halfquarter the price

译文:

我承认, 我已经跟不上了, 我刚刚学完了 backbone.js 就发现它已经过时了, 我应该去学习 ember.js, 还有不同的声音是, 我应该使用Meteor, 不, 还是 Angular.js 吧, 算了, 还是用Tower.js(基于 node.js )吧, html 模板方面, 我需要 handlebar, 而不是mustache, 等等, DoT.js也许更好, 再等一下, 为什么我需要浏览器内的HTML解析器? 这不就应该是浏览器本身的职责吗? 要不就不用 HTML 模板了? 好吧, 就选择 DOM snippets 吧, 你是在说 Web Components 吗? W3C不正在做这个么? 你是说像谷歌一样开发一套常规的 JavasScript 语言么? 噗, 我还是用 CoffeeScript 吧, 写出来的效果也还不错, 不用 CoffeeScript 了? 改用Coco? LiveScript? Dart? GWT? 好吧, 我们还是回到 Ruby on Rails 吧, 什么? 它不易扩展? 用Grails? Groovy? Roo? 太具弹性? 好吧, node.js怎么样? 也不易扩展?? 但是用它我能在客户端, 服务端和mongodb端用同样的语言完成开发? (但是何必用 JavaScript 呢?), 好吧, PHP怎么样, 你说它并不是真正的线程安全? 他们在撒谎? 好好好, 我们再回到服务端编程吧, Java仍是正确选择么? 不好? 那Lisp呢? 哦, 应该是 Clojure ? 恩, 它有一套 Bridge / protocol buffers / thrift 的实现, 这样就可以达到语言无关了, 这样我们也可以支持 Haskell 的开发人员了. 或者就转到 Scala/Lift/Play 上吧, 它们都是最好的框架(Foresquare 就是用的它们, 它们肯定很棒). 当然, 我们不会使用SOAP, 俄日是只用 JSON RESTful 服务, 只有银行和沃尔玛还在用SOAP, 再就是, 一定不要用SQL 数据库, 因为它们根本没法扩展. 我还是把这个项目外包出去吧… 他们可能会使用 Wordpress 模板,然后复制-粘贴 jQuery 代码, 就可以只用很少的代价获取同样精确的结果.

Windows 下 Pygments 的安装与使用

安装 Pygments

  • 安装 Python
  • 安装 distribute
  • 将 Python 安装路径与其下 Scripts 目录添加至环境变量 Path
  • 安装 pip: easy_install pip
  • 安装 pygments: pip install pygments
  • 验证是否安装成功: pygmentize -V