fmq 0.2.0 → 0.3.0
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 +15 -1
- data/README.txt +2 -1
- data/bin/fmq +3 -6
- data/config/hoe.rb +3 -3
- data/default-server/admin-interface/index.html +45 -235
- data/default-server/admin-interface/javascript/application.js +127 -0
- data/default-server/admin-interface/stylesheets/application.css +61 -0
- data/default-server/config.ru +86 -0
- data/lib/fmq/admin.rb +96 -0
- data/lib/fmq/boot.rb +6 -60
- data/lib/fmq/queue_manager.rb +43 -50
- data/lib/fmq/queues/forward.rb +2 -2
- data/lib/fmq/server.rb +144 -0
- data/lib/fmq/version.rb +1 -1
- data/lib/fmq.rb +2 -7
- data/test/test_queue_manager.rb +16 -23
- metadata +19 -8
- data/default-server/config.yml +0 -74
- data/lib/fmq/mongrel_server.rb +0 -172
- data/lib/fmq/queues/admin.rb +0 -94
- /data/default-server/admin-interface/{prototype.js → javascript/prototype.js} +0 -0
data/lib/fmq/admin.rb
ADDED
@@ -0,0 +1,96 @@
|
|
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
|
+
begin
|
20
|
+
require "rack"
|
21
|
+
rescue LoadError
|
22
|
+
require "rubygems"
|
23
|
+
require "rack"
|
24
|
+
end
|
25
|
+
|
26
|
+
module FreeMessageQueue
|
27
|
+
# This class is dedicated to the AJAX based admin interface.
|
28
|
+
class AdminInterface
|
29
|
+
# rack response for bad requests
|
30
|
+
WRONG_METHOD = [400, {"CONTENT-TYPE" => "text/plain", "ERROR" => "Wrong http Method"}, ""]
|
31
|
+
|
32
|
+
# rack response for good requests
|
33
|
+
OK = [200, {"CONTENT-TYPE" => "text/plain"}, ["ok"]]
|
34
|
+
|
35
|
+
# create the admin interface for the passed QueueManager
|
36
|
+
def initialize(queue_manager)
|
37
|
+
@manager = queue_manager
|
38
|
+
@log = FreeMessageQueue.logger
|
39
|
+
end
|
40
|
+
|
41
|
+
# handle all requests
|
42
|
+
def call(env)
|
43
|
+
begin
|
44
|
+
request = Rack::Request.new(env)
|
45
|
+
@log.debug "[AdminInterface] ENV: #{env.inspect}"
|
46
|
+
|
47
|
+
if request.get? then
|
48
|
+
@log.info "[AdminInterface] list queues"
|
49
|
+
# ======= LIST QUEUES
|
50
|
+
queues_code = []
|
51
|
+
@manager.queues.each do |queue_name|
|
52
|
+
queues_code << queue_to_json(queue_name)
|
53
|
+
end
|
54
|
+
|
55
|
+
return [200, {"CONTENT-TYPE" => "application/json"}, ["[%s]" % queues_code.join(","), ]]
|
56
|
+
elsif request.post? then
|
57
|
+
if request["_method"] == "delete" then
|
58
|
+
# ======= DELETE QUEUE
|
59
|
+
@log.info "[AdminInterface] delete queue"
|
60
|
+
@manager.delete_queue(request["path"])
|
61
|
+
return OK
|
62
|
+
elsif request["_method"] == "create"
|
63
|
+
# ======= CREATE QUEUE
|
64
|
+
@log.info "[AdminInterface] create queue"
|
65
|
+
@manager.create_queue(request["path"],
|
66
|
+
request["max_messages"].gsub("null", "-1").to_i,
|
67
|
+
request["max_size"].gsub("null", "-1").to_i)
|
68
|
+
return OK
|
69
|
+
else
|
70
|
+
return WRONG_METHOD
|
71
|
+
end
|
72
|
+
else
|
73
|
+
return WRONG_METHOD
|
74
|
+
end
|
75
|
+
rescue QueueManagerException => ex
|
76
|
+
return [400, {"CONTENT-TYPE" => "text/plain", "ERROR" => ex.message}, [ex.message]]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# converts the data of one queue to json format
|
83
|
+
def queue_to_json(queue_name)
|
84
|
+
constraints = @manager.queue_constraints[queue_name]
|
85
|
+
|
86
|
+
"[\"%s\", %d, %d, %d, %d]" % [
|
87
|
+
queue_name,
|
88
|
+
@manager.queue[queue_name].bytes,
|
89
|
+
constraints[:max_size],
|
90
|
+
@manager.queue[queue_name].size,
|
91
|
+
constraints[:max_messages],
|
92
|
+
]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
data/lib/fmq/boot.rb
CHANGED
@@ -16,13 +16,10 @@
|
|
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
|
-
require 'yaml'
|
20
19
|
require 'logger'
|
21
|
-
require 'fileutils'
|
22
20
|
|
23
21
|
require File.dirname(__FILE__) + '/version'
|
24
22
|
require File.dirname(__FILE__) + '/queue_manager'
|
25
|
-
require File.dirname(__FILE__) + '/mongrel_server'
|
26
23
|
|
27
24
|
module FreeMessageQueue
|
28
25
|
# This is the standard server header that will be used by mongel and other web servers
|
@@ -32,7 +29,7 @@ module FreeMessageQueue
|
|
32
29
|
# free message queue, so that it is simple to access
|
33
30
|
# the logger from somewhere in the project
|
34
31
|
def self.logger
|
35
|
-
$FMQ_GLOBAL_LOGGER
|
32
|
+
$FMQ_GLOBAL_LOGGER ||= create_logger
|
36
33
|
end
|
37
34
|
|
38
35
|
# This method creates the logger instance once (even if it is called twice).
|
@@ -48,7 +45,7 @@ module FreeMessageQueue
|
|
48
45
|
# * WARN => Client side errors
|
49
46
|
# * INFO => Setup information (config stuff etc.)
|
50
47
|
# * DEBUG => All operations of the queue manager and others
|
51
|
-
def self.
|
48
|
+
def self.log_level(level)
|
52
49
|
case level
|
53
50
|
when /fatal/i
|
54
51
|
FreeMessageQueue.logger.level = Logger::FATAL
|
@@ -64,61 +61,9 @@ module FreeMessageQueue
|
|
64
61
|
FreeMessageQueue.logger.debug "[Logger] set log level to #{level}"
|
65
62
|
end
|
66
63
|
|
67
|
-
# The class implements a simple interface to the configuration file
|
68
|
-
# and creates and setup the logger instance
|
69
|
-
class Configuration
|
70
|
-
# the yaml config file from <em>file_path</em> will be read and
|
71
|
-
# parsed. After parsing the global free message queue logger is
|
72
|
-
# created and setup vor further use
|
73
|
-
def initialize(file_path)
|
74
|
-
# open and read file
|
75
|
-
f = open(file_path, "r")
|
76
|
-
data = f.read
|
77
|
-
f.close
|
78
|
-
@config = YAML.load( data )
|
79
|
-
|
80
|
-
# create logger and setup log level
|
81
|
-
@log = FreeMessageQueue.create_logger
|
82
|
-
FreeMessageQueue.set_log_level(server["log-level"])
|
83
|
-
|
84
|
-
# debug the configuration
|
85
|
-
@log.debug("[Configuration] Server: " + YAML.dump(server))
|
86
|
-
@log.debug("[Configuration] QueueManager: " + YAML.dump(queue_manager))
|
87
|
-
end
|
88
|
-
|
89
|
-
# the configuration for the server (MongrelHandler, ...)
|
90
|
-
def server
|
91
|
-
@config["server"]
|
92
|
-
end
|
93
|
-
|
94
|
-
# the configuration for the queue manager
|
95
|
-
def queue_manager
|
96
|
-
@config["queue-manager"]
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
64
|
# Boot deals with the tasks to create up a project and start the server etc.
|
101
|
-
class Boot
|
102
|
-
#
|
103
|
-
# It is the starting point for booting the server.
|
104
|
-
# After reading the configuration the QueueManager and HttpServer (MongrelHandler)
|
105
|
-
# will be created and start listening.
|
106
|
-
# This method will stop when the server goes down otherwise it will run infinitely
|
107
|
-
def self.start_server
|
108
|
-
conf = FreeMessageQueue::Configuration.new("config.yml")
|
109
|
-
logger = FreeMessageQueue.logger
|
110
|
-
|
111
|
-
# create queue manager
|
112
|
-
queue_manager = FreeMessageQueue::QueueManager.new(conf.queue_manager)
|
113
|
-
|
114
|
-
# setup and run server
|
115
|
-
logger.debug "[MongrelHandler] startup at #{conf.server["interface"]}:#{conf.server["port"]}"
|
116
|
-
servsock = Mongrel::HttpServer.new(conf.server["interface"], conf.server["port"])
|
117
|
-
servsock.register("/", FreeMessageQueue::MongrelHandler.new(queue_manager))
|
118
|
-
servsock.run.join
|
119
|
-
end
|
120
|
-
|
121
|
-
# This message will copy the <em>default-server</em> project files
|
65
|
+
class Boot
|
66
|
+
# This method will copy the <em>default-server</em> project files
|
122
67
|
# to the passed (<em>project_name</em>) location.
|
123
68
|
# The <em>default-server</em> contains some basic and sample stuff
|
124
69
|
# so that the free message queue can be used as fast as possible. Including:
|
@@ -126,7 +71,8 @@ module FreeMessageQueue
|
|
126
71
|
# * The default configuration => with some sample queues
|
127
72
|
# * A custom queue implementation => to basically show how to create my own queues
|
128
73
|
def self.create_project(project_name)
|
74
|
+
require 'fileutils'
|
129
75
|
FileUtils.cp_r(File.dirname(__FILE__) + '/../../default-server', project_name)
|
130
76
|
end
|
131
77
|
end
|
132
|
-
end
|
78
|
+
end
|
data/lib/fmq/queue_manager.rb
CHANGED
@@ -16,6 +16,8 @@
|
|
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
|
+
require "ostruct"
|
20
|
+
|
19
21
|
module FreeMessageQueue
|
20
22
|
# All queue manager exceptions are raised using this class
|
21
23
|
class QueueManagerException < Exception
|
@@ -40,6 +42,9 @@ module FreeMessageQueue
|
|
40
42
|
class QueueManager
|
41
43
|
# Returns the queue that is passed otherwise nil
|
42
44
|
attr_reader :queue
|
45
|
+
|
46
|
+
# <b>true</b> to let the queue manager create a queue automaticly
|
47
|
+
attr_writer :auto_create_queues
|
43
48
|
|
44
49
|
# Returns the queue constrains as a hash. The hash has the following structure:
|
45
50
|
# {
|
@@ -59,18 +64,17 @@ module FreeMessageQueue
|
|
59
64
|
|
60
65
|
# setup the queue manager using the configuration from the configuration
|
61
66
|
# file (which is basically a hash)
|
62
|
-
def initialize(
|
67
|
+
def initialize()
|
63
68
|
@queue = {}
|
64
|
-
@config = config
|
65
69
|
@queue_constraints = {}
|
66
70
|
@log = FreeMessageQueue.logger
|
67
|
-
|
71
|
+
@auto_create_queues = true
|
68
72
|
end
|
69
73
|
|
70
74
|
# returns if the creation of queues should be done on demand
|
71
75
|
# (if someone sends a post to a queue)
|
72
76
|
def auto_create_queues?
|
73
|
-
@
|
77
|
+
@auto_create_queues == true
|
74
78
|
end
|
75
79
|
|
76
80
|
# Create a queue (<em>name</em> => <em>path</em>). The path must contain a leading "/" and a 3 character name
|
@@ -95,6 +99,14 @@ module FreeMessageQueue
|
|
95
99
|
|
96
100
|
@queue[name]
|
97
101
|
end
|
102
|
+
|
103
|
+
# create a queue using a block. The block can be used to set configuration
|
104
|
+
# options for the queue
|
105
|
+
def setup_queue(queue_class = DEFAULT_QUEUE_CLASS, &configure_queue)
|
106
|
+
queue_settings = OpenStruct.new
|
107
|
+
configure_queue.call(queue_settings)
|
108
|
+
create_queue_from_config(queue_class, queue_settings.marshal_dump)
|
109
|
+
end
|
98
110
|
|
99
111
|
# Delete the queue by name (path)
|
100
112
|
def delete_queue(name)
|
@@ -132,7 +144,7 @@ module FreeMessageQueue
|
|
132
144
|
unless @queue[name]
|
133
145
|
# only auto create queues if it is configured
|
134
146
|
if auto_create_queues?
|
135
|
-
|
147
|
+
create_queue(name)
|
136
148
|
else
|
137
149
|
raise QueueManagerException.new("[QueueManager] There is no queue '#{name}'", caller)
|
138
150
|
end
|
@@ -180,61 +192,54 @@ module FreeMessageQueue
|
|
180
192
|
!queue[name].nil?
|
181
193
|
end
|
182
194
|
|
195
|
+
# setup a this queue manager block need to be passed
|
196
|
+
def setup(&config)
|
197
|
+
config.call(self)
|
198
|
+
end
|
199
|
+
|
200
|
+
private
|
201
|
+
|
183
202
|
# create a queue from a configuration hash.
|
184
|
-
# The <em>queue_name</em> is just for debugging and organizing the queue.
|
185
203
|
# The <em>queue_config</em> contains the following parameter:
|
186
204
|
# * path: the path to the queue (with leading "/" and 3 characters at minimum) e.g. "/test_queue"
|
187
|
-
# * [optional]
|
188
|
-
# * [optional]
|
189
|
-
# * [optional] class: the class that implements this queue e.g. FreeMessageQueue::SystemQueue
|
205
|
+
# * [optional] max_size: the maximum size e.g. "10mb", "100kb", "2gb" or (black or -1) for infinite
|
206
|
+
# * [optional] max_messages: the maximim messages that can be in the queue e.g. 1500 or (black or -1) for infinite
|
190
207
|
# All other parameter will be send to the queue directly using a naming convention. So if you have the extra parameter
|
191
|
-
#
|
208
|
+
# expire_date = "1h"
|
192
209
|
# the QueueManager will set the expire date using this assignment
|
193
210
|
# queue.expire_date = "1h"
|
194
211
|
# therefore your queue must implement this method
|
195
212
|
# def expire_date=(time)
|
196
213
|
# @expires_after = parse_seconds(time)
|
197
214
|
# end
|
198
|
-
def create_queue_from_config(
|
199
|
-
@log.debug("[QueueManager] setup queue from config '#{queue_name}'")
|
200
|
-
|
215
|
+
def create_queue_from_config(queue_class, queue_config)
|
201
216
|
# path need to be specified
|
202
|
-
raise QueueManagerException.new("[QueueManager] There is now path specified for queue
|
203
|
-
path = queue_config[
|
204
|
-
queue_config.delete
|
217
|
+
raise QueueManagerException.new("[QueueManager] There is now path specified for queue", caller) if queue_config[:path].nil?
|
218
|
+
path = queue_config[:path]
|
219
|
+
queue_config.delete :path
|
220
|
+
|
221
|
+
@log.debug("[QueueManager] setup queue from config '#{path}'")
|
205
222
|
|
206
223
|
# set max size parameter -- this parameter is optional
|
207
|
-
max_size = str_bytes(queue_config[
|
224
|
+
max_size = str_bytes(queue_config[:max_size])
|
208
225
|
max_size = INFINITE if max_size.nil? || max_size <= 0
|
209
|
-
queue_config.delete
|
226
|
+
queue_config.delete :max_size
|
210
227
|
|
211
228
|
# set max messages parameter -- this parameter is optional
|
212
|
-
max_messages = queue_config[
|
229
|
+
max_messages = queue_config[:max_messages].to_i
|
213
230
|
max_messages = INFINITE if max_messages.nil? || max_messages <= 0
|
214
|
-
queue_config.delete
|
231
|
+
queue_config.delete :max_messages
|
215
232
|
|
216
|
-
|
217
|
-
default_class = queue_config["class"]
|
218
|
-
puts default_class
|
219
|
-
default_class = eval(default_class) unless default_class.nil?
|
220
|
-
queue_config.delete "class"
|
221
|
-
|
222
|
-
if default_class.nil?
|
223
|
-
queue = create_queue(path, max_messages, max_size)
|
224
|
-
else
|
225
|
-
queue = create_queue(path, max_messages, max_size, default_class)
|
226
|
-
end
|
233
|
+
queue = create_queue(path, max_messages, max_size, queue_class)
|
227
234
|
|
228
235
|
if queue_config.size > 0
|
229
|
-
@log.debug("[QueueManager] Configure addional parameters for queue '#{
|
230
|
-
for
|
231
|
-
method_name
|
232
|
-
queue.send(method_name + "=", queue_config[parameter])
|
236
|
+
@log.debug("[QueueManager] Configure addional parameters for queue '#{path}'; parameter: #{queue_config.inspect}")
|
237
|
+
for method_name in queue_config.keys
|
238
|
+
queue.send(method_name.to_s + "=", queue_config[method_name])
|
233
239
|
end
|
234
240
|
end
|
235
241
|
end
|
236
|
-
|
237
|
-
private
|
242
|
+
|
238
243
|
# Retuns count of bytes to a expression with kb, mb or gb
|
239
244
|
# e.g 10kb will return 10240
|
240
245
|
def str_bytes(str)
|
@@ -250,17 +255,5 @@ module FreeMessageQueue
|
|
250
255
|
end
|
251
256
|
bs
|
252
257
|
end
|
253
|
-
|
254
|
-
# Create the queues that are defined in the configuration
|
255
|
-
def setup_queue_manager
|
256
|
-
if @config.nil?
|
257
|
-
raise QueueManagerException.new("[QueueManager] there is no queue manager configuration" , caller)
|
258
|
-
else
|
259
|
-
@log.info("[QueueManager] Create defined queues (#{@config["defined-queues"].size})")
|
260
|
-
for defined_queue in @config["defined-queues"]
|
261
|
-
create_queue_from_config(defined_queue[0], defined_queue[1])
|
262
|
-
end
|
263
|
-
end
|
264
|
-
end
|
265
258
|
end
|
266
|
-
end
|
259
|
+
end
|
data/lib/fmq/queues/forward.rb
CHANGED
data/lib/fmq/server.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
#!/usr/bin/env ruby -wKU
|
2
|
+
#
|
3
|
+
# Copyright (c) 2008 Vincent Landgraf
|
4
|
+
#
|
5
|
+
# This file is part of the Free Message Queue.
|
6
|
+
#
|
7
|
+
# Free Message Queue is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# Free Message Queue is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
begin
|
21
|
+
require "rack"
|
22
|
+
rescue LoadError
|
23
|
+
require "rubygems"
|
24
|
+
require "rack"
|
25
|
+
end
|
26
|
+
|
27
|
+
module FreeMessageQueue
|
28
|
+
# This implements server that plugs the free message queue into a rack enviroment
|
29
|
+
class Server
|
30
|
+
# When creating a server you have to pass the QueueManager
|
31
|
+
def initialize(queue_manager)
|
32
|
+
@queue_manager = queue_manager
|
33
|
+
@log = FreeMessageQueue.logger
|
34
|
+
end
|
35
|
+
|
36
|
+
# Process incoming request and send them to the right sub processing method like <em>process_get</em>
|
37
|
+
def call(env)
|
38
|
+
request = Rack::Request.new(env)
|
39
|
+
queue_path = request.env["REQUEST_PATH"]
|
40
|
+
@log.debug("[Server] Request params: #{YAML.dump(request.params)})")
|
41
|
+
|
42
|
+
response = nil
|
43
|
+
begin
|
44
|
+
# process supported features
|
45
|
+
if request.request_method.match(/^(GET|POST|HEAD|DELETE)$/) then
|
46
|
+
response = self.send("process_" + request.request_method.downcase, request, queue_path)
|
47
|
+
else
|
48
|
+
response = client_exception(request, queue_path,
|
49
|
+
ArgumentError.new("[Server] Method is not supported '#{method}'"))
|
50
|
+
end
|
51
|
+
rescue QueueManagerException => ex
|
52
|
+
response = client_exception(request, queue_path, ex)
|
53
|
+
end
|
54
|
+
|
55
|
+
response.header["SERVER"] = SERVER_HEADER
|
56
|
+
return response.finish
|
57
|
+
end
|
58
|
+
|
59
|
+
protected
|
60
|
+
|
61
|
+
# Returns an item from queue and sends it to the client.
|
62
|
+
# If there is no item to fetch send an 204 (NoContent) and same as HEAD
|
63
|
+
def process_get(request, queue_path)
|
64
|
+
message = @queue_manager.poll(queue_path)
|
65
|
+
|
66
|
+
unless message.nil? then
|
67
|
+
response = Rack::Response.new([], 200)
|
68
|
+
|
69
|
+
@log.debug("[Server] Response to GET (200)")
|
70
|
+
response.header["CONTENT-TYPE"] = message.content_type
|
71
|
+
response.header["QUEUE_SIZE"] = @queue_manager.queue_size(queue_path).to_s
|
72
|
+
response.header["QUEUE_BYTES"] = @queue_manager.queue_bytes(queue_path).to_s
|
73
|
+
|
74
|
+
# send all options of the message back to the client
|
75
|
+
if message.respond_to?(:option) && message.option.size > 0
|
76
|
+
for option_name in message.option.keys
|
77
|
+
response.header["MESSAGE_#{option_name.gsub("-", "_").upcase}"] = message.option[option_name].to_s
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
if !message.payload.nil? && message.bytes > 0
|
82
|
+
@log.debug("[Server] Message payload: #{message.payload}")
|
83
|
+
response.write(message.payload)
|
84
|
+
end
|
85
|
+
else
|
86
|
+
response = Rack::Response.new([], 204)
|
87
|
+
@log.debug("[Server] Response to GET (204)")
|
88
|
+
response.header["QUEUE_SIZE"] = response["QUEUE_BYTES"] = 0.to_s
|
89
|
+
end
|
90
|
+
return response
|
91
|
+
end
|
92
|
+
|
93
|
+
# Put new item to the queue and and return sam e as head action (HTTP 200)
|
94
|
+
def process_post(request, queue_path)
|
95
|
+
@log.debug("[Server] Response to POST (200)")
|
96
|
+
post_body = request.body.read
|
97
|
+
message = Message.new(post_body, request.content_type)
|
98
|
+
@log.debug("[Server] Message payload: #{post_body}")
|
99
|
+
|
100
|
+
# send all options of the message back to the client
|
101
|
+
for option_name in request.env.keys
|
102
|
+
if option_name.match(/HTTP_MESSAGE_([a-zA-Z][a-zA-Z0-9_\-]*)/)
|
103
|
+
message.option[$1] = request.env[option_name]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
@queue_manager.put(queue_path, message)
|
108
|
+
|
109
|
+
response = Rack::Response.new([], 200)
|
110
|
+
response.header["QUEUE_SIZE"] = @queue_manager.queue_size(queue_path).to_s
|
111
|
+
response.header["QUEUE_BYTES"] = @queue_manager.queue_bytes(queue_path).to_s
|
112
|
+
return response
|
113
|
+
end
|
114
|
+
|
115
|
+
# Just return server header and queue size (HTTP 200)
|
116
|
+
def process_head(request, queue_path)
|
117
|
+
@log.debug("[Server] Response to HEAD (200)")
|
118
|
+
|
119
|
+
response = Rack::Response.new([], 200)
|
120
|
+
response.header["QUEUE_SIZE"] = @queue_manager.queue_size(queue_path).to_s
|
121
|
+
response.header["QUEUE_BYTES"] = @queue_manager.queue_bytes(queue_path).to_s
|
122
|
+
return response
|
123
|
+
end
|
124
|
+
|
125
|
+
# Delete the queue and return server header (HTTP 200)
|
126
|
+
def process_delete(request, queue_path)
|
127
|
+
@log.debug("[Server] Response to DELETE (200)")
|
128
|
+
@queue_manager.delete_queue(queue_path)
|
129
|
+
|
130
|
+
response = Rack::Response.new([], 200)
|
131
|
+
end
|
132
|
+
|
133
|
+
# Inform the client that he did something wrong (HTTP 400).
|
134
|
+
# HTTP-Header field Error contains information about the problem.
|
135
|
+
# The client errorwill also be reported to warn level of logger.
|
136
|
+
def client_exception(request, queue_path, ex)
|
137
|
+
@log.warn("[Server] Client error: #{ex}")
|
138
|
+
|
139
|
+
response = Rack::Response.new([], 400)
|
140
|
+
response.header["ERROR"] = ex.message
|
141
|
+
return response
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
data/lib/fmq/version.rb
CHANGED
data/lib/fmq.rb
CHANGED
@@ -22,12 +22,7 @@ Dir.glob(File.dirname(__FILE__) + "/fmq/queues/*.rb").each do |file|
|
|
22
22
|
require file
|
23
23
|
end
|
24
24
|
|
25
|
-
# load all local queues (from project directory)
|
26
|
-
Dir.glob("queues/*.rb").each do |file|
|
27
|
-
require file
|
28
|
-
end
|
29
|
-
|
30
25
|
# load all parts in right order
|
31
|
-
['boot', 'client'].each do |file|
|
26
|
+
['boot', 'admin', 'client', 'server'].each do |file|
|
32
27
|
require File.dirname(__FILE__) + "/fmq/#{file}"
|
33
|
-
end
|
28
|
+
end
|
data/test/test_queue_manager.rb
CHANGED
@@ -5,20 +5,19 @@ class TestQueueManager < Test::Unit::TestCase
|
|
5
5
|
DEFAULT_QUEUE_NAME = "/fmq_test/test1"
|
6
6
|
|
7
7
|
def setup
|
8
|
-
FreeMessageQueue.
|
9
|
-
|
8
|
+
FreeMessageQueue.log_level "fatal"
|
9
|
+
|
10
|
+
@queue_manager = FreeMessageQueue::QueueManager.new()
|
10
11
|
|
11
|
-
@
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
}
|
21
|
-
@queue_manager = FreeMessageQueue::QueueManager.new(@working_conf)
|
12
|
+
@queue_manager.setup do |qm|
|
13
|
+
qm.auto_create_queues = false
|
14
|
+
|
15
|
+
qm.setup_queue do |q|
|
16
|
+
q.path = DEFAULT_QUEUE_NAME
|
17
|
+
q.max_messages = 100
|
18
|
+
q.max_size = "100mb"
|
19
|
+
end
|
20
|
+
end
|
22
21
|
end
|
23
22
|
|
24
23
|
def test_config
|
@@ -26,17 +25,11 @@ class TestQueueManager < Test::Unit::TestCase
|
|
26
25
|
constraints = { :max_messages => 100, :max_size => 104857600 }
|
27
26
|
assert_equal constraints, @queue_manager.queue_constraints[DEFAULT_QUEUE_NAME]
|
28
27
|
|
29
|
-
# the queue manager can't be created without config
|
30
|
-
assert_raise(FreeMessageQueue::QueueManagerException) {
|
31
|
-
FreeMessageQueue::QueueManager.new(nil)
|
32
|
-
}
|
33
|
-
|
34
28
|
# check that the simple config will work
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
FreeMessageQueue::QueueManager.new(simple)
|
29
|
+
FreeMessageQueue::QueueManager.new()
|
30
|
+
@queue_manager.setup do |qm|
|
31
|
+
qm.auto_create_queues = false
|
32
|
+
end
|
40
33
|
end
|
41
34
|
|
42
35
|
def test_poll_and_get
|
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.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vincent Landgraf
|
@@ -9,10 +9,19 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-
|
12
|
+
date: 2008-08-26 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rack
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.4.0
|
24
|
+
version:
|
16
25
|
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.
|
17
26
|
email:
|
18
27
|
- fmq-3z@gmx.net
|
@@ -36,16 +45,18 @@ files:
|
|
36
45
|
- config/requirements.rb
|
37
46
|
- default-server/admin-interface/images/logo.png
|
38
47
|
- default-server/admin-interface/index.html
|
39
|
-
- default-server/admin-interface/prototype.js
|
40
|
-
- default-server/
|
48
|
+
- default-server/admin-interface/javascript/prototype.js
|
49
|
+
- default-server/admin-interface/javascript/application.js
|
50
|
+
- default-server/admin-interface/stylesheets/application.css
|
51
|
+
- default-server/config.ru
|
41
52
|
- default-server/queues/my_test.rb
|
42
53
|
- lib/fmq.rb
|
43
54
|
- lib/fmq/boot.rb
|
44
55
|
- lib/fmq/client.rb
|
45
|
-
- lib/fmq/
|
56
|
+
- lib/fmq/admin.rb
|
57
|
+
- lib/fmq/server.rb
|
46
58
|
- lib/fmq/queue_manager.rb
|
47
59
|
- lib/fmq/queues/README.txt
|
48
|
-
- lib/fmq/queues/admin.rb
|
49
60
|
- lib/fmq/queues/base.rb
|
50
61
|
- lib/fmq/queues/file.rb
|
51
62
|
- lib/fmq/queues/forward.rb
|