fmq 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/fmq CHANGED
@@ -4,20 +4,26 @@
4
4
  #
5
5
  # This file is part of the Free Message Queue.
6
6
  #
7
- # Foobar is free software: you can redistribute it and/or modify
7
+ # Free Message Queue is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU General Public License as published by
9
9
  # the Free Software Foundation, either version 3 of the License, or
10
10
  # (at your option) any later version.
11
11
  #
12
- # Foobar is distributed in the hope that it will be useful,
12
+ # Free Message Queue is distributed in the hope that it will be useful,
13
13
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
14
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
15
  # GNU General Public License for more details.
16
16
  #
17
17
  # You should have received a copy of the GNU General Public License
18
- # along with Foobar. If not, see <http://www.gnu.org/licenses/>.
18
+ # along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
19
19
  #
20
-
20
+ # == Command line options
21
+ #
22
+ # usage: /usr/bin/fmq [create <project_name>]
23
+ #
24
+ # * Invocation without parameter will start server
25
+ # * Invocation with parameter <em>create</em> *project_name*
26
+ # will create a project folder with the name *project_name*
21
27
  begin
22
28
  require "fmq"
23
29
  rescue LoadError
File without changes
@@ -40,6 +40,14 @@ queue-manager:
40
40
  test-queue-3:
41
41
  path: /fmq_test/test3
42
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
43
51
  # the admin queue is a special queue, that is used to
44
52
  # administrate the queue_manager
45
53
  admin-page-backend:
data/lib/fmq.rb CHANGED
@@ -3,18 +3,18 @@
3
3
  #
4
4
  # This file is part of the Free Message Queue.
5
5
  #
6
- # Foobar is free software: you can redistribute it and/or modify
6
+ # Free Message Queue is free software: you can redistribute it and/or modify
7
7
  # it under the terms of the GNU General Public License as published by
8
8
  # the Free Software Foundation, either version 3 of the License, or
9
9
  # (at your option) any later version.
10
10
  #
11
- # Foobar is distributed in the hope that it will be useful,
11
+ # Free Message Queue is distributed in the hope that it will be useful,
12
12
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
13
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
14
  # GNU General Public License for more details.
15
15
  #
16
16
  # You should have received a copy of the GNU General Public License
17
- # along with Foobar. If not, see <http://www.gnu.org/licenses/>.
17
+ # along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
 
20
20
  # load all queues and manager and server
@@ -3,18 +3,18 @@
3
3
  #
4
4
  # This file is part of the Free Message Queue.
5
5
  #
6
- # Foobar is free software: you can redistribute it and/or modify
6
+ # Free Message Queue is free software: you can redistribute it and/or modify
7
7
  # it under the terms of the GNU General Public License as published by
8
8
  # the Free Software Foundation, either version 3 of the License, or
9
9
  # (at your option) any later version.
10
10
  #
11
- # Foobar is distributed in the hope that it will be useful,
11
+ # Free Message Queue is distributed in the hope that it will be useful,
12
12
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
13
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
14
  # GNU General Public License for more details.
15
15
  #
16
16
  # You should have received a copy of the GNU General Public License
17
- # along with Foobar. If not, see <http://www.gnu.org/licenses/>.
17
+ # along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
  require 'yaml'
20
20
  require 'logger'
@@ -25,16 +25,29 @@ require File.dirname(__FILE__) + '/queue_manager'
25
25
  require File.dirname(__FILE__) + '/mongrel_server'
26
26
 
27
27
  module FreeMessageQueue
28
+ # This is the standard server header that will be used by mongel and other web servers
28
29
  SERVER_HEADER = "FMQ/#{FreeMessageQueue::VERSION::STRING} (#{RUBY_PLATFORM}) Ruby/#{RUBY_VERSION}"
29
30
 
31
+ # This method returns the ruby logger instance for the
32
+ # free message queue, so that it is simple to access
33
+ # the logger from somewhere in the project
30
34
  def self.logger
31
35
  $FMQ_GLOBAL_LOGGER
32
36
  end
33
37
 
38
+ # This method creates the logger instance once (even if it is called twice).
34
39
  def self.create_logger(log_to = STDOUT)
35
40
  $FMQ_GLOBAL_LOGGER ||= Logger.new(log_to)
36
41
  end
37
42
 
43
+ # This method sets the log level of the fmq logger
44
+ # the level must be a string (either downcase or upcase)
45
+ # that contains one of the following levels:
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
38
51
  def self.set_log_level(level)
39
52
  case level
40
53
  when /fatal/i
@@ -51,7 +64,12 @@ module FreeMessageQueue
51
64
  FreeMessageQueue.logger.debug "[Logger] set log level to #{level}"
52
65
  end
53
66
 
67
+ # The class implements a simple interface to the configuration file
68
+ # and creates and setup the logger instance
54
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
55
73
  def initialize(file_path)
56
74
  # open and read file
57
75
  f = open(file_path, "r")
@@ -59,28 +77,36 @@ module FreeMessageQueue
59
77
  f.close
60
78
  @config = YAML.load( data )
61
79
 
62
- # set log level
80
+ # create logger and setup log level
81
+ @log = FreeMessageQueue.create_logger
63
82
  FreeMessageQueue.set_log_level(server["log-level"])
64
83
 
65
84
  # debug the configuration
66
- FreeMessageQueue.logger.debug("[Configuration] Server: " + YAML.dump(server))
67
- FreeMessageQueue.logger.debug("[Configuration] QueueManager: " + YAML.dump(queue_manager))
85
+ @log.debug("[Configuration] Server: " + YAML.dump(server))
86
+ @log.debug("[Configuration] QueueManager: " + YAML.dump(queue_manager))
68
87
  end
69
88
 
89
+ # the configuration for the server (MongrelHandler, ...)
70
90
  def server
71
91
  @config["server"]
72
92
  end
73
93
 
94
+ # the configuration for the queue manager
74
95
  def queue_manager
75
96
  @config["queue-manager"]
76
97
  end
77
98
  end
78
99
 
100
+ # Boot deals with the tasks to create up a project and start the server etc.
79
101
  class Boot
102
+ # The configuration file <em>config.yml</em> must be in the same directory.
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
80
107
  def self.start_server
81
- # create logger and setup log level
82
- logger = FreeMessageQueue.create_logger
83
108
  conf = FreeMessageQueue::Configuration.new("config.yml")
109
+ logger = FreeMessageQueue.logger
84
110
 
85
111
  # create queue manager
86
112
  queue_manager = FreeMessageQueue::QueueManager.new(conf.queue_manager)
@@ -92,6 +118,13 @@ module FreeMessageQueue
92
118
  servsock.run.join
93
119
  end
94
120
 
121
+ # This message will copy the <em>default-server</em> project files
122
+ # to the passed (<em>project_name</em>) location.
123
+ # The <em>default-server</em> contains some basic and sample stuff
124
+ # so that the free message queue can be used as fast as possible. Including:
125
+ # * The Admin UI (Ajax Interface) => so that you can make changes
126
+ # * The default configuration => with some sample queues
127
+ # * A custom queue implementation => to basically show how to create my own queues
95
128
  def self.create_project(project_name)
96
129
  FileUtils.cp_r(File.dirname(__FILE__) + '/../../default-server', project_name)
97
130
  end
@@ -3,28 +3,56 @@
3
3
  #
4
4
  # This file is part of the Free Message Queue.
5
5
  #
6
- # Foobar is free software: you can redistribute it and/or modify
6
+ # Free Message Queue is free software: you can redistribute it and/or modify
7
7
  # it under the terms of the GNU General Public License as published by
8
8
  # the Free Software Foundation, either version 3 of the License, or
9
9
  # (at your option) any later version.
10
10
  #
11
- # Foobar is distributed in the hope that it will be useful,
11
+ # Free Message Queue is distributed in the hope that it will be useful,
12
12
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
13
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
14
  # GNU General Public License for more details.
15
15
  #
16
16
  # You should have received a copy of the GNU General Public License
17
- # along with Foobar. If not, see <http://www.gnu.org/licenses/>.
17
+ # along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
  require 'net/http'
20
20
 
21
21
  module FreeMessageQueue
22
+ # Here you can find the client side api for the free message queue.
23
+ # This api is build using the net/http facilitys
24
+ #
25
+ # Some sample usage of the client api:
26
+ #
27
+ # require "fmq"
28
+ #
29
+ # # queue adress
30
+ # QA = "http://localhost/webserver_agent/urgent_messages"
31
+ #
32
+ # my_remote_queue = FreeMessageQueue::ClientQueue.new(QA)
33
+ #
34
+ # # pick one message
35
+ # msg = my_remote_queue.get()
36
+ # puts " == URGENT MESSSAGE == "
37
+ # puts msg
38
+ #
39
+ # # put an urgent message on the queue e.g.in yaml
40
+ # msg = "
41
+ # title: server don't answer a ping request
42
+ # date_time: 2008-06-01 20:19:28
43
+ # server: 10.10.30.62
44
+ # "
45
+ #
46
+ # my_remote_queue.put(msg)
47
+ #
22
48
  class ClientQueue
49
+ # create a connection to a queue (by url)
23
50
  def initialize(url)
24
51
  @url = url
25
52
  end
26
-
27
- def get()
53
+
54
+ # this returns one message from the queue as a string
55
+ def poll()
28
56
  url = URI.parse(@url)
29
57
  req = Net::HTTP::Get.new(url.path)
30
58
  res = Net::HTTP.start(url.host, url.port) do |http|
@@ -33,11 +61,16 @@ module FreeMessageQueue
33
61
  res.body
34
62
  end
35
63
 
64
+ alias get poll
65
+
66
+ # this puts one message to the queue as a string
36
67
  def put(data)
37
68
  url = URI.parse(@url)
38
69
  res = Net::HTTP.start(url.host, url.port) do |http|
39
70
  http.post(url.path, data)
40
71
  end
41
72
  end
73
+
74
+ alias post put
42
75
  end
43
76
  end
@@ -4,18 +4,18 @@
4
4
  #
5
5
  # This file is part of the Free Message Queue.
6
6
  #
7
- # Foobar is free software: you can redistribute it and/or modify
7
+ # Free Message Queue is free software: you can redistribute it and/or modify
8
8
  # it under the terms of the GNU General Public License as published by
9
9
  # the Free Software Foundation, either version 3 of the License, or
10
10
  # (at your option) any later version.
11
11
  #
12
- # Foobar is distributed in the hope that it will be useful,
12
+ # Free Message Queue is distributed in the hope that it will be useful,
13
13
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
14
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
15
  # GNU General Public License for more details.
16
16
  #
17
17
  # You should have received a copy of the GNU General Public License
18
- # along with Foobar. If not, see <http://www.gnu.org/licenses/>.
18
+ # along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
19
19
  #
20
20
  begin
21
21
  require "mongrel"
@@ -25,12 +25,17 @@ rescue LoadError
25
25
  end
26
26
 
27
27
  module FreeMessageQueue
28
+ # This implements the MongrelServlet that serves free message queue
29
+ # in a mongrel enviroment
28
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
29
33
  def initialize(queue_manager)
30
34
  @queue_manager = queue_manager
31
35
  @log = FreeMessageQueue.logger
32
36
  end
33
37
 
38
+ # Process incoming request and send them to the right sub processing method like <em>process_get</em>
34
39
  def process(request, response)
35
40
  queue_path = request.params["REQUEST_PATH"]
36
41
  method = request.params["REQUEST_METHOD"]
@@ -42,7 +47,8 @@ module FreeMessageQueue
42
47
  if method.match(/^(GET|POST|HEAD|DELETE)$/) then
43
48
  self.send("process_" + method.downcase, request, response, queue_path)
44
49
  else
45
- raise QueueManagerException.new("[MongrelHandler] Method is not supported '#{method}'", caller)
50
+ client_exception(request, response, queue_path,
51
+ ArgumentError.new("[MongrelHandler] Method is not supported '#{method}'"))
46
52
  end
47
53
  rescue QueueManagerException => ex
48
54
  client_exception(request, response, queue_path, ex)
@@ -51,10 +57,10 @@ module FreeMessageQueue
51
57
  end
52
58
  end
53
59
 
54
- private
60
+ protected
55
61
 
56
- # returns an item from queue and sends it to the client
57
- # if there is no item to fetch send an 204 (NoContent) and same as HEAD
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
58
64
  def process_get(request, response, queue_path)
59
65
  queue_item = @queue_manager.poll(queue_path)
60
66
 
@@ -78,7 +84,7 @@ module FreeMessageQueue
78
84
  end
79
85
  end
80
86
 
81
- # put new item to the queue and and return sam e as head action
87
+ # Put new item to the queue and and return sam e as head action (HTTP 200)
82
88
  def process_post(request, response, queue_path)
83
89
  @log.debug("[MongrelHandler] Response to POST (200)")
84
90
  data = request.body.read
@@ -91,7 +97,7 @@ module FreeMessageQueue
91
97
  end
92
98
  end
93
99
 
94
- # just return server header and queue size
100
+ # Just return server header and queue size (HTTP 200)
95
101
  def process_head(request, response, queue_path)
96
102
  @log.debug("[MongrelHandler] Response to HEAD (200)")
97
103
 
@@ -101,7 +107,7 @@ module FreeMessageQueue
101
107
  end
102
108
  end
103
109
 
104
- # delete the queue and return server header
110
+ # Delete the queue and return server header (HTTP 200)
105
111
  def process_delete(request, response, queue_path)
106
112
  @log.debug("[MongrelHandler] Response to DELETE (200)")
107
113
  @queue_manager.delete_queue(queue_path)
@@ -111,7 +117,9 @@ module FreeMessageQueue
111
117
  end
112
118
  end
113
119
 
114
- # inform the client that he did something wrong
120
+ # Inform the client that he did something wrong (HTTP 400).
121
+ # HTTP-Header field Error contains information about the problem.
122
+ # The client errorwill also be reported to warn level of logger.
115
123
  def client_exception(request, response, queue_path, ex)
116
124
  @log.warn("[MongrelHandler] Client error: #{ex}")
117
125
  response.start(400) do |head,out|
@@ -120,7 +128,10 @@ module FreeMessageQueue
120
128
  end
121
129
  end
122
130
 
123
- # report server error
131
+ # Report server error (HTTP 500).
132
+ # HTTP-Header field Error contains information about the problem.
133
+ # The body of the response contains the full stack trace.
134
+ # The error and stack trace will also be reported to logger.
124
135
  def server_exception(request, response, queue_path, ex)
125
136
  @log.fatal("[MongrelHandler] System error: #{ex}")
126
137
  for line in ex.backtrace
@@ -3,36 +3,52 @@
3
3
  #
4
4
  # This file is part of the Free Message Queue.
5
5
  #
6
- # Foobar is free software: you can redistribute it and/or modify
6
+ # Free Message Queue is free software: you can redistribute it and/or modify
7
7
  # it under the terms of the GNU General Public License as published by
8
8
  # the Free Software Foundation, either version 3 of the License, or
9
9
  # (at your option) any later version.
10
10
  #
11
- # Foobar is distributed in the hope that it will be useful,
11
+ # Free Message Queue is distributed in the hope that it will be useful,
12
12
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
13
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
14
  # GNU General Public License for more details.
15
15
  #
16
16
  # You should have received a copy of the GNU General Public License
17
- # along with Foobar. If not, see <http://www.gnu.org/licenses/>.
17
+ # along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
  module FreeMessageQueue
20
- class QueueManagerException < RuntimeError
20
+ # All queue manager exceptions are raised using this class
21
+ class QueueManagerException < Exception
21
22
  attr_accessor :message, :backtrace
22
23
 
23
- def initialize(message, callstack)
24
+ # Create exception with message and backtrace (if needed)
25
+ def initialize(message, callstack = [])
24
26
  @message = message
25
27
  @backtrace = callstack
26
28
  end
27
29
 
30
+ # Returns the message of the exception
28
31
  def to_s
29
32
  @message
30
33
  end
31
34
  end
32
35
 
36
+ # The queue manager is one of the core components of the system.
37
+ # This component manages the queues by pathname and checks on the
38
+ # corresponding constraints. Every queue that is created by this
39
+ # queue manager will get a reference (<em>manager</em>) for later use.
33
40
  class QueueManager
41
+ # This value is used to decribe that a constraint has no limit e.g.
42
+ # :max_messages => INFINITE
43
+ # means that there is no limitation for messages
34
44
  INFINITE = -1
45
+
46
+ # this is the default queue class if no other is specified this
47
+ # class will be created when setting up a queue
48
+ DEFAULT_QUEUE_CLASS = FreeMessageQueue::SyncronizedQueue
35
49
 
50
+ # setup the queue manager using the configuration from the configuration
51
+ # file (which is basically a hash)
36
52
  def initialize(config)
37
53
  @queue = {}
38
54
  @config = config
@@ -41,11 +57,15 @@ module FreeMessageQueue
41
57
  setup_queue_manager()
42
58
  end
43
59
 
60
+ # returns if the creation of queues should be done on demand
61
+ # (if someone sends a post to a queue)
44
62
  def auto_create_queues?
45
63
  @config["auto-create-queues"]
46
64
  end
47
65
 
48
- def create_queue(name, max_messages = INFINITE, max_size = INFINITE, default_class = FreeMessageQueue::SyncronizedQueue)
66
+ # Create a queue (<em>name</em> => <em>path</em>). The path must contain a leading "/" and a 3 character name
67
+ # at minimum. Exceptions will be raised if the queue allready exists.
68
+ def create_queue(name, max_messages = INFINITE, max_size = INFINITE, default_class = DEFAULT_QUEUE_CLASS)
49
69
  # path must begin with /
50
70
  raise QueueManagerException.new("[QueueManager] Leading / in path '#{name}' missing", caller) if name[0..0] != "/"
51
71
 
@@ -67,6 +87,7 @@ module FreeMessageQueue
67
87
  @queue[name]
68
88
  end
69
89
 
90
+ # Delete the queue by name (path)
70
91
  def delete_queue(name)
71
92
  if @queue[name]
72
93
  @log.info("[QueueManager] Delete queue '#{name}' with #{@queue[name].size} messages")
@@ -78,15 +99,26 @@ module FreeMessageQueue
78
99
  end
79
100
  end
80
101
 
102
+ # This returns one message from the passed queue
81
103
  def poll(name)
82
104
  if @queue[name]
83
105
  @log.debug("[QueueManager] Poll from queue '#{name}' with #{@queue[name].size} messages")
84
- queue_item = @queue[name].poll
106
+ if @queue[name].respond_to? :poll
107
+ queue_item = @queue[name].poll
108
+ else
109
+ raise QueueManagerException.new("[QueueManager] You can't poll from queue '#{name}'", caller)
110
+ end
85
111
  else
86
112
  raise QueueManagerException.new("[QueueManager] There is no queue '#{name}'", caller)
87
113
  end
88
114
  end
115
+
116
+ alias get poll
89
117
 
118
+ # Puts a message (<em>data</em>) to the queue and checks if the constraints are vaild otherwise
119
+ # it will raise a QueueManagerException. If <em>auto_create_queues</em> is set to *true* the queue
120
+ # will be generated if there isn't a queue with the passed name (path). Otherwise
121
+ # it will raise a QueueManagerException if the passed queue doesn't exists.
90
122
  def put(name, data)
91
123
  unless @queue[name]
92
124
  # only auto create queues if it is configured
@@ -110,36 +142,59 @@ module FreeMessageQueue
110
142
  end
111
143
 
112
144
  @log.debug("[QueueManager] put message to queue '#{name}' with #{@queue[name].size} messages")
113
- @queue[name].put(data)
145
+ if @queue[name].respond_to? :put
146
+ @queue[name].put(data)
147
+ else
148
+ raise QueueManagerException.new("[QueueManager] You can't put to queue '#{name}'", caller)
149
+ end
114
150
  end
115
-
151
+
152
+ alias post put
153
+
154
+ # Returns the names (paths) of all queues managed by this queue manager
116
155
  def queues
117
156
  @queue.keys
118
157
  end
119
158
 
159
+ # Returns the size of a queue in bytes
120
160
  def queue_size(name)
121
161
  @queue[name].size
122
162
  end
123
163
 
164
+ # Returns the queue constrains as a hash. The hash has the following structure:
165
+ # {
166
+ # :max_size => "100mb",
167
+ # :max_messages => 1000
168
+ # }
124
169
  def queue_constraints(name)
125
170
  @queue_constraints[name]
126
171
  end
127
172
 
173
+ # Returns the queue that is passed otherwise nil
128
174
  def queue(name)
129
175
  @queue[name]
130
176
  end
131
177
 
178
+ # Is the name (path) of the queue in use allready
132
179
  def queue_exists?(name)
133
180
  !queue(name).nil?
134
181
  end
135
182
 
136
- # create a queue from a configuration hash
137
- # <em>queue_name</em> this name is just for debugging and organizing the queue
138
- # <em>queue_config</em> here you will pass the parameter:
139
- # * path:
140
- # * [optional] max-size: the maximum size e.g. 10mb
141
- # * [optional] max-messages: the maximim messages that can be in the queue e.g. 9999999
183
+ # create a queue from a configuration hash.
184
+ # The <em>queue_name</em> is just for debugging and organizing the queue.
185
+ # The <em>queue_config</em> contains the following parameter:
186
+ # * path: the path to the queue (with leading "/" and 3 characters at minimum) e.g. "/test_queue"
187
+ # * [optional] max-size: the maximum size e.g. "10mb", "100kb", "2gb" or (black or -1) for infinite
188
+ # * [optional] max-messages: the maximim messages that can be in the queue e.g. 1500 or (black or -1) for infinite
142
189
  # * [optional] class: the class that implements this queue e.g. FreeMessageQueue::SystemQueue
190
+ # All other parameter will be send to the queue directly using a naming convention. So if you have the extra parameter
191
+ # expire-date: 1h
192
+ # the QueueManager will set the expire date using this assignment
193
+ # queue.expire_date = "1h"
194
+ # therefore your queue must implement this method
195
+ # def expire_date=(time)
196
+ # @expires_after = parse_seconds(time)
197
+ # end
143
198
  def create_queue_from_config(queue_name, queue_config)
144
199
  @log.debug("[QueueManager] setup queue from config '#{queue_name}'")
145
200
 
@@ -179,7 +234,7 @@ module FreeMessageQueue
179
234
  end
180
235
 
181
236
  private
182
- # retuns count of bytes to a expression with kb, mb or gb
237
+ # Retuns count of bytes to a expression with kb, mb or gb
183
238
  # e.g 10kb will return 10240
184
239
  def str_bytes(str)
185
240
  case str
@@ -195,7 +250,7 @@ module FreeMessageQueue
195
250
  bs
196
251
  end
197
252
 
198
- # create the queues that are defined in the configuration
253
+ # Create the queues that are defined in the configuration
199
254
  def setup_queue_manager
200
255
  @log.info("[QueueManager] Create defined queues (#{@config["defined-queues"].size})")
201
256
  for defined_queue in @config["defined-queues"]
@@ -0,0 +1,36 @@
1
+ == Creating custom queues:
2
+
3
+ Read this simple description on how to create a queue for your special purpose.
4
+ First of all, this template is where you start.
5
+ 1. You have to create a class that is meanful and ends up with "Queue" (for naming convention) e.g. "MyTestQueue"
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"
8
+ 3. Change the queue implementation to something you like
9
+ * every queue must have an <em>manager</em>.
10
+ * this manager must be able to read <em>bytes</em> and <em>size</em>
11
+ * the queue should have at least one of the <tt>put(data)</tt> or <tt>poll()</tt> methods defined
12
+ * when implementing the poll queue the object you returning needs to have a <em>data</em> method.
13
+ This examples uses OpenStruct for this purpose
14
+
15
+ # FILE: my_project/queues/my_test.rb
16
+
17
+ require "ostruct"
18
+
19
+ class MyTestQueue
20
+ attr_accessor :manager
21
+ attr_reader :bytes, :size
22
+
23
+ def initialize
24
+ @bytes = @size = 1
25
+ end
26
+
27
+ def put(data)
28
+ puts "NEW MESSAGE"
29
+ end
30
+
31
+ def poll
32
+ item = OpenStruct.new
33
+ item.data = "Hello World"
34
+ item
35
+ end
36
+ end
@@ -3,30 +3,47 @@
3
3
  #
4
4
  # This file is part of the Free Message Queue.
5
5
  #
6
- # Foobar is free software: you can redistribute it and/or modify
6
+ # Free Message Queue is free software: you can redistribute it and/or modify
7
7
  # it under the terms of the GNU General Public License as published by
8
8
  # the Free Software Foundation, either version 3 of the License, or
9
9
  # (at your option) any later version.
10
10
  #
11
- # Foobar is distributed in the hope that it will be useful,
11
+ # Free Message Queue is distributed in the hope that it will be useful,
12
12
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
13
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
14
  # GNU General Public License for more details.
15
15
  #
16
16
  # You should have received a copy of the GNU General Public License
17
- # along with Foobar. If not, see <http://www.gnu.org/licenses/>.
18
- #
17
+ # along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
19
  require 'ostruct'
20
20
 
21
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
22
32
  class AdminQueue
33
+ # QueueManager refrence
23
34
  attr_accessor :manager
24
35
 
36
+ # Bytes size is -1. Size is allways 1 message
37
+ attr_reader :bytes, :size
38
+
25
39
  def initialize()
26
40
  super
41
+ @bytes = -1
42
+ @size = 1
27
43
  @filter_queues = []
28
44
  end
29
45
 
46
+ # returns an json list of visible queues
30
47
  def poll()
31
48
  item = OpenStruct.new
32
49
 
@@ -43,6 +60,7 @@ module FreeMessageQueue
43
60
  item
44
61
  end
45
62
 
63
+ # can be either used to *create* or *delete* a queue
46
64
  def put(data)
47
65
  if data.match(/_method=delete&path=(.*)/)
48
66
  # delete queue
@@ -54,10 +72,8 @@ module FreeMessageQueue
54
72
  end
55
73
  end
56
74
 
57
- def size
58
- 1 # there is always a message in the queue
59
- end
60
-
75
+ # *CONFIGURATION* *OPTION*
76
+ # sets the paths that should be filterd out, seperate them with space char
61
77
  def filter=(str)
62
78
  @filter_queues = str.split " "
63
79
  end
@@ -73,6 +89,7 @@ module FreeMessageQueue
73
89
  skip
74
90
  end
75
91
 
92
+ # converts the data of one queue to json format
76
93
  def queue_to_json(queue_name)
77
94
  constraints = manager.queue_constraints(queue_name)
78
95
 
@@ -3,50 +3,69 @@
3
3
  #
4
4
  # This file is part of the Free Message Queue.
5
5
  #
6
- # Foobar is free software: you can redistribute it and/or modify
6
+ # Free Message Queue is free software: you can redistribute it and/or modify
7
7
  # it under the terms of the GNU General Public License as published by
8
8
  # the Free Software Foundation, either version 3 of the License, or
9
9
  # (at your option) any later version.
10
10
  #
11
- # Foobar is distributed in the hope that it will be useful,
11
+ # Free Message Queue is distributed in the hope that it will be useful,
12
12
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
13
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
14
  # GNU General Public License for more details.
15
15
  #
16
16
  # You should have received a copy of the GNU General Public License
17
- # along with Foobar. If not, see <http://www.gnu.org/licenses/>.
18
- #
17
+ # along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
19
  module FreeMessageQueue
20
+ # This queue returns everytime the same file. This is useful during debugging or
21
+ # to serve the admin page.
22
+ #
23
+ # configuration sample:
24
+ # queue-manager:
25
+ # auto-create-queues: true
26
+ # defined-queues:
27
+ # admin-page-index:
28
+ # path: /admin/index
29
+ # class: FreeMessageQueue::FileQueue
30
+ # file: admin-interface/index.html
31
+ # content-type: text/html
32
+ #
33
+ # *NOTE* the put method is not implemented in this queue. It is a poll only queue.
20
34
  class FileQueue
35
+ # QueueManager refrence
21
36
  attr_accessor :manager
22
-
23
- def initialize()
24
- super
37
+
38
+ # Bytes are -1 at startup but fill after first poll. Size is allways 1 message
39
+ attr_reader :bytes, :size
40
+
41
+ def initialize
42
+ # there is always one message (the file) in the queue
43
+ @bytes = -1
44
+ @size = 1
25
45
  end
26
46
 
47
+ # Return the file and content type
27
48
  def poll()
28
49
  item = OpenStruct.new
29
50
 
30
51
  f = open(@file_path, "rb")
31
52
  item.data = f.read
53
+ @bytes = item.data.size
32
54
  f.close
33
55
 
34
56
  item.content_type = @content_type
35
57
  item
36
58
  end
37
-
38
- def put(data)
39
- # do nothing
40
- end
41
-
42
- def size
43
- 1 # there is always a message in the queue
44
- end
45
59
 
60
+ # *CONFIGURATION* *OPTION*
61
+ # sets the path to the file that should be read
46
62
  def file=(path)
47
63
  @file_path = path
48
64
  end
49
65
 
66
+ # *CONFIGURATION* *OPTION*
67
+ # sets the content_type of the file. This option
68
+ # make sense if you want to test with the webbrowser.
50
69
  def content_type=(type)
51
70
  @content_type = type
52
71
  end
@@ -0,0 +1,60 @@
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 "ostruct"
20
+
21
+ module FreeMessageQueue
22
+ # This queue returns sends one message to several queues at a time.
23
+ #
24
+ # configuration sample:
25
+ # queue-manager:
26
+ # auto-create-queues: true
27
+ # defined-queues:
28
+ # path: /fmq_test/forward_to_1_and_2
29
+ # class: FreeMessageQueue::ForwardQueue
30
+ # forward_to: /fmq_test/test1 /fmq_test/test2
31
+ #
32
+ # *NOTE* the poll method is not implemented in this queue. It is a put only queue.
33
+ class ForwardQueue
34
+ # QueueManager refrence
35
+ attr_accessor :manager
36
+
37
+ # Bytes and size are allways 0 because this queue holds no data
38
+ attr_reader :bytes, :size
39
+
40
+ def initialize
41
+ @bytes = @size = 0
42
+ @forwards = []
43
+ end
44
+
45
+ # put the data from this queue to the queues
46
+ # that are specified in the <em>forward-to</em> configuration option.
47
+ def put(data)
48
+ for forward in @forwards do
49
+ @manager.put(forward, data)
50
+ end
51
+ end
52
+
53
+ # *CONFIGURATION* *OPTION
54
+ # you can add as may queues as you want
55
+ # but seperate them with a space char
56
+ def forward_to=(urls)
57
+ @forwards = urls.split " "
58
+ end
59
+ end
60
+ end
@@ -3,33 +3,40 @@
3
3
  #
4
4
  # This file is part of the Free Message Queue.
5
5
  #
6
- # Foobar is free software: you can redistribute it and/or modify
6
+ # Free Message Queue is free software: you can redistribute it and/or modify
7
7
  # it under the terms of the GNU General Public License as published by
8
8
  # the Free Software Foundation, either version 3 of the License, or
9
9
  # (at your option) any later version.
10
10
  #
11
- # Foobar is distributed in the hope that it will be useful,
11
+ # Free Message Queue is distributed in the hope that it will be useful,
12
12
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
13
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
14
  # GNU General Public License for more details.
15
15
  #
16
16
  # You should have received a copy of the GNU General Public License
17
- # along with Foobar. If not, see <http://www.gnu.org/licenses/>.
18
- #
17
+ # along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
19
  module FreeMessageQueue
20
+ # Simple queue item class is used, because it is
21
+ # considered to be faster than ostruct
20
22
  class QueueItem
21
23
  attr_accessor :next, :data, :created_at
22
24
 
25
+ # Create queue item
23
26
  def initialize(data, created_at = Time.new)
24
27
  @data = data
25
28
  @created_at = created_at
26
29
  end
27
30
 
31
+ # Aize of item in bytes
28
32
  def bytes
29
33
  @data.size
30
34
  end
31
35
  end
32
36
 
37
+ # *DO* *NOT* *USE* *THIS* *QUEUE* *DIRECTLY* *IN* *THE* *QUEUE* *MANAGER*
38
+ # it is not thread safe.
39
+ # This Queue implements a FIFO based store in system memory.
33
40
  class LinkedQueue
34
41
  attr_reader :size, :bytes
35
42
 
@@ -40,13 +47,14 @@ module FreeMessageQueue
40
47
  @bytes = 0
41
48
  end
42
49
 
43
- # remove all items
50
+ # Remove all items from the queue
44
51
  def clear
45
52
  if size > 0
46
53
  while self.poll; end
47
54
  end
48
55
  end
49
-
56
+
57
+ # Put an item to the queue
50
58
  def put(data)
51
59
  return false if data == nil
52
60
 
@@ -67,6 +75,7 @@ module FreeMessageQueue
67
75
  true
68
76
  end
69
77
 
78
+ # Return an item from the queue
70
79
  def poll()
71
80
  if @size > 0
72
81
  # remove allways the first item
@@ -3,24 +3,38 @@
3
3
  #
4
4
  # This file is part of the Free Message Queue.
5
5
  #
6
- # Foobar is free software: you can redistribute it and/or modify
6
+ # Free Message Queue is free software: you can redistribute it and/or modify
7
7
  # it under the terms of the GNU General Public License as published by
8
8
  # the Free Software Foundation, either version 3 of the License, or
9
9
  # (at your option) any later version.
10
10
  #
11
- # Foobar is distributed in the hope that it will be useful,
11
+ # Free Message Queue is distributed in the hope that it will be useful,
12
12
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
13
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
14
  # GNU General Public License for more details.
15
15
  #
16
16
  # You should have received a copy of the GNU General Public License
17
- # along with Foobar. If not, see <http://www.gnu.org/licenses/>.
18
- #
17
+ # along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
19
  require File.dirname(__FILE__) + '/syncronized'
20
20
 
21
21
  module FreeMessageQueue
22
- class LoadBalancedQueue
23
- attr_accessor :queues, :manager
22
+ # This queue is an approach to the issue that you want to have
23
+ # multiple threads at one queue at a time. Currently this is not
24
+ # considered to be a stable queue. Just use it for experimental things.
25
+ #
26
+ # configuration sample:
27
+ # queue-manager:
28
+ # auto-create-queues: true
29
+ # defined-queues:
30
+ # test-queue-1:
31
+ # path: /fmq_test/test1
32
+ # max-messages: 1000000
33
+ # max-size: 10kb
34
+ # class: FreeMessageQueue::LoadBalancedQueue
35
+ class LoadBalancedQueue
36
+ # QueueManager refrence
37
+ attr_accessor :manager
24
38
 
25
39
  def initialize(queue_count = 5)
26
40
  @queues = []
@@ -31,6 +45,7 @@ module FreeMessageQueue
31
45
  @semaphore = Mutex.new
32
46
  end
33
47
 
48
+ # delete all messages in all queues
34
49
  def clear
35
50
  @queues.each { |q| q.clear }
36
51
  end
@@ -49,15 +64,17 @@ module FreeMessageQueue
49
64
  return tmp_bytes
50
65
  end
51
66
 
67
+ # Return one message from one of the queues
52
68
  def poll
53
69
  @queues[next_poll_index].poll
54
70
  end
55
71
 
72
+ # Put an item to one of the queues
56
73
  def put(data)
57
74
  @queues[next_put_index].put(data)
58
75
  end
59
76
 
60
- private
77
+ private
61
78
 
62
79
  # next index acts like 'round robin'
63
80
  def next_poll_index
@@ -3,23 +3,34 @@
3
3
  #
4
4
  # This file is part of the Free Message Queue.
5
5
  #
6
- # Foobar is free software: you can redistribute it and/or modify
6
+ # Free Message Queue is free software: you can redistribute it and/or modify
7
7
  # it under the terms of the GNU General Public License as published by
8
8
  # the Free Software Foundation, either version 3 of the License, or
9
9
  # (at your option) any later version.
10
10
  #
11
- # Foobar is distributed in the hope that it will be useful,
11
+ # Free Message Queue is distributed in the hope that it will be useful,
12
12
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
13
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
14
  # GNU General Public License for more details.
15
15
  #
16
16
  # You should have received a copy of the GNU General Public License
17
- # along with Foobar. If not, see <http://www.gnu.org/licenses/>.
18
- #
17
+ # along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
18
+ #
19
19
  require 'thread'
20
20
  require File.dirname(__FILE__) + '/linked'
21
21
 
22
22
  module FreeMessageQueue
23
+ # The SyncronizedQueue implements a little wrapper around the
24
+ # LinkedQueue to make it thread safe
25
+ #
26
+ # configuration sample:
27
+ # queue-manager:
28
+ # auto-create-queues: true
29
+ # defined-queues:
30
+ # test-queue-1:
31
+ # path: /fmq_test/test1
32
+ # max-messages: 1000000
33
+ # max-size: 10kb
23
34
  class SyncronizedQueue < LinkedQueue
24
35
  attr_accessor :manager
25
36
 
@@ -28,12 +39,14 @@ module FreeMessageQueue
28
39
  @semaphore = Mutex.new
29
40
  end
30
41
 
42
+ # Returns one item from the queue
31
43
  def poll()
32
44
  @semaphore.synchronize {
33
45
  super
34
46
  }
35
47
  end
36
48
 
49
+ # Puts one item to the queue
37
50
  def put(data)
38
51
  @semaphore.synchronize {
39
52
  super(data)
@@ -3,24 +3,24 @@
3
3
  #
4
4
  # This file is part of the Free Message Queue.
5
5
  #
6
- # Foobar is free software: you can redistribute it and/or modify
6
+ # Free Message Queue is free software: you can redistribute it and/or modify
7
7
  # it under the terms of the GNU General Public License as published by
8
8
  # the Free Software Foundation, either version 3 of the License, or
9
9
  # (at your option) any later version.
10
10
  #
11
- # Foobar is distributed in the hope that it will be useful,
11
+ # Free Message Queue is distributed in the hope that it will be useful,
12
12
  # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
13
  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
14
  # GNU General Public License for more details.
15
15
  #
16
16
  # You should have received a copy of the GNU General Public License
17
- # along with Foobar. If not, see <http://www.gnu.org/licenses/>.
17
+ # along with Free Message Queue. If not, see <http://www.gnu.org/licenses/>.
18
18
  #
19
19
  module FreeMessageQueue
20
20
  module VERSION #:nodoc:
21
21
  MAJOR = 0
22
22
  MINOR = 1
23
- TINY = 0
23
+ TINY = 1
24
24
 
25
25
  STRING = [MAJOR, MINOR, TINY].join('.')
26
26
  end
File without changes
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.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vincent Landgraf
@@ -20,8 +20,8 @@ executables:
20
20
  - fmq
21
21
  extensions: []
22
22
 
23
- extra_rdoc_files: []
24
-
23
+ extra_rdoc_files:
24
+ - lib/fmq/queues/README.txt
25
25
  files:
26
26
  - bin/fmq
27
27
  - default-server/admin-interface/images/logo.png
@@ -34,8 +34,10 @@ files:
34
34
  - lib/fmq/boot.rb
35
35
  - lib/fmq/mongrel_server.rb
36
36
  - lib/fmq/queue_manager.rb
37
+ - lib/fmq/queues/README.txt
37
38
  - lib/fmq/queues/admin.rb
38
39
  - lib/fmq/queues/file.rb
40
+ - lib/fmq/queues/forward.rb
39
41
  - lib/fmq/queues/linked.rb
40
42
  - lib/fmq/queues/load_balanced.rb
41
43
  - lib/fmq/queues/syncronized.rb
@@ -67,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
69
  requirements: []
68
70
 
69
71
  rubyforge_project: fmq
70
- rubygems_version: 1.0.1
72
+ rubygems_version: 1.2.0
71
73
  signing_key:
72
74
  specification_version: 2
73
75
  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.