简体   繁体   English

Elixir:Observables

[英]Elixir: Observables

Elixir streams provide iterables, but I couldn't find any information on observables (Google was no help here). Elixir流提供迭代,但我找不到任何关于observable的信息(谷歌在这里没有帮助)。 I'd greatly appreciate it if someone could point me to resources for the same. 如果有人能指出我同样的资源,我将不胜感激。

You can combine Stream and Enum to write observable-style code. 您可以将Stream和Enum结合起来编写可观察样式的代码。 Here's an example of an echo server written in observable fashion: 以下是以可观察方式编写的echo服务器的示例:

IO.stream(:stdio, :line) 
|> Stream.map(&String.upcase/1)
|> Enum.each(&IO.write(&1))

Basically, for each line you send to standard input, it will be converted to uppercase and then printed back to standard output. 基本上,对于发送到标准输入的每一行,它将转换为大写,然后打印回标准输出。 This is a simple example, but the point is that all you need to compose an observable is already available via Stream and Enum. 这是一个简单的例子,但关键是你需要编写一个observable才能通过Stream和Enum获得。

Streams in Elixir are abstractions over function composition. Elixir中的流是功能组合的抽象。 In the end, all you get is a function, calling which will loop over the input stream and transform it. 最后,你得到的只是一个函数,调用它将循环输入流并转换它。

In order to build stateful streams like the example in Twitter4j (buffering new twitter statutes during one second and dispatching them all in one list), you'll need to use the building blocks that can have state. 为了构建有状态的流,如Twitter4j中的示例(在一秒钟内缓冲新的twitter规则并将它们全部分配到一个列表中),您将需要使用可以具有状态的构建块。 In Elixir, it is common to encapsulate state in processes. 在Elixir中,通常将状态封装在进程中。

The example might look like this 示例可能如下所示

tweetsPerSecond =
  twitterStream 
  |> SS.buffer({1, :second}) 
  |> SS.map(&length(&1))

SS.subscribe(tweetsPerSecond, fn n -> IO.puts "Got #{n} tweets in the last second" end)
SS.subscribe(tweetsPerSecond, fn n -> IO.puts "Second subscriber" end)

SS is a new module we need to write to implement the observable functionality. SS是我们需要编写的新模块,用于实现可观察的功能。 The core idea (as far as I get it) is being able to subscribe to a stream without modifying it. 核心思想(据我所知)能够订阅流而无需修改它。

In order for this to work, the twitterStream itself should be a process emitting events for others to consume. 为了实现这一点, twitterStream本身应该是一个为其他人消费的事件。 You can't use Stream in this case because it has "blocking pull" semantics, ie you won't be able to interrupt waiting on the next element in a stream after some fixed amount of time has elapsed. 在这种情况下,您不能使用Stream ,因为它具有“阻塞拉”语义,即在经过一段固定的时间后,您将无法中断等待流中的下一个元素。

To achieve the equivalent functionality in Elixir, take a look at the GenEvent module. 要在Elixir中实现等效功能,请查看GenEvent模块。 It provides the ability to emit and subscribe to events. 它提供发出和订阅事件的能力。 There is no stream-like interface for it though, not that I'm aware of. 虽然它没有类似流的界面,但并不是我所知道的。

I have built a PoC of a Pub-Sub system where I have followed a kind of "Observable Pattern": http://mendrugory.weebly.com/blog/pub-sub-system-in-elixir . 我已经建立了一个Pub-Sub系统的PoC,我遵循了一种“可观察模式”: http//mendrugory.weebly.com/blog/pub-sub-system-in-elixir

In order keep the state (what process has to be informed) I have used an Agent . 为了保持状态(必须通知什么过程)我使用了代理

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM