fmq 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +11 -0
- data/README.txt +17 -18
- data/default-server/config.ru +16 -16
- data/lib/fmq/admin.rb +0 -7
- data/lib/fmq/boot.rb +10 -18
- data/lib/fmq/queue_manager.rb +10 -15
- data/lib/fmq/queues/README.txt +4 -4
- data/lib/fmq/queues/base.rb +2 -1
- data/lib/fmq/queues/file.rb +12 -14
- data/lib/fmq/queues/file_persistent.rb +86 -0
- data/lib/fmq/queues/forward.rb +6 -8
- data/lib/fmq/queues/linked.rb +1 -1
- data/lib/fmq/queues/load_balanced.rb +8 -12
- data/lib/fmq/queues/syncronized.rb +11 -13
- data/lib/fmq/server.rb +0 -7
- data/lib/fmq/version.rb +1 -1
- data/lib/fmq.rb +8 -0
- data/test/test_basic.rb +9 -7
- data/test/test_file_persistent.rb +18 -0
- data/test/test_helper.rb +59 -1
- data/test/test_linked.rb +3 -57
- data/test/test_queue_manager.rb +8 -19
- metadata +15 -2
data/History.txt
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
== 0.3.2 2008-08-28
|
2
|
+
|
3
|
+
* 3 minor changes:
|
4
|
+
* changed the way of the queue manager setup
|
5
|
+
* updated rdoc, readme and website documentaition
|
6
|
+
* added a new queue that persists the messages in the file system
|
7
|
+
* 3 tiny changes:
|
8
|
+
* fixed the fmq logger creation
|
9
|
+
* some fixes to the queue manager and some queues
|
10
|
+
* refactored testing of fifo based queues
|
11
|
+
|
1
12
|
== 0.3.1 2008-08-27
|
2
13
|
|
3
14
|
* 2 minor changes:
|
data/README.txt
CHANGED
@@ -6,8 +6,6 @@ Project github repositiory: git://github.com/threez/fmq.git
|
|
6
6
|
|
7
7
|
== TODO:
|
8
8
|
|
9
|
-
* create full rdoc
|
10
|
-
* support of logging to file
|
11
9
|
* add client apis for other languages
|
12
10
|
* complete unit tests
|
13
11
|
|
@@ -15,21 +13,21 @@ Project github repositiory: git://github.com/threez/fmq.git
|
|
15
13
|
|
16
14
|
The project implements a queue system with a server and some client apis.
|
17
15
|
|
18
|
-
The server is a
|
19
|
-
You can GET, POST, DELETE, HEAD queue
|
20
|
-
The system itself uses a configuration
|
21
|
-
startup or even at runtime. The queue
|
22
|
-
|
16
|
+
The server is a rack server that holds REST-named queues, so that the
|
17
|
+
implemention can be changed rapidly. You can GET, POST, DELETE, HEAD queue
|
18
|
+
messages using the normal HTTP requests. The system itself uses a configuration
|
19
|
+
file (*config.ru*) to setup queues at startup or even at runtime. The queue
|
20
|
+
implementations can be changed or you can develep own queues with ease.
|
23
21
|
|
24
|
-
For an simple administration
|
22
|
+
For an simple administration try out the integrated ajax based web interface.
|
25
23
|
|
26
|
-
The client apis are implemented using the HTTP protocol, so that
|
27
|
-
|
24
|
+
The client apis are implemented using the HTTP protocol, so that you can
|
25
|
+
use even curl to receive messages. A client library for ruby is implemented
|
26
|
+
right now, other languages will follow.
|
28
27
|
|
29
|
-
The queue itself is
|
30
|
-
or http://localhost:5884/myApplication/myQueueName
|
31
|
-
this url with a web browser you will receive one message from the queue.
|
32
|
-
stores it’s internal data in an FIFO in system memory.
|
28
|
+
The queue itself is a RESTful url like @http://localhost:5884/myQueueName/@
|
29
|
+
or @http://localhost:5884/myApplication/myQueueName/@. If you do a GET request
|
30
|
+
to this url with a web browser you will receive one message from the queue.
|
33
31
|
|
34
32
|
== FEATURES/PROBLEMS:
|
35
33
|
|
@@ -46,16 +44,17 @@ stores it’s internal data in an FIFO in system memory.
|
|
46
44
|
After installing the gem you can start by creating a project:
|
47
45
|
|
48
46
|
fmq create my_project_name
|
47
|
+
|
49
48
|
next step is to change to the folder and start the FMQ server:
|
50
49
|
|
51
50
|
cd my_project_name
|
52
|
-
|
51
|
+
rackup -p 5884
|
53
52
|
|
54
|
-
The server will start and host a admin interface on http://localhost:5884/admin/index.
|
53
|
+
The server will start and host a admin interface on http://localhost:5884/admin/index.html.
|
55
54
|
|
56
55
|
== REQUIREMENTS:
|
57
56
|
|
58
|
-
*
|
57
|
+
* rack >= 0.4.0 (web server provider)
|
59
58
|
|
60
59
|
== INSTALL:
|
61
60
|
|
@@ -67,4 +66,4 @@ Just install the gem as you expect:
|
|
67
66
|
|
68
67
|
(GNU GENERAL PUBLIC LICENSE, Version 3)
|
69
68
|
|
70
|
-
Copyright (c) 2008 Vincent Landgraf
|
69
|
+
Copyright (c) 2008 Vincent Landgraf
|
data/default-server/config.ru
CHANGED
@@ -7,22 +7,13 @@ end
|
|
7
7
|
# load all local queues (from project directory)
|
8
8
|
Dir.glob("queues/*.rb").each { |f| require f }
|
9
9
|
|
10
|
-
# setup log level of free message queue
|
11
|
-
FreeMessageQueue.log_level("info")
|
12
|
-
|
13
10
|
# =====================================================
|
14
11
|
# create and configure the queue manager
|
15
12
|
# =====================================================
|
16
|
-
queue_manager = FreeMessageQueue::QueueManager.new()
|
17
13
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
# <em>auto_create_queues</em> is <b>true</b>. This
|
22
|
-
# is a useful option if you are in development,
|
23
|
-
# the queue will be a FreeMessageQueue::SyncronizedQueue by default
|
24
|
-
qm.auto_create_queues = true
|
25
|
-
|
14
|
+
# if someone pushes to a queue that don't exists
|
15
|
+
# the queue manager will create one for you if you pass true
|
16
|
+
queue_manager = FreeMessageQueue::QueueManager.new(true) do
|
26
17
|
# =====================================================
|
27
18
|
# if you want some queues right from startup
|
28
19
|
# define there url and constraints here
|
@@ -31,7 +22,7 @@ queue_manager.setup do |qm|
|
|
31
22
|
# the path to the queue e.g. /app1/myframe/test1
|
32
23
|
# means http://localhost:5884/app1/myframe/test1
|
33
24
|
# this parameter is not optional
|
34
|
-
|
25
|
+
setup_queue "/fmq_test/test1" do |q|
|
35
26
|
# this defines the maximum count of messages that
|
36
27
|
# can be in the queue, if the queue is full every
|
37
28
|
# new message will be rejected with a http error
|
@@ -46,19 +37,28 @@ queue_manager.setup do |qm|
|
|
46
37
|
|
47
38
|
# if you want you can specify the class of the queue
|
48
39
|
# this is interessting if you write your own queues
|
49
|
-
|
40
|
+
setup_queue "/fmq_test/test2", FreeMessageQueue::LoadBalancedQueue
|
50
41
|
|
51
42
|
# if you have special queues include put them into the queues
|
52
43
|
# folder and and use them (this MyTestQueue is places in queues/mytest.rb)
|
53
|
-
|
44
|
+
setup_queue "/fmq_test/test3", MyTestQueue
|
54
45
|
|
55
46
|
# this is a forwarding queue wich forwards one message
|
56
47
|
# to some other queues
|
57
|
-
|
48
|
+
setup_queue "/fmq_test/forward_to_1_and_2", FreeMessageQueue::ForwardQueue do |q|
|
58
49
|
# you can add as may queues as you want
|
59
50
|
# but seperate them with a space char
|
60
51
|
q.forward_to = ["/fmq_test/test1", "/fmq_test/test2"]
|
61
52
|
end
|
53
|
+
|
54
|
+
# this is a file system queue that will save each method
|
55
|
+
# in the file system until they are polled
|
56
|
+
# the message is useful if you want to have a queue that will
|
57
|
+
# save it's state so that you can reboot the server
|
58
|
+
setup_queue "/fmq_test/file_persistent", FreeMessageQueue::FilePersistentQueue do |q|
|
59
|
+
q.folder = "./tmp/mail_box/threez"
|
60
|
+
q.max_messages = 10_000
|
61
|
+
end
|
62
62
|
end
|
63
63
|
|
64
64
|
# =====================================================
|
data/lib/fmq/admin.rb
CHANGED
@@ -16,13 +16,6 @@
|
|
16
16
|
# You should have received a copy of the GNU General Public License
|
17
17
|
# along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
|
18
18
|
#
|
19
|
-
begin
|
20
|
-
require "rack"
|
21
|
-
rescue LoadError
|
22
|
-
require "rubygems"
|
23
|
-
require "rack"
|
24
|
-
end
|
25
|
-
|
26
19
|
module FreeMessageQueue
|
27
20
|
# This class is dedicated to the AJAX based admin interface.
|
28
21
|
class AdminInterface
|
data/lib/fmq/boot.rb
CHANGED
@@ -29,35 +29,27 @@ module FreeMessageQueue
|
|
29
29
|
# free message queue, so that it is simple to access
|
30
30
|
# the logger from somewhere in the project
|
31
31
|
def self.logger
|
32
|
-
$FMQ_GLOBAL_LOGGER ||= create_logger
|
32
|
+
$FMQ_GLOBAL_LOGGER ||= FreeMessageQueue.create_logger
|
33
33
|
end
|
34
34
|
|
35
35
|
# This method creates the logger instance once (even if it is called twice).
|
36
|
+
# it is by default on fatal
|
36
37
|
def self.create_logger(log_to = STDOUT)
|
37
38
|
$FMQ_GLOBAL_LOGGER ||= Logger.new(log_to)
|
39
|
+
FreeMessageQueue.log_level(:fatal)
|
40
|
+
return $FMQ_GLOBAL_LOGGER
|
38
41
|
end
|
39
42
|
|
40
43
|
# This method sets the log level of the fmq logger
|
41
44
|
# the level must be a string (either downcase or upcase)
|
42
45
|
# that contains one of the following levels:
|
43
|
-
# *
|
44
|
-
# *
|
45
|
-
# *
|
46
|
-
# *
|
47
|
-
# *
|
46
|
+
# * :fatal => Server side errors
|
47
|
+
# * :error => Server side error backtraces
|
48
|
+
# * :warn => Client side errors
|
49
|
+
# * :info => Setup information (config stuff etc.)
|
50
|
+
# * :debug => All operations of the queue manager and others
|
48
51
|
def self.log_level(level)
|
49
|
-
|
50
|
-
when /fatal/i
|
51
|
-
FreeMessageQueue.logger.level = Logger::FATAL
|
52
|
-
when /error/i
|
53
|
-
FreeMessageQueue.logger.level = Logger::ERROR
|
54
|
-
when /warn/i
|
55
|
-
FreeMessageQueue.logger.level = Logger::WARN
|
56
|
-
when /info/i
|
57
|
-
FreeMessageQueue.logger.level = Logger::INFO
|
58
|
-
when /debug/i
|
59
|
-
FreeMessageQueue.logger.level = Logger::DEBUG
|
60
|
-
end
|
52
|
+
FreeMessageQueue.logger.level = eval("Logger::#{level.to_s.upcase}")
|
61
53
|
FreeMessageQueue.logger.debug "[Logger] set log level to #{level}"
|
62
54
|
end
|
63
55
|
|
data/lib/fmq/queue_manager.rb
CHANGED
@@ -15,8 +15,7 @@
|
|
15
15
|
#
|
16
16
|
# You should have received a copy of the GNU General Public License
|
17
17
|
# along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
|
18
|
-
#
|
19
|
-
require "ostruct"
|
18
|
+
#
|
20
19
|
|
21
20
|
# add kb, mb and gb methods for easy use in the config file
|
22
21
|
class Fixnum
|
@@ -64,10 +63,11 @@ module FreeMessageQueue
|
|
64
63
|
|
65
64
|
# setup the queue manager using the configuration from the configuration
|
66
65
|
# file (which is basically a hash)
|
67
|
-
def initialize()
|
66
|
+
def initialize(auto_create_queues = true, &block)
|
68
67
|
@queues = {}
|
69
68
|
@log = FreeMessageQueue.logger
|
70
|
-
@auto_create_queues =
|
69
|
+
@auto_create_queues = auto_create_queues
|
70
|
+
instance_eval(&block) if block_given?
|
71
71
|
end
|
72
72
|
|
73
73
|
# returns if the creation of queues should be done on demand
|
@@ -78,12 +78,10 @@ module FreeMessageQueue
|
|
78
78
|
|
79
79
|
# create a queue using a block. The block can be used to set configuration
|
80
80
|
# options for the queue
|
81
|
-
def setup_queue(path, queue_class = DEFAULT_QUEUE_CLASS)
|
81
|
+
def setup_queue(path, queue_class = DEFAULT_QUEUE_CLASS, &block)
|
82
82
|
check_queue_name(path)
|
83
83
|
queue_object = queue_class.new(self)
|
84
|
-
if block_given?
|
85
|
-
yield queue_object
|
86
|
-
end
|
84
|
+
block.call(queue_object) if block_given?
|
87
85
|
@queues[path] = queue_object
|
88
86
|
@log.info("[QueueManager] Create queue '#{path}' {type: #{queue_class}, max_messages: #{queue_object.max_messages}, max_size: #{queue_object.max_size}}")
|
89
87
|
return queue_object
|
@@ -93,7 +91,7 @@ module FreeMessageQueue
|
|
93
91
|
def delete_queue(name)
|
94
92
|
if queue_exists? name
|
95
93
|
@log.info("[QueueManager] Delete queue '#{name}' with #{queue(name).size} messages")
|
96
|
-
queue(name).clear
|
94
|
+
queue(name).clear if queue(name).respond_to? :clear
|
97
95
|
@queues.delete name
|
98
96
|
true
|
99
97
|
else
|
@@ -126,7 +124,7 @@ module FreeMessageQueue
|
|
126
124
|
unless queue_exists? name
|
127
125
|
# only auto create queues if it is configured
|
128
126
|
if auto_create_queues?
|
129
|
-
|
127
|
+
setup_queue(name)
|
130
128
|
else
|
131
129
|
raise QueueManagerException.new("[QueueManager] There is no queue '#{name}'", caller)
|
132
130
|
end
|
@@ -152,11 +150,7 @@ module FreeMessageQueue
|
|
152
150
|
!queue(name).nil?
|
153
151
|
end
|
154
152
|
|
155
|
-
#
|
156
|
-
def setup(&config)
|
157
|
-
config.call(self)
|
158
|
-
end
|
159
|
-
|
153
|
+
# returns the queue qith the passed name
|
160
154
|
def queue(name)
|
161
155
|
return @queues[name]
|
162
156
|
end
|
@@ -177,3 +171,4 @@ module FreeMessageQueue
|
|
177
171
|
end
|
178
172
|
end
|
179
173
|
end
|
174
|
+
|
data/lib/fmq/queues/README.txt
CHANGED
@@ -4,7 +4,7 @@ Read this simple description on how to create a queue for your special purpose.
|
|
4
4
|
First of all, this template is where you start.
|
5
5
|
1. You have to create a class that is meanful and ends up with "Queue" (for naming convention) e.g. "MyTestQueue"
|
6
6
|
2. Name your file to the name of the queue. In this example we have the queue "MyTestQueue"
|
7
|
-
so the file will be "my_test.rb". Save your new file to the queue folder of your projects folder "queues/my_test.rb"
|
7
|
+
so the file will be "my_test.rb". Save your new file to the queue folder of your projects folder "./queues/my_test.rb"
|
8
8
|
3. Change the queue implementation to something you like
|
9
9
|
* every queue must have an <em>manager</em>. (for this just inherit from FreeMessageQueue::BaseQueue)
|
10
10
|
* this manager must be able to read <em>bytes</em> and <em>size</em> (for this just inherit from FreeMessageQueue::BaseQueue)
|
@@ -21,7 +21,7 @@ First of all, this template is where you start.
|
|
21
21
|
|
22
22
|
def poll
|
23
23
|
FreeMessageQueue::Message.new "Hello World", "text/plain" do |m|
|
24
|
-
|
25
|
-
|
24
|
+
m.option["Time"] = Time.now
|
25
|
+
end
|
26
26
|
end
|
27
|
-
end
|
27
|
+
end
|
data/lib/fmq/queues/base.rb
CHANGED
data/lib/fmq/queues/file.rb
CHANGED
@@ -22,23 +22,21 @@ module FreeMessageQueue
|
|
22
22
|
# This queue returns everytime the same file. This is useful during debugging or
|
23
23
|
# to serve the admin page.
|
24
24
|
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
# class: FreeMessageQueue::FileQueue
|
32
|
-
# file: admin-interface/index.html
|
33
|
-
# content-type: text/html
|
25
|
+
# queue_manager = FreeMessageQueue::QueueManager.new(true) do
|
26
|
+
# setup_queue "/dummy/file", FreeMessageQueue::FileQueue do |q|
|
27
|
+
# q.file = "tmp/default_message.yml"
|
28
|
+
# q.content_type = "text/yaml"
|
29
|
+
# end
|
30
|
+
# end
|
34
31
|
#
|
35
32
|
# *NOTE* the put method is not implemented in this queue. It is a poll only queue.
|
36
33
|
class FileQueue < BaseQueue
|
37
34
|
# Return the file and content type
|
38
|
-
def poll()
|
39
|
-
|
40
|
-
|
41
|
-
|
35
|
+
def poll()
|
36
|
+
file_content = ""
|
37
|
+
File.open(@file_path, "rb") do |f|
|
38
|
+
file_content = f.read
|
39
|
+
end
|
42
40
|
|
43
41
|
@bytes = file_content.size
|
44
42
|
Message.new(file_content, @content_type)
|
@@ -57,4 +55,4 @@ module FreeMessageQueue
|
|
57
55
|
@content_type = type
|
58
56
|
end
|
59
57
|
end
|
60
|
-
end
|
58
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2008 Vincent Landgraf
|
3
|
+
#
|
4
|
+
# This file is part of the Free Message Queue.
|
5
|
+
#
|
6
|
+
# Free Message Queue is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU General Public License as published by
|
8
|
+
# the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# Free Message Queue is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU General Public License
|
17
|
+
# along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#
|
19
|
+
require File.dirname(__FILE__) + '/base'
|
20
|
+
require "fileutils"
|
21
|
+
|
22
|
+
module FreeMessageQueue
|
23
|
+
# This a FIFO queue that stores messages in the file system
|
24
|
+
#
|
25
|
+
# queue_manager = FreeMessageQueue::QueueManager.new(true) do
|
26
|
+
# setup_queue "/mail_box/threez", FreeMessageQueue::FilePersistentQueue do |q|
|
27
|
+
# q.folder = "./tmp/mail_box/threez"
|
28
|
+
# q.max_messages = 10000
|
29
|
+
# end
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# *NOTE* the put method is not implemented in this queue. It is a poll only queue.
|
33
|
+
class FilePersistentQueue < BaseQueue
|
34
|
+
# Return the
|
35
|
+
def poll()
|
36
|
+
check_folder_name
|
37
|
+
messages = all_messages.sort!
|
38
|
+
return nil if messages.size == 0
|
39
|
+
|
40
|
+
msg_bin = File.open(messages.first, "rb") { |f| f.read }
|
41
|
+
FileUtils.rm messages.first
|
42
|
+
remove_message(Marshal.load(msg_bin))
|
43
|
+
end
|
44
|
+
|
45
|
+
# add one message to the queue (will be saved in file system)
|
46
|
+
def put(message)
|
47
|
+
check_folder_name
|
48
|
+
return false if message.nil?
|
49
|
+
|
50
|
+
add_message(message) # check constraints and update stats
|
51
|
+
|
52
|
+
msg_bin = Marshal.dump(message)
|
53
|
+
File.open(@folder_path + "/#{Time.now.to_f}.msg", "wb") do |f|
|
54
|
+
f.write msg_bin
|
55
|
+
end
|
56
|
+
return true
|
57
|
+
end
|
58
|
+
|
59
|
+
# *CONFIGURATION* *OPTION*
|
60
|
+
# sets the path to the folder that holds all messages, this will
|
61
|
+
# create the folder if it doesn't exist
|
62
|
+
def folder=(path)
|
63
|
+
FileUtils.mkdir_p path unless File.exist? path
|
64
|
+
@folder_path = path
|
65
|
+
end
|
66
|
+
|
67
|
+
# remove all items from the queue
|
68
|
+
def clear
|
69
|
+
FileUtils.rm all_messages
|
70
|
+
@size = 0
|
71
|
+
@bytes = 0
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
# returns an array with all paths to queue messages
|
77
|
+
def all_messages
|
78
|
+
Dir[@folder_path + "/*.msg"]
|
79
|
+
end
|
80
|
+
|
81
|
+
# raise an exceptin if the folder name is not set
|
82
|
+
def check_folder_name
|
83
|
+
raise QueueException.new("[FilePersistentQueue] The folder_path need to be specified", caller) if @folder_path.nil?
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
data/lib/fmq/queues/forward.rb
CHANGED
@@ -20,14 +20,12 @@ require File.dirname(__FILE__) + '/base'
|
|
20
20
|
|
21
21
|
module FreeMessageQueue
|
22
22
|
# This queue returns sends one message to several queues at a time.
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# class: FreeMessageQueue::ForwardQueue
|
30
|
-
# forward_to: /fmq_test/test1 /fmq_test/test2
|
23
|
+
#
|
24
|
+
# queue_manager = FreeMessageQueue::QueueManager.new(true) do
|
25
|
+
# setup_queue "/fmq_test/forward_to_1_and_2", FreeMessageQueue::ForwardQueue do |q|
|
26
|
+
# q.forward_to = ["/fmq_test/test1", "/fmq_test/test2"]
|
27
|
+
# end
|
28
|
+
# end
|
31
29
|
#
|
32
30
|
# *NOTE* the poll method is not implemented in this queue. It is a put only queue.
|
33
31
|
class ForwardQueue < BaseQueue
|
data/lib/fmq/queues/linked.rb
CHANGED
@@ -22,16 +22,12 @@ module FreeMessageQueue
|
|
22
22
|
# This queue is an approach to the issue that you want to have
|
23
23
|
# multiple threads at one queue at a time. Currently this is not
|
24
24
|
# considered to be a stable queue. Just use it for experimental things.
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
# path: /fmq_test/test1
|
32
|
-
# max-messages: 1000000
|
33
|
-
# max-size: 10kb
|
34
|
-
# class: FreeMessageQueue::LoadBalancedQueue
|
25
|
+
#
|
26
|
+
# queue_manager = FreeMessageQueue::QueueManager.new(true) do
|
27
|
+
# setup_queue "/fmq_test/test1", FreeMessageQueue::LoadBalancedQueue do |q|
|
28
|
+
# q.forward_to = ["/fmq_test/test1", "/fmq_test/test2"]
|
29
|
+
# end
|
30
|
+
# end
|
35
31
|
class LoadBalancedQueue
|
36
32
|
# QueueManager refrence
|
37
33
|
attr_accessor :manager
|
@@ -71,8 +67,8 @@ module FreeMessageQueue
|
|
71
67
|
end
|
72
68
|
|
73
69
|
# Put an item to one of the queues
|
74
|
-
def put(
|
75
|
-
@queues[next_put_index].put(
|
70
|
+
def put(message)
|
71
|
+
@queues[next_put_index].put(message)
|
76
72
|
end
|
77
73
|
|
78
74
|
# queue has infinite count
|
@@ -22,15 +22,13 @@ require File.dirname(__FILE__) + '/linked'
|
|
22
22
|
module FreeMessageQueue
|
23
23
|
# The SyncronizedQueue implements a little wrapper around the
|
24
24
|
# LinkedQueue to make it thread safe
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
# max-messages: 1000000
|
33
|
-
# max-size: 10kb
|
25
|
+
#
|
26
|
+
# queue_manager = FreeMessageQueue::QueueManager.new(true) do
|
27
|
+
# setup_queue "/fmq_test/test1" do |q|
|
28
|
+
# q.max_messages = 1000000
|
29
|
+
# q.max_size = 10.kb
|
30
|
+
# end
|
31
|
+
# end
|
34
32
|
class SyncronizedQueue < LinkedQueue
|
35
33
|
|
36
34
|
def initialize(manager)
|
@@ -45,11 +43,11 @@ module FreeMessageQueue
|
|
45
43
|
}
|
46
44
|
end
|
47
45
|
|
48
|
-
# Puts one
|
49
|
-
def put(
|
46
|
+
# Puts one message to the queue
|
47
|
+
def put(message)
|
50
48
|
@semaphore.synchronize {
|
51
|
-
super(
|
49
|
+
super(message)
|
52
50
|
}
|
53
51
|
end
|
54
52
|
end
|
55
|
-
end
|
53
|
+
end
|
data/lib/fmq/server.rb
CHANGED
@@ -17,13 +17,6 @@
|
|
17
17
|
# You should have received a copy of the GNU General Public License
|
18
18
|
# along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
|
19
19
|
#
|
20
|
-
begin
|
21
|
-
require "rack"
|
22
|
-
rescue LoadError
|
23
|
-
require "rubygems"
|
24
|
-
require "rack"
|
25
|
-
end
|
26
|
-
|
27
20
|
module FreeMessageQueue
|
28
21
|
# This implements server that plugs the free message queue into a rack enviroment
|
29
22
|
class Server
|
data/lib/fmq/version.rb
CHANGED
data/lib/fmq.rb
CHANGED
@@ -17,6 +17,14 @@
|
|
17
17
|
# along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
|
18
18
|
#
|
19
19
|
|
20
|
+
# load the rack enviroment
|
21
|
+
begin
|
22
|
+
require "rack"
|
23
|
+
rescue LoadError
|
24
|
+
require "rubygems"
|
25
|
+
require "rack"
|
26
|
+
end
|
27
|
+
|
20
28
|
# load all queues and manager and server
|
21
29
|
Dir.glob(File.dirname(__FILE__) + "/fmq/queues/*.rb").each do |file|
|
22
30
|
require file
|
data/test/test_basic.rb
CHANGED
@@ -27,19 +27,21 @@ end
|
|
27
27
|
|
28
28
|
class BaseQueue < Test::Unit::TestCase
|
29
29
|
def setup
|
30
|
-
@manager = FreeMessageQueue::QueueManager.new()
|
31
|
-
|
32
|
-
|
33
|
-
@queue1 = m.setup_queue "/dummy1"
|
34
|
-
@queue2 = m.setup_queue "/dummy2" do |q|
|
30
|
+
@manager = FreeMessageQueue::QueueManager.new() do
|
31
|
+
setup_queue "/dummy1"
|
32
|
+
setup_queue "/dummy2" do |q|
|
35
33
|
q.max_messages = 100
|
36
34
|
q.max_size = 100.kb
|
37
35
|
end
|
38
|
-
|
36
|
+
setup_queue "/dummy3" do |q|
|
39
37
|
q.max_size = 0
|
40
38
|
q.max_messages = -10
|
41
39
|
end
|
42
40
|
end
|
41
|
+
|
42
|
+
@queue1 = @manager.queue "/dummy1"
|
43
|
+
@queue2 = @manager.queue "/dummy2"
|
44
|
+
@queue3 = @manager.queue "/dummy3"
|
43
45
|
end
|
44
46
|
|
45
47
|
def test_creating
|
@@ -83,4 +85,4 @@ class BaseQueue < Test::Unit::TestCase
|
|
83
85
|
@queue2.put(new_msg("X" * 10.kb))
|
84
86
|
end
|
85
87
|
end
|
86
|
-
end
|
88
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/test_helper.rb'
|
2
|
+
require "fileutils"
|
3
|
+
|
4
|
+
# This is the default test to the message interface
|
5
|
+
class TestFilePersistentQueue < Test::Unit::TestCase
|
6
|
+
include FifoQueueTests
|
7
|
+
|
8
|
+
def setup
|
9
|
+
manager = nil # the manager is not needed in this test
|
10
|
+
@queue = FreeMessageQueue::FilePersistentQueue.new(manager)
|
11
|
+
@queue.folder = "/tmp/fmq/FilePersistentQueue/testqueue"
|
12
|
+
end
|
13
|
+
|
14
|
+
def teardown
|
15
|
+
# remove the test data
|
16
|
+
FileUtils.rm_rf "/tmp/fmq"
|
17
|
+
end
|
18
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -3,4 +3,62 @@ require File.dirname(__FILE__) + '/../lib/fmq'
|
|
3
3
|
|
4
4
|
def new_msg(payload)
|
5
5
|
FreeMessageQueue::Message.new(payload)
|
6
|
-
end
|
6
|
+
end
|
7
|
+
|
8
|
+
module FifoQueueTests
|
9
|
+
def test_basic_get_poll
|
10
|
+
assert_nil @queue.poll
|
11
|
+
assert_equal 0, @queue.size
|
12
|
+
assert @queue.put(nil) == false
|
13
|
+
assert_nil @queue.poll
|
14
|
+
td_1 = new_msg("asdasd")
|
15
|
+
assert @queue.put(td_1)
|
16
|
+
assert_equal 1, @queue.size
|
17
|
+
assert_equal td_1.payload, @queue.poll.payload
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_n_messages
|
21
|
+
n = 20
|
22
|
+
byte_size = 0
|
23
|
+
n.times { |t| byte_size += t.to_s.size }
|
24
|
+
|
25
|
+
assert_equal 0, @queue.bytes
|
26
|
+
assert_nil @queue.poll
|
27
|
+
n.times do |i|
|
28
|
+
assert @queue.put(new_msg(i.to_s))
|
29
|
+
end
|
30
|
+
assert_equal byte_size, @queue.bytes
|
31
|
+
assert_equal n, @queue.size
|
32
|
+
n.times do |i|
|
33
|
+
assert_equal i.to_s, @queue.poll.payload
|
34
|
+
end
|
35
|
+
assert_equal 0, @queue.bytes
|
36
|
+
assert_nil @queue.poll
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_mam_messages
|
40
|
+
@queue.put(new_msg("asd"))
|
41
|
+
@queue.put(new_msg("asd"))
|
42
|
+
@queue.poll()
|
43
|
+
@queue.put(new_msg("asd"))
|
44
|
+
@queue.put(new_msg("asd"))
|
45
|
+
@queue.poll()
|
46
|
+
@queue.put(new_msg("asd"))
|
47
|
+
@queue.poll()
|
48
|
+
assert_equal 2, @queue.size
|
49
|
+
@queue.put(new_msg("asd"))
|
50
|
+
@queue.put(new_msg("asd"))
|
51
|
+
assert_equal 4, @queue.size
|
52
|
+
@queue.clear
|
53
|
+
assert_equal 0, @queue.size
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_queue_bytes
|
57
|
+
@queue.put(new_msg("XX" * 40))
|
58
|
+
@queue.put(new_msg("X" * 40))
|
59
|
+
@queue.put(new_msg("XX888" * 40))
|
60
|
+
assert_equal 2*40+40+5*40, @queue.bytes
|
61
|
+
@queue.clear
|
62
|
+
assert_equal 0, @queue.bytes
|
63
|
+
end
|
64
|
+
end
|
data/test/test_linked.rb
CHANGED
@@ -2,64 +2,10 @@ require File.dirname(__FILE__) + '/test_helper.rb'
|
|
2
2
|
|
3
3
|
# This is the default test to the message interface
|
4
4
|
class TestLinkedQueue < Test::Unit::TestCase
|
5
|
+
include FifoQueueTests
|
6
|
+
|
5
7
|
def setup
|
6
8
|
manager = nil # the manager is not needed in this test
|
7
9
|
@queue = FreeMessageQueue::LinkedQueue.new(manager)
|
8
10
|
end
|
9
|
-
|
10
|
-
def test_basic_get_poll
|
11
|
-
assert_nil @queue.poll
|
12
|
-
assert_equal 0, @queue.size
|
13
|
-
assert @queue.put(nil) == false
|
14
|
-
assert_nil @queue.poll
|
15
|
-
td_1 = new_msg("asdasd")
|
16
|
-
assert @queue.put(td_1)
|
17
|
-
assert_equal 1, @queue.size
|
18
|
-
assert_equal td_1.payload, @queue.poll.payload
|
19
|
-
end
|
20
|
-
|
21
|
-
def test_n_messages
|
22
|
-
n = 20
|
23
|
-
byte_size = 0
|
24
|
-
n.times { |t| byte_size += t.to_s.size }
|
25
|
-
|
26
|
-
assert_equal 0, @queue.bytes
|
27
|
-
assert_nil @queue.poll
|
28
|
-
n.times do |i|
|
29
|
-
assert @queue.put(new_msg(i.to_s))
|
30
|
-
end
|
31
|
-
assert_equal byte_size, @queue.bytes
|
32
|
-
assert_equal n, @queue.size
|
33
|
-
n.times do |i|
|
34
|
-
assert_equal i.to_s, @queue.poll.payload
|
35
|
-
end
|
36
|
-
assert_equal 0, @queue.bytes
|
37
|
-
assert_nil @queue.poll
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_mam_messages
|
41
|
-
@queue.put(new_msg("asd"))
|
42
|
-
@queue.put(new_msg("asd"))
|
43
|
-
@queue.poll()
|
44
|
-
@queue.put(new_msg("asd"))
|
45
|
-
@queue.put(new_msg("asd"))
|
46
|
-
@queue.poll()
|
47
|
-
@queue.put(new_msg("asd"))
|
48
|
-
@queue.poll()
|
49
|
-
assert_equal 2, @queue.size
|
50
|
-
@queue.put(new_msg("asd"))
|
51
|
-
@queue.put(new_msg("asd"))
|
52
|
-
assert_equal 4, @queue.size
|
53
|
-
@queue.clear
|
54
|
-
assert_equal 0, @queue.size
|
55
|
-
end
|
56
|
-
|
57
|
-
def test_queue_bytes
|
58
|
-
@queue.put(new_msg("XX" * 40))
|
59
|
-
@queue.put(new_msg("X" * 40))
|
60
|
-
@queue.put(new_msg("XX888" * 40))
|
61
|
-
assert_equal 2*40+40+5*40, @queue.bytes
|
62
|
-
@queue.clear
|
63
|
-
assert_equal 0, @queue.bytes
|
64
|
-
end
|
65
|
-
end
|
11
|
+
end
|
data/test/test_queue_manager.rb
CHANGED
@@ -5,34 +5,22 @@ class TestQueueManager < Test::Unit::TestCase
|
|
5
5
|
DEFAULT_QUEUE_NAME = "/fmq_test/test1"
|
6
6
|
|
7
7
|
def setup
|
8
|
-
FreeMessageQueue.
|
9
|
-
|
10
|
-
@queue_manager = FreeMessageQueue::QueueManager.new()
|
11
|
-
|
12
|
-
@queue_manager.setup do |qm|
|
13
|
-
qm.auto_create_queues = false
|
14
|
-
|
15
|
-
qm.setup_queue DEFAULT_QUEUE_NAME do |q|
|
8
|
+
@queue_manager = FreeMessageQueue::QueueManager.new(false) do
|
9
|
+
setup_queue DEFAULT_QUEUE_NAME do |q|
|
16
10
|
q.max_messages = 100
|
17
11
|
q.max_size = 100.mb
|
18
12
|
end
|
19
13
|
|
20
|
-
|
21
|
-
|
14
|
+
setup_queue "/second_test_queue"
|
15
|
+
setup_queue "/third_test_queue"
|
22
16
|
end
|
23
17
|
end
|
24
18
|
|
25
|
-
def test_config
|
26
|
-
# check that the simple config will work
|
27
|
-
FreeMessageQueue::QueueManager.new()
|
28
|
-
@queue_manager.setup do |qm|
|
29
|
-
qm.auto_create_queues = false
|
30
|
-
end
|
31
|
-
|
19
|
+
def test_config
|
32
20
|
# check if all queues are available
|
33
21
|
assert_equal 3, @queue_manager.queues.size
|
34
22
|
[DEFAULT_QUEUE_NAME, "/second_test_queue", "/third_test_queue"].each do |e|
|
35
|
-
assert @queue_manager.queues.include?
|
23
|
+
assert @queue_manager.queues.include?(e)
|
36
24
|
end
|
37
25
|
end
|
38
26
|
|
@@ -84,4 +72,5 @@ class TestQueueManager < Test::Unit::TestCase
|
|
84
72
|
@queue_manager.put(url, new_msg("Test"))
|
85
73
|
}
|
86
74
|
end
|
87
|
-
end
|
75
|
+
end
|
76
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fmq
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vincent Landgraf
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-08-
|
12
|
+
date: 2008-08-28 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -22,6 +22,16 @@ dependencies:
|
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: 0.4.0
|
24
24
|
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: hoe
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.7.0
|
34
|
+
version:
|
25
35
|
description: The project implements a queue system with a server and some client apis. This project wants to be a fast and lightweight implementation with most of the features of MQS or ActiveMQ.
|
26
36
|
email:
|
27
37
|
- fmq-3z@gmx.net
|
@@ -63,12 +73,14 @@ files:
|
|
63
73
|
- lib/fmq/queues/linked.rb
|
64
74
|
- lib/fmq/queues/load_balanced.rb
|
65
75
|
- lib/fmq/queues/syncronized.rb
|
76
|
+
- lib/fmq/queues/file_persistent.rb
|
66
77
|
- lib/fmq/version.rb
|
67
78
|
- test/test_basic.rb
|
68
79
|
- test/test_fmq_client.rb
|
69
80
|
- test/test_helper.rb
|
70
81
|
- test/test_linked.rb
|
71
82
|
- test/test_queue_manager.rb
|
83
|
+
- test/test_file_persistent.rb
|
72
84
|
has_rdoc: true
|
73
85
|
homepage: http://fmq.rubyforge.org
|
74
86
|
post_install_message: |-
|
@@ -101,6 +113,7 @@ specification_version: 2
|
|
101
113
|
summary: The project implements a queue system with a server and some client apis. This project wants to be a fast and lightweight implementation with most of the features of MQS or ActiveMQ.
|
102
114
|
test_files:
|
103
115
|
- test/test_basic.rb
|
116
|
+
- test/test_file_persistent.rb
|
104
117
|
- test/test_fmq_client.rb
|
105
118
|
- test/test_helper.rb
|
106
119
|
- test/test_linked.rb
|