Akka Streams: Using TCP

引子

准确来说,IO API 不算是 Akka Streams的内容,但它却是 Streaming IO (TCP) 的基础。

IO API 编程的第一步,是获取一个管理对象的引用。比如我们想针对TCP编程,可以这么获取 TCP Manager:

manager 是一个 actor 对象,用于处理底层 I/O资源和操作(诸如channels/selectors,或是workers的初始化),同时对于上层提供基于actor 模型的抽象

IO TCP

IO TCP 编程也是 CS 模型的,好处是不需要写繁琐的 S[……]

阅读全文

Akka Streams: Integrating with Actors

引子

Akka Streams 为异步编程提供了管道和流式接口,但如果我们希望结合 actor 模型的消息机制呢?Akka Streams提供了如下解决方案:

  • Sink.actorRef 产生 ActorRef,做为下游结点接收管道里的流数据
  • Source.actorRef 产生ActorRef,能被下游结点消费
  • Source.ActorPublisher 产生ActorRef,用于实现Reactive Streams中的Publisher
  • Sink.ActorSubscriber 产生ActorRef,用于实现Reactive Streams中的Subscriber[……]

阅读全文

Akka Streams: GraphStage

Stages

Stage 是 Akka Streams 里的核心概念,它代表了在Graph里的单位,是如何定义输入端口(Inlet)  / 输出端口(Outlet) 的;常用的基础形态有:

compose_shapes1

  • Source: 只有一个Outlet
  • Sink: 只有一个Inlet
  • Flow: 只有一个Outlet和一个Inlet
  • Fan-In: 多个Inlet一个Outlet
  • Fan-Out: 一个Inlet多个Outlet
  • BidiFlow: 双向通道,一对Inlet一对Outlet

有了这些基础件,我们可以按需组合出各种拓扑的图来:
runnable_graph1

自定义流处理

之前介绍过[……]

阅读全文

Akka Streams: pipelines

Reactive Streams

reactive streams 是一个异步流标准,Akka项目是这个标准最早的实现者之一。

标准定义了两个通道:

  • publisher为上游生产者通道
  • subscriber为下游消费者通道

reactive_stream标准要求这两个通道间的通信是异步非阻塞的,并且是基于反压模式(back pressure)的——数据是从publisher流向subscriber的,但数据一次发送多少个elements是由subscriber通过request(n)来告诉上游的,这使得流可控。同时,这也使得流在处理过程中的合并与拆分成为可能:

split_and_merge_streams

akka-stream[……]

阅读全文

Akka in action: Let it crash

Akka 在容错方面有如下特点:

  • 分区容错(local & remote),错误隔离
  • Actors 基于策略进行监督和恢复
  • 在错误解决前,失效的Actor 可被挂起,转由系统代收消息(Dead Letter),并在恢复时继续之前的消息处理

Akka 对于错误的观点值得称道:没有银弹,还是着眼于如何进行灾后重建吧 :)

Let it crash

与传统应用将 业务逻辑和 try {} catch{}错误处理 绞在一起不同,Akka 的容错恢复是独立于业务逻辑的:Actors专注于自己的消息处理逻辑,而错误处理和策略设定,则由层 级结构里,它的监督者(父级Acto[……]

阅读全文

Akka in action: actor model

引子

最近在学习 Akka,因为Scala的新版本已将Actors迁移到Akka [1](教材就是那本烂到一定程度的 Akka in action,排版字体代码示例一如既往的Manning式的糟糕)——至于为什么要学习Actors,大概是因为 红宝书 里提出了一些对异步编程组合子的设计要求。

Akka

官方定义:

Akka is a toolkit and runtime for building highly concurrent, distributed, and resilient message-driven applications on the JVM.

做为一个消息驱[……]

阅读全文

RingBuffer in scala

是什么?

ring_bufferRingBuffer (环形缓冲区),是一种用于表示一个固定尺寸、头尾相连的缓冲区的数据结构,适合缓存数据流(用来实现轮转功能的日志也很合适)。

它亦是一个队列,先进先出(FIFO)。这意味着,入队永远是在环的尾部(tail),出队永远是在环的头部(head)。这个环的容量是一开始就确定的,那么不停变换的,是头尾两个指针:入队驱动tail,出队驱动head,在环上单向轮转。

性能优势

我们可以将RingBuffer实现为一个不停覆盖尾部的版本, 以提供一种高性能的有限无锁队列:

  • 它使用数组,比链表要快,且基于一个可预测的访问模式(数组内元素的内存地址 具有连续性[……]

阅读全文

JS中的一些函数式编程术语

组合 Composition

组合某种类型(含函数)的两个元素,进而生成一个该类型的新元素:

偏函数应用 Partial Application

一个多参函数,如果我们只提供了部分参数,这种应用就是偏函数应用:

柯里化 Currying

把多参数函数处理成 接受一个参数,返回一个接受下一个参数的函数 的形式:

注意:柯里化和偏函数应用是不同的,它只接受单参输入;在Haskell这样[……]

阅读全文

学习RxJS:Cycle.js

是什么

Cycle.js 是一个极简的JavaScript框架(核心部分加上注释125行),提供了一种函数式,响应式的人机交互接口(以下简称HCI):

函数式

Cycle.js 把应用程序抽象成一个纯函数 main(),从外部世界读取副作用(sources),然后产生输出(sinks) 传递到外部世界,在那形成副作用。这些外部世界的副作用,做为Cycle.js的插件存在(drivers),它们负责:处理DOM、提供HTTP访问等。

circuit_flow

响应式

Cycle.js 使用 rx.js 来实现关注分离,这意味着应用程序是基于事件流的,数据流是 Observable 的:

observable_stream

HCI[……]

阅读全文

学习RxJS: 导入

引子

新手们在异步编程里跌倒时,永远会有这么一个经典问题:怎么在一次异步调用里return一个结果啊?

老司机说要用回调函数,然后有条件判断的嵌套回调(回调地狱)问题来了;

老司机推荐用事件,然后异步流程里有顺序依赖;

老司机推荐用Promise,然后有顺序依赖的流程里,居然还想订阅事件;

老司机建议试试协程,谁知对方想要合并两个异步调用;

……

以上,是异步编程里要面对的一些难题,也是ReactiveX API 所致力解决的

是什么

知道有 ReactiveX 这么一回事, 源于一位巨硬铁粉的安利演示:Reactive LINQ 加持的C#,简洁[……]

阅读全文