fmq 0.1.0 → 0.1.1

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/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.