tinymq学习小结

学了tinymq,

先将它的README翻译了一下:

TinyMQ - A diminutive message queue (TinyMQ ---一个小型的消息队列)

TinyMQ是一个为erlang实现的基于频道的内存消息队列。频道被字符串标识(任何你想的字符串),同时根据需要自动创建和销毁。每一个频道都被一个gen_server进程管理。理论上,每一个频道进程属于一个erlang集群的不同节点,但是现在的代码中,他们都属于TinyMQ启动的那个进程节点。

启动队列:application:start(tinymq), % the max_age 环境变量定义了消息的默认超时时间,单位秒,默认值为60。

推送消息到一个频道:tinymq:push("some-channel", <<"Hello, world!">>),

检查某个频道是否存在消息:

Timestamp = tinymq:now("some-channel"), %获取时间戳,新消息要大于这个值

{ok, NewTimestamp, Messages} = tinymq:poll("some-channel", Timestamp), %获取消息和新时间戳

时间戳是个很重要的API设计,通过使用返回的时间戳NewTimeStamp,你能够确保收到管道的所有消息,并且没有重复。

此外,轮询一个频道可以为进程订阅某个频道,一旦消息到达,能够收到任何发送给此频道的消息。

tinymq:subscribe("some-channel", now, self()),

%now是个原子或者是个时间戳,self()表示收到消息的那个进程

receive

{_From, Timestamp, Messages} ->

io:format("Received messages: ~p~n", [Messages])

end

每个频道都有不限制的订阅者。一旦第一条消息被发送,订阅者就会从频道中移除,因此,为了保持订阅者活跃有效,你需要通过返回的时间戳作为下一次调用的输入来重新订阅。

本质上,消息存储在一个优先级队列中,任何频道活跃之后都会清空旧的消息(但是不超过每秒一次),

开销是O(log(M) + E),M是在一个频道中的消息总数,E是一个频道中,自从上一次消息到期时间到现在的消息数目。用更好的数据结构,可能会提升到O(log(M)),但需要注意,垃圾回收器将不得不执行O(E)的操作。因此额外的开销可能不值得我们为此失眠。

在最大默认超时时间之后一直没有活动频道将被销毁,因为旧消息只有当频道活跃的时候才会被销毁,一些消息存在内存中超过2*max_age秒数(比如最后一个频道活跃发生时\epsilon秒之前,消息被设置成到期)。

一个频道的新消息被连续地发送到所有频道的订阅者中,通过适当的并行运行,时间可能提升到O(S/K),S是订阅者的数量,K是内核数量。但是这需要做些工作。

 

posted @ 2013-07-21 23:54  ..孔雀翎..  阅读(441)  评论(0编辑  收藏  举报