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/default-server/config.yml
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
server:
|
2
|
-
# start the server on every nic
|
3
|
-
interface: 0.0.0.0
|
4
|
-
# this option set the port for the FMQ
|
5
|
-
port: 5884
|
6
|
-
# here you can setup the log level to see what is going wrong if needed
|
7
|
-
log-level: info
|
8
|
-
|
9
|
-
queue-manager:
|
10
|
-
# if someone pushes to a queue that don't exists
|
11
|
-
# the queue manager will create one for you. This
|
12
|
-
# is a good option if you are in development
|
13
|
-
# the queue will be a LoadBalancedQueue by default
|
14
|
-
auto-create-queues: true
|
15
|
-
# if you want some queues right from startup
|
16
|
-
# define there url and constraints here
|
17
|
-
defined-queues:
|
18
|
-
# queue names are not relevant use them to
|
19
|
-
# organize your queues
|
20
|
-
test-queue-1:
|
21
|
-
# the path to the queue e.g. /app1/myframe/test1
|
22
|
-
# means http://localhost:5884/app1/myframe/test1
|
23
|
-
# this parameter is not optional
|
24
|
-
path: /fmq_test/test1
|
25
|
-
# this defines the maximum count of messages that
|
26
|
-
# can be in the queue, if the queue is full every
|
27
|
-
# new message will be rejected with a http error
|
28
|
-
# this parameter is optional if you don't specify
|
29
|
-
# a max value the queue size depends on your system
|
30
|
-
max-messages: 1000000
|
31
|
-
# this optional to and specifys the max content size
|
32
|
-
# for all data of a queue
|
33
|
-
# valid extensions are kb, mb, gb
|
34
|
-
max-size: 10kb
|
35
|
-
test-queue-2:
|
36
|
-
path: /fmq_test/test2
|
37
|
-
# if you want you can specify the class of the queue
|
38
|
-
# this is interessting if you write your own queues
|
39
|
-
class: FreeMessageQueue::LoadBalancedQueue
|
40
|
-
test-queue-3:
|
41
|
-
path: /fmq_test/test3
|
42
|
-
class: MyTestQueue
|
43
|
-
# this is a forwarding queue wich forwards one message
|
44
|
-
# to some other queues
|
45
|
-
test-queue-forward:
|
46
|
-
path: /fmq_test/forward_to_1_and_2
|
47
|
-
class: FreeMessageQueue::ForwardQueue
|
48
|
-
# you can add as may queues as you want
|
49
|
-
# but seperate them with a space char
|
50
|
-
forward_to: /fmq_test/test1 /fmq_test/test2
|
51
|
-
# the admin queue is a special queue, that is used to
|
52
|
-
# administrate the queue_manager
|
53
|
-
admin-page-backend:
|
54
|
-
path: /admin/queue
|
55
|
-
class: FreeMessageQueue::AdminQueue
|
56
|
-
filter: /admin
|
57
|
-
# The following 3 queues are specail queues to, they
|
58
|
-
# are the admin interface to the application and
|
59
|
-
# make use of the file queue
|
60
|
-
admin-page-index:
|
61
|
-
path: /admin/index
|
62
|
-
class: FreeMessageQueue::FileQueue
|
63
|
-
file: admin-interface/index.html
|
64
|
-
content-type: text/html
|
65
|
-
admin-page-logo:
|
66
|
-
path: /admin/images/logo.png
|
67
|
-
class: FreeMessageQueue::FileQueue
|
68
|
-
file: admin-interface/images/logo.png
|
69
|
-
content-type: image/png
|
70
|
-
admin-page-prototype:
|
71
|
-
path: /admin/prototype.js
|
72
|
-
class: FreeMessageQueue::FileQueue
|
73
|
-
file: admin-interface/prototype.js
|
74
|
-
content-type: text/javascript
|
data/lib/fmq/mongrel_server.rb
DELETED
@@ -1,172 +0,0 @@
|
|
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 "mongrel"
|
22
|
-
rescue LoadError
|
23
|
-
require "rubygems"
|
24
|
-
require "mongrel"
|
25
|
-
end
|
26
|
-
|
27
|
-
module FreeMessageQueue
|
28
|
-
# This implements the MongrelServlet that serves free message queue
|
29
|
-
# in a mongrel enviroment
|
30
|
-
class MongrelHandler < Mongrel::HttpHandler
|
31
|
-
# When creationg a mongrel handler you have to pass the <em>queue_manager</em>
|
32
|
-
# that should be distributed by mongrel
|
33
|
-
def initialize(queue_manager)
|
34
|
-
@queue_manager = queue_manager
|
35
|
-
@log = FreeMessageQueue.logger
|
36
|
-
end
|
37
|
-
|
38
|
-
# Process incoming request and send them to the right sub processing method like <em>process_get</em>
|
39
|
-
def process(request, response)
|
40
|
-
queue_path = request.params["REQUEST_PATH"]
|
41
|
-
method = request.params["REQUEST_METHOD"]
|
42
|
-
@log.debug("[MongrelHandler] Incomming request for #{queue_path} [#{method}] (#{request.params["REMOTE_ADDR"]})")
|
43
|
-
@log.debug("[MongrelHandler] Request params: #{YAML.dump(request.params)})")
|
44
|
-
|
45
|
-
begin
|
46
|
-
# process supported features
|
47
|
-
if method.match(/^(GET|POST|HEAD|DELETE)$/) then
|
48
|
-
self.send("process_" + method.downcase, request, response, queue_path)
|
49
|
-
else
|
50
|
-
client_exception(request, response, queue_path,
|
51
|
-
ArgumentError.new("[MongrelHandler] Method is not supported '#{method}'"))
|
52
|
-
end
|
53
|
-
rescue QueueManagerException => ex
|
54
|
-
client_exception(request, response, queue_path, ex)
|
55
|
-
rescue => ex
|
56
|
-
server_exception(request, response, queue_path, ex)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
protected
|
61
|
-
|
62
|
-
# Returns an item from queue and sends it to the client.
|
63
|
-
# If there is no item to fetch send an 204 (NoContent) and same as HEAD
|
64
|
-
def process_get(request, response, queue_path)
|
65
|
-
message = @queue_manager.poll(queue_path)
|
66
|
-
|
67
|
-
unless message.nil? then
|
68
|
-
response.start(200) do |head,out|
|
69
|
-
@log.debug("[MongrelHandler] Response to GET (200)")
|
70
|
-
head["CONTENT-TYPE"] = message.content_type
|
71
|
-
head["SERVER"] = SERVER_HEADER
|
72
|
-
head["QUEUE_SIZE"] = @queue_manager.queue_size(queue_path)
|
73
|
-
head["QUEUE_BYTES"] = @queue_manager.queue_bytes(queue_path)
|
74
|
-
|
75
|
-
# send all options of the message back to the client
|
76
|
-
if message.respond_to?(:option) && message.option.size > 0
|
77
|
-
for option_name in message.option.keys
|
78
|
-
head["MESSAGE_#{option_name.gsub("-", "_").upcase}"] = message.option[option_name].to_s
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
if !message.payload.nil? && message.bytes > 0
|
83
|
-
@log.debug("[MongrelHandler] Message payload: #{message.payload}")
|
84
|
-
out.write(message.payload)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
else
|
88
|
-
response.start(204) do |head,out|
|
89
|
-
@log.debug("[MongrelHandler] Response to GET (204)")
|
90
|
-
head["SERVER"] = SERVER_HEADER
|
91
|
-
head["QUEUE_SIZE"] = head["QUEUE_BYTES"] = 0
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
# Put new item to the queue and and return sam e as head action (HTTP 200)
|
97
|
-
def process_post(request, response, queue_path)
|
98
|
-
@log.debug("[MongrelHandler] Response to POST (200)")
|
99
|
-
message = Message.new(request.body.read, request.params["CONTENT_TYPE"])
|
100
|
-
@log.debug("[MongrelHandler] Message payload: #{message.payload}")
|
101
|
-
|
102
|
-
# send all options of the message back to the client
|
103
|
-
for option_name in request.params.keys
|
104
|
-
if option_name.match(/HTTP_MESSAGE_([a-zA-Z][a-zA-Z0-9_\-]*)/)
|
105
|
-
message.option[$1] = request.params[option_name]
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
@queue_manager.put(queue_path, message)
|
110
|
-
|
111
|
-
response.start(200) do |head,out|
|
112
|
-
head["SERVER"] = SERVER_HEADER
|
113
|
-
head["QUEUE_SIZE"] = @queue_manager.queue_size(queue_path)
|
114
|
-
head["QUEUE_BYTES"] = @queue_manager.queue_bytes(queue_path)
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
# Just return server header and queue size (HTTP 200)
|
119
|
-
def process_head(request, response, queue_path)
|
120
|
-
@log.debug("[MongrelHandler] Response to HEAD (200)")
|
121
|
-
|
122
|
-
response.start(200) do |head,out|
|
123
|
-
head["SERVER"] = SERVER_HEADER
|
124
|
-
head["QUEUE_SIZE"] = @queue_manager.queue_size(queue_path)
|
125
|
-
head["QUEUE_BYTES"] = @queue_manager.queue_bytes(queue_path)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
# Delete the queue and return server header (HTTP 200)
|
130
|
-
def process_delete(request, response, queue_path)
|
131
|
-
@log.debug("[MongrelHandler] Response to DELETE (200)")
|
132
|
-
@queue_manager.delete_queue(queue_path)
|
133
|
-
|
134
|
-
response.start(200) do |head,out|
|
135
|
-
head["SERVER"] = SERVER_HEADER
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
# Inform the client that he did something wrong (HTTP 400).
|
140
|
-
# HTTP-Header field Error contains information about the problem.
|
141
|
-
# The client errorwill also be reported to warn level of logger.
|
142
|
-
def client_exception(request, response, queue_path, ex)
|
143
|
-
@log.warn("[MongrelHandler] Client error: #{ex}")
|
144
|
-
response.start(400) do |head,out|
|
145
|
-
head["SERVER"] = SERVER_HEADER
|
146
|
-
head["ERROR"] = ex.message
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
# Report server error (HTTP 500).
|
151
|
-
# HTTP-Header field Error contains information about the problem.
|
152
|
-
# The body of the response contains the full stack trace.
|
153
|
-
# The error and stack trace will also be reported to logger.
|
154
|
-
def server_exception(request, response, queue_path, ex)
|
155
|
-
@log.fatal("[MongrelHandler] System error: #{ex}")
|
156
|
-
for line in ex.backtrace
|
157
|
-
@log.error line
|
158
|
-
end
|
159
|
-
|
160
|
-
response.start(500) do |head,out|
|
161
|
-
head["CONTENT-TYPE"] = "text/plain"
|
162
|
-
head["SERVER"] = SERVER_HEADER
|
163
|
-
head["ERROR"] = ex.message
|
164
|
-
|
165
|
-
out.write(ex.message + "\r\n\r\n")
|
166
|
-
for line in ex.backtrace
|
167
|
-
out.write(line + "\r\n")
|
168
|
-
end
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
data/lib/fmq/queues/admin.rb
DELETED
@@ -1,94 +0,0 @@
|
|
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
|
-
|
21
|
-
module FreeMessageQueue
|
22
|
-
# This queue is dedicated to the AJAX based admin interface.
|
23
|
-
#
|
24
|
-
# configuration sample:
|
25
|
-
# queue-manager:
|
26
|
-
# auto-create-queues: true
|
27
|
-
# defined-queues:
|
28
|
-
# admin-page-backend:
|
29
|
-
# path: /admin/queue
|
30
|
-
# class: FreeMessageQueue::AdminQueue
|
31
|
-
# filter: /admin
|
32
|
-
class AdminQueue < BaseQueue
|
33
|
-
def initialize(manager)
|
34
|
-
super(manager)
|
35
|
-
@filter_queues = []
|
36
|
-
end
|
37
|
-
|
38
|
-
# returns an json list of visible queues
|
39
|
-
def poll()
|
40
|
-
queues_code = []
|
41
|
-
manager.queues.each do |queue_name|
|
42
|
-
# skip if it is filterd
|
43
|
-
next if filtered? queue_name
|
44
|
-
|
45
|
-
# add a new entry to the array
|
46
|
-
queues_code << queue_to_json(queue_name)
|
47
|
-
end
|
48
|
-
|
49
|
-
Message.new("[%s]" % queues_code.join(","), "application/json")
|
50
|
-
end
|
51
|
-
|
52
|
-
# can be either used to *create* or *delete* a queue
|
53
|
-
def put(message)
|
54
|
-
if message.payload.match(/_method=delete&path=(.*)/)
|
55
|
-
# delete queue
|
56
|
-
manager.delete_queue($1)
|
57
|
-
elsif message.payload.match(/_method=create&data=(.*)/)
|
58
|
-
# create queue
|
59
|
-
conf = eval($1.gsub(":", "=>").gsub("null", "-1"))
|
60
|
-
manager.create_queue_from_config("dynamic-created-queue", conf)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
# *CONFIGURATION* *OPTION*
|
65
|
-
# sets the paths that should be filterd out, seperate them with space char
|
66
|
-
def filter=(str)
|
67
|
-
@filter_queues = str.split " "
|
68
|
-
end
|
69
|
-
|
70
|
-
private
|
71
|
-
|
72
|
-
# check if the system queue should filter the queue
|
73
|
-
def filtered? (name)
|
74
|
-
skip = false
|
75
|
-
for filter in @filter_queues
|
76
|
-
skip = true if name[0...filter.size] == filter
|
77
|
-
end
|
78
|
-
skip
|
79
|
-
end
|
80
|
-
|
81
|
-
# converts the data of one queue to json format
|
82
|
-
def queue_to_json(queue_name)
|
83
|
-
constraints = manager.queue_constraints[queue_name]
|
84
|
-
|
85
|
-
"[\"%s\", %d, %d, %d, %d]" % [
|
86
|
-
queue_name,
|
87
|
-
manager.queue[queue_name].bytes,
|
88
|
-
constraints[:max_size],
|
89
|
-
manager.queue[queue_name].size,
|
90
|
-
constraints[:max_messages],
|
91
|
-
]
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
File without changes
|