`

ParSeq in Action

阅读更多

近年来,rest架构风格火了起来,源于越来越多的人在SOA的实践中厌倦了SOAP之流,于是rest api终于抬头。LinkedIn 也于半年前开源了其rest + json的架构:rest.li,着实为rest加了把火。

 

什么是ParSeq

rest.li允许资源异步地返回结果。这个机制由LinkedIn的另外一个开源项目ParSeq来支撑。ParSeq是轻量级的Java异步操作框架。

 

ParSeq能做什么

它的主要提供了如下特性:

  • 并行的异步操作机制
  • 顺序执行非阻塞式的任务
  • 任务组合
  • 简单的异常传播和恢复机制
  • 任务执行追踪和可视化

 

ParSeq的架构简介

在ParSeq的架构里,Task是最基础的工作单元,如同Java的Callable,不同之处在于Task的执行结果可以被异步地获取。Task的启停,调度都交由Engine或者Context(你很快能从下文中看到它们)管理。用户是无法直接使用TaskEngine负责启停和调度Task,而Context则负责子任务。

 

之前我们也提到了ParSeq支持异步获取任务的执行结果。类比Java的多线程机制,不难发现,我们缺少一个等同Java中Future功能的组件,而Promise就是这样一个东西。在Java中如果我们使用

future.get()

来等待future的完成,但这样会阻塞当前的线程。而Promise提供一套监听机制,用户可以为Promise添加监听器,Task完成时会通知这些监听器完成回调逻辑。

 

此外,ParSeq可以非常方便地组合任务。ParSeq提供了一对常用的组合策略:如果并行地运行一组Task,你可以使用par,如果想顺序地执行,那么你可以使用seq

 

下载&编译

下载源码

源码维护在GitHub上:https://github.com/linkedin/parseq。你可以直接下载zip包,使用Github客户端下载,使用Git客户端下载等等。

 

编译环境

请先确认环境是否安装JDKAnt。如果需要可视化追踪功能,请下载node.jsnpm。JDK版本1.6和1.7皆可。Ant需要1.8.2及以上版本。JDK,Ant都需要配置环境变量。

 

编译源码

导航至源码根目录,执行如下命令:

ant -Dno.test.tracevis=1 test

 如果要打包,执行如下命令:

ant dist

 

Eclipse导入parseq源码

我使用的是Eclipse Juno。

File->New->Other->选择Java Project from Existing Ant Buildfile->Next->Browse->选择parseq根目录下的build.xml->Finish。 

 

如何使用ParSeq

环境准备好后,给出一个官网上的简单例子,帮助你快速上手。对于一个最基本的ParSeq程序,用户至少需要定义EngineTask这个两个组件。

 

创建Engine

import com.linkedin.parseq.Engine;
import com.linkedin.parseq.EngineBuilder;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;

// ...

final int numCores = Runtime.getRuntime().availableProcessors();
final ExecutorService taskScheduler = Executors.newFixedThreadPool(numCores + 1);
final ScheduledExecutorService timerScheduler = Executors.newSingleThreadScheduledExecutor(); 

final Engine engine = new EngineBuilder()
        .setTaskExecutor(taskScheduler)
        .setTimerScheduler(timerScheduler)
        .build();

 

engine由builder构建,这种高可读的显式构造方式使用户对构造engine时所需的参数一目了然。在本例中,我们使用了容量为处理器核数+1的线程池作为任务执行池,并使用另外一个线程来调度计时器。当然这些都可以根据用户的具体用例来定制不同的engine。

 

关闭Engine

engine.shutdown();
engine.awaitTermination(1, TimeUnit.SECOND);
taskScheduler.shutdown();
timerScheduler.shutdown();

自解释的代码,无需多言。值得注意的是Engine并不管理executor的生命周期,用户需要显式地关闭它们。在关闭期间,新的Task不允许执行,而ParSeq允许运行中的Task完成自己的任务。

 

创建任务

用户可以按不同的业务行为定义不同的任务:

<图一>


 各Task实现类的明细功能会在后文中介绍,本例中我们先使用CallableTask。这种Task常用来做一些简单的计算和转换工作。本例的Task用于返回输入字符串的字符数。

import com.linkedin.parseq.Task;
import com.linkedin.parseq.Tasks;

import java.util.concurrent.Callable;

// ...

class GetLengthTask implements Callable<Integer>
{
  private final String _string;
  
  public GetLengthTask(String string) {
    _string = string;
  }
  
  @Override
  public Integer call() throws Exception {
    return _string.length();
  }
}

final Task<Integer> task = Tasks.callable("length of 'test str'", new GetLengthTask("test str"));

CallableTask还常用来转换其他Task的结果,这部分内容我们会在Task组合中更详细地介绍。  

 

运行任务

engine.run(task);

 

 

自定义Task

图一中,我们可以看到名为BaseTask的抽象类。如果用户想自定义自己的Task类型,就可以继承该类。

 

集成第三方异步库

个人觉得ParSeq最赞的功能是可以无缝地集成第三方异步库,这些库把自己托管给ParSeq。一旦集成完毕,所有的异步库摇身一变,跳起ParSeq Style。这对上层的程序员来说,无异于福音,他们无需再了解如何使用这些异步库。此外,第三方库也可以共享ParSeq为任务提供的各种额外功能。

 

为此官方提供了一个例子,这个例子集成的是GitHub上的一个开源异步Http客户端:

https://github.com/ning/async-http-client

https://github.com/sonatype/async-http-client

 

import com.linkedin.parseq.BaseTask;
import com.linkedin.parseq.Context;
import com.linkedin.parseq.promise.Promise;
import com.linkedin.parseq.promise.Promises;
import com.linkedin.parseq.promise.SettablePromise;

import com.ning.http.client.AsyncCompletionHandler;
import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.Request;
import com.ning.http.client.Response;

// ...

class HttpRequestTask extends BaseTask<Response>
{
  private final Request _request;

  public HttpRequestTask(Request request) {
    super("Http request: " + request);
    _request = request;
  }

  @Override
  protected Promise<Response> run(final Context context) throws Exception {
    // Create a settable promise. We'll use this to signal completion of this
    // task once the response is received from the HTTP client.
    final SettablePromise<Response> promise = Promises.settable();

    // Send the request and register a callback with the client that will
    // set the response on our promise.
    HTTP_CLIENT.prepareRequest(_request).execute(new AsyncCompletionHandler<Response>() {
      @Override
      public Response onCompleted(final Response response) throws Exception {
        // At this point the HTTP client has given us the HTTP response
        // asynchronously. We set the response value on our promise to indicate
        // that the task is complete.
        promise.done(response);
        return response;
      }

      @Override
      public void onThrowable(final Throwable t)
      {
        // If there was an error then we should set it on the promise.
        promise.fail(t);
      }
    });

    // Return the promise to the ParSeq framework. It may or may not be
    // resolved by the time we return this promise.
    return promise;
  }
}

非常方便,用户立刻得到了一个ParSeq Style的异步Http客户端。代码中的HTTP_CLIENT是AsyncHttpClient的一个实例。

 

在代码中,我们创建了SettablePromise用于记录HTTP的相应:


这部分的实现比较精彩。值得一读源码。

 

Task的组合

 To be continued...

  • 大小: 11.8 KB
  • 大小: 8.9 KB
分享到:
评论

相关推荐

    Spring in Action 中文版 第五部分(Spring in Action CN.005)

    Spring in Action CN.001&lt;br&gt;Spring in Action CN.002&lt;br&gt;Spring in Action CN.003&lt;br&gt;Spring in Action CN.004&lt;br&gt;Spring in Action CN.005&lt;br&gt;Spring in Action CN.006&lt;br&gt;Spring in Action CN.007&lt;br&gt;Spring in ...

    Spring in Action 中文版 第二部分(Spring in Action CN.002)

    Spring in Action CN.001&lt;br&gt;Spring in Action CN.002&lt;br&gt;Spring in Action CN.003&lt;br&gt;Spring in Action CN.004&lt;br&gt;Spring in Action CN.005&lt;br&gt;Spring in Action CN.006&lt;br&gt;Spring in Action CN.007&lt;br&gt;Spring in ...

    ActiveMQ in Action pdf英文版+源代码

    ActiveMQ in Action pdf英文原版加源代码压缩包。 Apache ActiveMQ in Action is a thorough, practical guide to implementing message-oriented systems in Java using ActiveMQ. The book lays out the core of ...

    In Action系列技术书籍

    本系列包含的书籍有《Spring in Action》第三版、《Restlet in Action》、《OSGi in Action》以及《MongoDB in Action》。 【描述】中的"Spring in Action.3rd"指的是Spring框架的实战指南,第三版。Spring是Java...

    lucene in action 2nd edition, lucene in action 第二版 PDF

    《Lucene in Action 第二版》是一本深入探讨Apache Lucene全文检索库的专业书籍,它在Java开发领域具有很高的权威性。这本书详细介绍了如何利用Lucene进行高效的文本搜索和索引构建,是Java开发者和信息检索爱好者的...

    spring in action的jar包

    《Spring in Action》是关于Spring框架的一本经典书籍,它深入浅出地介绍了Spring的核心概念和技术。这个"spring in action的jar包"很可能是书中提到的一些必要的库文件,用于配合书中的实例代码运行。这些jar包是...

    Hadoop In Action2

    Hadoop In Action 中文第二版 卷二 rar

    IronPython in Action 无水印pdf版

    IronPython in Action 无水印pdf版。 IronPython in Action 英文无水印pdf pdf所有页面使用FoxitReader和PDF-XChangeViewer测试都可以打开 本资源转载自网络 IronPython Action

    R in Action 中文版PDF及原代码

    《R in Action》是一本深度探讨R语言的实用书籍,其中文版的PDF及源代码提供了全面学习和实践R语言的机会。这本书旨在帮助读者不仅理解R语言的基本语法和概念,而且能够利用R进行数据处理、统计分析以及创建高质量的...

    r in action ,第一版和第二版高清pdf R_IN_ACTION_1_AND_2

    《R in Action》是关于R语言的一本经典著作,涵盖了从初学者到高级用户的全面教程。这本书分为两个版本,第一版和第二版,都提供了高清PDF格式,方便读者在线阅读或下载保存。作为一本旨在帮助统计学入门者的书籍,...

    《Rust in Action》 by Timothy Samuel McNamara

    Rust in Action 是一本面向想要探索 Rust 编程语言世界的中级程序员的书。它适用于可能已经用尽网络上的免费资料但仍想了解更多信息的人。它与 Rust 编程的其他材料不同,因为它还教您有关系统编程的知识。您将能够...

    ibatis in action 中文版3ibatis in action 中文版3

    ibatis in action 中文版3ibatis in action 中文版3ibatis in action 中文版3ibatis in action 中文版3

    Spring in Action, 6th Edition, PDF 格式

    Spring in Action, Sixth Edition is a comprehensive guide to Spring’s core features, all explained in Craig Walls’ famously clear style. You’ll put Spring into action as you build a complete ...

    C++ Concurrency in Action 2nd.pdf

    《C++ Concurrency in Action》第二版是一本专注于C++编程语言中并发和并行编程的权威指南。本书主要侧重于C++11以及后续版本中引入的多线程功能,旨在帮助读者深入理解并有效运用C++并发特性。由于C++11对并发的...

    Kotlin In Action中英版

    《Kotlin in Action》是一本深受开发者欢迎的书籍,它详细介绍了Kotlin编程语言的各个方面。这本书分为中英文两个版本,都有完整的目录结构,方便读者快速定位到所需内容,尤其适合那些希望深入学习Kotlin并将其应用...

    Spring in Action 中文版 pdf

    《Spring in Action》是Spring框架领域的一本经典著作,它以深入浅出的方式介绍了Spring框架的核心概念和技术。这本书的中文版对于中国的Java开发者来说是一份非常宝贵的资源,它帮助我们理解并掌握Spring框架,从而...

    Unity in Action Multiplatform game development in C#(2nd) 无水印原版pdf

    Unity in Action Multiplatform game development in C#(2nd) 英文无水印原版pdf 第2版 pdf所有页面使用FoxitReader、PDF-XChangeViewer、SumatraPDF和Firefox测试都可以打开 本资源转载自网络,如有侵权,请联系...

Global site tag (gtag.js) - Google Analytics