JSON

EventMachine for ruby 学习(二)

字号+ 作者:H5之家 来源:H5之家 2017-12-19 12:00 我要评论( )

参考文章:http://rubylearning.com/blog/2010/10/01/an-introduction-to-eventmachine-and-how-to-avoid-callback-spaghetti/eventma

EventMachine for ruby 学习(二) 2012-07-02 14:54:47

分类: Python/Ruby

参考文章:

eventmachine 介绍以及如何避免回调混乱。

事件驱动编程最近变得很新潮,这很大程度是源于 


这个程序每隔一秒输出一个信息,运行不了,首先检查人品问题哈。

它是如何运作的呢? require eventmachine 之后,我们调用了 EventMachine.run,它会接收一个代码块最为参数。现在我们可以无视这些,专注于代码块内部,没有这个 eventmachine 可没法工作啊(如果你有强烈的好奇心,可以学习下 reactor pattern.)  EventMachine.run  中我们调用了 add_periodic_timer ,并传入了另外一个代码块。这里告诉 eventmachine  每隔1秒触发一个事件,然后调用代码块。这是我们学到的第一个有用的知识,这个代码块被称之为回调。

你可能会想使用一个循环不是更简单  loop { puts 'hi'; sleep 1 } ,你想的没错。但我保证,往后看,你会知道我们的方式更优。

在网络 IO上使用 eventmachine。

高效的 IO 是 eventmachine 的全部意义所在,一定要理解这一点。当你使用 eventmachine 进行网络 IO 编程时,你要么直接使用 eventmachine,要么是通过 eventmachine 钩子扩展的某种 lib (在 github 上你会找到很多的这种例子,很好识别,因为他们大多以  em- 开头命名)。然后你需要小心挑选使用哪些gems 来进行 database, api 等等的编程。

如果你选择不当就会阻塞 reactor,就是在 IO 操作结束前,eventmachine 将不会触发任何事件。比如说,如果你是用标准库中的 Net::HTTP ,向一个 URL 发出请求,预计10s响应,在此期间上面代码中的定时器都不会触发,直到操作结束。你已经完全丧失了并发性。

我们讨论下 HTTP client。 eventmachine 已经自带有两个不同的 HTTP client,但都有些问题,我们推荐不要用它们,这里有个更为强大的模块:em-http-request 。

安装:gem install em-http-request让我们通过它发出一个 http 请求,看看它如何工作的。(注:EM 是 EventMachine 的缩写,大家都喜欢少打几个字吧!)

Again we’re attaching a callback which is called once the request has completed. We’re attaching it in a slightly different way to the timer above, which we’ll discuss next.

Abstracting code that has a success or failure case

在设计 API 接口时,需要有办法来区分响应成功或者失败。在 Ruby中,有两种常用的方法。一种是返回 nil ,一种是抛出异常(比如 ActiveRecord::NotFound)。Eventmachine 提供了一种更为优雅的方案:the deferrable。

deferrable 是一个对象,通过它你可以添加上成功或者失败后的回调方法,名字分别为 callback 和 errback。愿意的话,你可以查看源码 code, 不算复杂.

前面代码中调用 HttpRequest#get 时,返回的就是一个 deferrable (实际上返回的是一个 EM::HttpClient 实例对象,它实际上也被 mix in 到了EM::Deferrable 模块中)。当然也有更为通用的办法,就是直接使用 EM::DefaultDeferrable。

As an excuse to use a deferrable ourselves I’ve decided that it would be a jolly marvelous idea to look up the language of tweets as they arrive from the twitter streaming API.

Handily, the Google AJAX Language API allows you to get the language of any piece of text. It’s designed to be used from the browser, but we won’t let a small matter like that stop us for now (although you should if it’s a real application).

When I’m trying out a new API I generally start with HTTParty (gem install httparty) since it’s just so quick and easy to use. Warning: you can’t use HTTParty with eventmachine since it uses Net::HTTP under the covers – this is just for testing!


Cool, Google understands Welsh!

在将这段代码修改为使用 use em-http-request 前 (HTTParty 是使用的Net::HTTP ),我们先将它封装成一个类,拿它同我们随后要写的 eventmachine 版本做下比较。无法判定语言则返回 nil 值。

现在将代码修改为使用 em-http-request:

返回结果如下:

  • The language was cy
  • 这段代码看起来完全不同。最大的区别是,由于引入了EM::Deferrable,无论我们的调用成功或者失败,相应的 callback 或 errback 代码都会被执行。

    作为练习,你可以试着修改下代码,让它允许三次错误,期间重复调用相关方法。这同现实情况极其类似,通过这个封装我们很好的隐藏了复杂性,完成后我们也不用再关心内部实现细节了。

    抽象代码,允许多次返回多个事件。

    现在我们将进入 eventmachine  最擅长的领域,接触它最激动人心的特性。

    我们将构建一个 client ,连接到 Twitter’s streaming api ,每当有消息到达时,将触发一系列事件。 

    使用 Twitter’s streaming API ,你只需要开启一个活跃的长 HTTP 连接到stream.twitter.com,然后等待信息涌入。我们会再次使用到 em-http-request。连接到 API,监听所有的 tweets ,静待新的 twitter 到达,代码很简单:


    这里返回的是一个 deferrable (用于请求完成后触发相应回调函数), 实际上我们用到了另外一个技巧。 We can also register to be notified every time new data is received:

    让我们把代码组合起来,监听 tweets:


    返回信息类似如下:

    It works! Now say we wanted to lookup the language of each tweet using the class we built earlier. We could do this by adding further to our stream method, however this is the road to callback hell (and just imagine what it would be like if we hadn’t abstracted the language detection!).

    我们来重写优化部分代码。

    前面我们使用 deferrable 来抽离代码,用于处理异步事件返回的成功或失败。另外一个在 eventmachine 中广泛采用的通用技术是提供一个 onevent 回调。比如类似如下的接口代码:

    现在我们可以对代码进一步优化:

    同一处理流程中混合不同的 IO 

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • android学习轨迹之四:org.json.JSONException: No value for

      android学习轨迹之四:org.json.JSONException: No value for

      2017-12-12 08:27

    • 好好学习,改变自己

      好好学习,改变自己

      2017-12-10 15:00

    • 【学习】spring MVC之返回JSON数据(Spring3.0 MVC+Jackson+AJAX)

      【学习】spring MVC之返回JSON数据(Spring3.0 MVC+Jackson+AJAX)

      2017-12-10 12:01

    • taglib 学习

      taglib 学习

      2017-12-10 11:00

    网友点评