lib/ezmlm/listdaemon.rb
author Michael Granger <mgranger@laika.com>
Wed, 06 Aug 2008 17:24:00 +0000
changeset 6 66beb495a861
permissions -rw-r--r--
Checkpoint commit.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
     1
#!/usr/bin/ruby
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
     2
#
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
     3
# A DRb interface to one or more ezmlm-idx mailing lists.
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
     4
#
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
     5
# == Version
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
     6
#
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
     7
#  $Id$
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
     8
#
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
     9
# == Authors
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    10
#
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    11
# * Michael Granger <mgranger@laika.com>
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    12
# * Jeremiah Jordan <jjordan@laika.com>
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    13
#
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    14
# :include: LICENSE
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    15
# 
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    16
#---
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    17
#
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    18
# Please see the file LICENSE in the base directory for licensing details.
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    19
#
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    20
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    21
require 'pathname'
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    22
require 'ezmlm'
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    23
require 'ezmlm/list'
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    24
require 'drb'
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    25
require 'ostruct'
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    26
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    27
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    28
### A DRb interface to one or more ezmlm-idx mailing lists
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    29
class Ezmlm::ListDaemon
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    30
	
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    31
	# The default port to listen on
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    32
	DEFAULT_PORT = 32315
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    33
	
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    34
	# The default address to bind to
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    35
	DEFAULT_ADDRESS = '127.0.0.1'
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    36
	
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    37
	
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    38
	### The interface that is presented to DRb
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    39
	class Service
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    40
		include Enumerable
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    41
		
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    42
		### Create a new service endpoint for the specified +listsdir+, which is a directory
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    43
		### which contains ezmlm-idx list directories.
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    44
		def initialize( listsdir )
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    45
			listsdir = Pathname.new( listsdir )
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    46
			@listsdir = listsdir
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    47
		end
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    48
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    49
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    50
		######
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    51
		public
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    52
		######
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    53
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    54
		# The directory which contains the list directories that should be served.
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    55
		attr_reader :listsdir
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    56
		
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    57
		
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    58
		### Create a new Ezmlm::List object for the list directory with the specified +name+.
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    59
		def get_list( name )
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    60
			name = validate_listdir_name( name )
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    61
			return Ezmlm::List.new( self.listsdir + name )
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    62
		end
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    63
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    64
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    65
		### Iterate over each current list in the Service's listsdir, yielding an Ezmlm::List object
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    66
		### for each one.
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    67
		def each_list( &block ) # :yields: list_object
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    68
			Ezmlm.each_list( self.listsdir, &block )
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    69
		end
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    70
		alias_method :each, :each_list
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    71
		
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    72
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    73
		#######
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    74
		private
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    75
		#######
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    76
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    77
		VALID_LISTNAME_PATTERN = /^[a-z0-9.-]+$/i
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    78
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    79
		### Ensure that the given +name+ is a valid list name, raising an exception if not. Returns
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    80
		### an untainted copy of +name+.
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    81
		def validate_listdir_name( name )
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    82
			unless match = VALID_LISTNAME_PATTERN.match( name )
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    83
				raise ArgumentError, "invalid list name %p" % [ name ]
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    84
			end
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    85
			
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    86
			return match[0].untaint
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    87
		end
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    88
		
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    89
	end # class Service
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    90
	
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    91
	
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    92
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    93
	### Return an OpenStruct that contains the default options
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    94
	def self::default_options
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    95
		opts = OpenStruct.new
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    96
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    97
		opts.bind_addr  = DEFAULT_ADDRESS
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    98
		opts.bind_port  = DEFAULT_PORT
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
    99
		opts.debugmode  = false
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   100
		opts.helpmode   = false
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   101
		opts.foreground = false
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   102
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   103
		return opts
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   104
	end
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   105
	
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   106
	
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   107
	#################################################################
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   108
	###	I N S T A N C E   M E T H O D S
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   109
	#################################################################
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   110
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   111
	### Create a new Ezmlm::ListDaemon that will serve objects for the list directories
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   112
	### contained in +listsdir+. The +options+ argument, if given, is an object (such as the one
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   113
	### returned from ::default_options) that contains values for the following methods:
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   114
	### 
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   115
	### bind_addr::
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   116
	###   The address to bind to. Defaults to DEFAULT_ADDRESS.
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   117
	### bind_port::
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   118
	###   The port to listen on. Defaults to DEFAULT_PORT.
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   119
	### debugmode:: 
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   120
	###   Whether to run in debugging mode, which causes the daemon to run in the foreground
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   121
	###   and send any output to STDERR. Defaults to +false+.
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   122
	### foreground::
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   123
	###   Don't go into the background.
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   124
	def initialize( listsdir, options=nil )
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   125
		@service = Service.new( listsdir )
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   126
		@options = options || self.class.default_options
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   127
	end
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   128
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   129
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   130
	######
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   131
	public
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   132
	######
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   133
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   134
	# The daemon's configuration options
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   135
	attr_reader :options
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   136
	
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   137
	# The Ezmlm::ListDaemon::Service object that serves as the DRb interface
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   138
	attr_reader :service
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   139
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   140
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   141
	### Daemonize unless configured otherwise, start the DRb service and return the listening 
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   142
	### Thread object
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   143
	def start
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   144
		uri = "druby://%s:%d" % [ self.options.bind_addr, self.options.bind_port ]
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   145
		DRb.start_service( uri, @service )
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   146
		
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   147
		return DRb.thread
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   148
	end
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   149
	
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   150
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   151
end # class Ezmlm::ListDaemon
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   152
66beb495a861 Checkpoint commit.
Michael Granger <mgranger@laika.com>
parents:
diff changeset
   153
# vim: set nosta noet ts=4 sw=4: