xapian_db 0.5.9 → 0.5.10

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/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ##0.5.10 (April 6th, 2011)
2
+
3
+ Features:
4
+
5
+ - the beanstalk worker is now implemented as a daemon script (execute 'rails generate xapian_db:install' to install it)
6
+ - execute a block with auto indexing disabled (see 'Bulk inserts / updates / deletes' in teh README)
7
+ - updated the xapian source to version 1.2.5
8
+
1
9
  ##0.5.9 (March 25th, 2011)
2
10
 
3
11
  Fixes:
data/README.rdoc CHANGED
@@ -244,6 +244,19 @@ only if the block does not raise an exception.
244
244
  object2.save
245
245
  end
246
246
 
247
+ === Bulk inserts / updates / deletes
248
+
249
+ When you change a lot of models, it is not very efficient to update the xapian index on each insert / update / delete. Instead,
250
+ you can use the auto_indexing_disabled method with a block and rebuild the whole index afterwards:
251
+
252
+ XapianDb.auto_indexing_disabled do
253
+ Person.each do |person|
254
+ # change person
255
+ person.save
256
+ end
257
+ end
258
+ Person.rebuild_xapian_index
259
+
247
260
  == Production setup
248
261
 
249
262
  Since Xapian allows only one database instance to write to the index, the default setup of XapianDb will not work
@@ -282,21 +295,26 @@ The easiest way is to use macports or homebrew:
282
295
  gem 'beanstalk-client' # Add this to your Gemfile
283
296
  bundle install
284
297
 
285
- === 3. Configure your production environment in config/xapian_db.yml
298
+ === 3. Install the beanstalk worker script
299
+
300
+ rails generate xapian:db install
301
+
302
+ === 4. Configure your production environment in config/xapian_db.yml
286
303
 
287
304
  production:
288
305
  database: db/xapian_db/production
289
306
  writer: beanstalk
290
307
  beanstalk_daemon: localhost:11300
291
308
 
292
- === 4. start the beanstalk daemon
309
+ === 5. start the beanstalk daemon
293
310
 
294
311
  beanstalkd -d
295
312
 
296
- === 5. start the beanstalk worker from within your Rails app root directory
297
-
298
- rake RAILS_ENV=production xapian_db:beanstalk_worker
313
+ === 6. start the beanstalk worker from within your Rails app root directory
299
314
 
300
- <b>Important: Do not start multiple instances of this worker task!</b>
315
+ RAILS_ENV=production script/beanstalk_worker start
301
316
 
317
+ If everything is fine, you should find a file namend beanstalk_worker.pid in tmp/pids. If something
318
+ goes wrong, you'll find beanstalk_worker.log instead showing the stack trace.
302
319
 
320
+ <b>Important: Do not start multiple instances of this daemon!</b>
data/Rakefile CHANGED
@@ -9,7 +9,7 @@ def system!(cmd)
9
9
  system(cmd) or raise
10
10
  end
11
11
 
12
- ver = '1.2.4'
12
+ ver = '1.2.5'
13
13
  source_dir = 'xapian_source'
14
14
  core = "xapian-core-#{ver}"
15
15
  bindings = "xapian-bindings-#{ver}"
@@ -0,0 +1,17 @@
1
+ require 'rails/generators'
2
+
3
+ module XapianDb
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ source_root File.expand_path("../templates", __FILE__)
7
+
8
+ desc "Creates a beanstalk worker script."
9
+
10
+ def copy_script
11
+ copy_file "beanstalk_worker", "script/beanstalk_worker"
12
+ chmod "script/beanstalk_worker", 0755
13
+ end
14
+
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require "bundler/setup"
5
+ require 'rails'
6
+ require 'daemons'
7
+ require "xapian_db"
8
+ require 'yaml'
9
+ require 'rails/railtie' # execute xapian_db railtie
10
+
11
+ # daemon script to manage the beanstalk worker daemon
12
+ # @author Gernot Kogler
13
+ module XapianDb
14
+ class BeanstalkWorker
15
+
16
+ def process_requests
17
+
18
+ Rails.logger.info "XapianDb beanstalk worker: initializing..."
19
+
20
+ url = XapianDb::Config.beanstalk_daemon_url
21
+ beanstalk = Beanstalk::Pool.new([url])
22
+ worker = XapianDb::IndexWriters::BeanstalkWorker.new
23
+ Rails.logger.info "XapianDb beanstalk worker: ready"
24
+
25
+ loop do
26
+ begin
27
+ job = beanstalk.reserve
28
+ params = YAML::load job.body
29
+ Rails.logger.info "XapianDb beanstalk worker: executing task #{params}"
30
+ task = params.delete :task
31
+ worker.send task, params
32
+ rescue Exception => ex
33
+ Rails.logger.error "XapianDb beanstalk worker: could not process #{job.body} (#{ex})"
34
+ end
35
+
36
+ begin
37
+ job.delete
38
+ rescue Exception => ex
39
+ Rails.logger.error "XapianDb beanstalk worker: could delete job #{job.body} (#{ex})"
40
+ end
41
+
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ # =========================================================================================
48
+ # daemon setup
49
+ # =========================================================================================
50
+ dir = File.expand_path(File.join(File.dirname(__FILE__), '..'))
51
+ pids_dir = File.join(dir, 'tmp', 'pids')
52
+ FileUtils.makedirs pids_dir unless File.exists?(pids_dir)
53
+
54
+ daemon_options = {
55
+ :multiple => false,
56
+ :dir_mode => :normal,
57
+ :dir => pids_dir,
58
+ :backtrace => true
59
+ }
60
+
61
+ Daemons.run_proc('beanstalk_worker', daemon_options) do
62
+ if ARGV.include?('--')
63
+ ARGV.slice! 0..ARGV.index('--')
64
+ else
65
+ ARGV.clear
66
+ end
67
+
68
+ Dir.chdir dir
69
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment'))
70
+ XapianDb::BeanstalkWorker.new.process_requests
71
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ # This writer is a dummy writer that simply does nothing.
4
+ # @author Gernot Kogler
5
+
6
+ module XapianDb
7
+ module IndexWriters
8
+
9
+ class NoOpWriter
10
+
11
+ # Update an object in the index
12
+ # @param [Object] obj An instance of a class with a blueprint configuration
13
+ def index(obj); end
14
+
15
+ # Remove an object from the index
16
+ # @param [Object] obj An instance of a class with a blueprint configuration
17
+ def unindex(obj); end
18
+
19
+ # Reindex all objects of a given class
20
+ # @param [Class] klass The class to reindex
21
+ # @param [Hash] options Options for reindexing
22
+ # @option options [Boolean] :verbose (false) Should the reindexing give status informations?
23
+ def reindex_class(klass, options={})
24
+ raise "rebuild_xapian_index is not supported inside a block with auto indexing disabled"
25
+ end
26
+
27
+ end
28
+ end
29
+ end
@@ -9,11 +9,16 @@ module XapianDb
9
9
  # @author Gernot Kogler
10
10
  class Railtie < ::Rails::Railtie
11
11
 
12
- # Require our rake tasks
12
+ # require our rake tasks
13
13
  rake_tasks do
14
14
  load "#{File.dirname(__FILE__)}/../../tasks/beanstalk_worker.rake"
15
15
  end
16
16
 
17
+ # require our generators
18
+ generators do
19
+ require "#{File.dirname(__FILE__)}/../generators/install_generator.rb"
20
+ end
21
+
17
22
  config.before_configuration do
18
23
 
19
24
  # Read the database configuration file if there is one
@@ -49,24 +54,24 @@ module XapianDb
49
54
  load blueprints_file_path if File.exist?(blueprints_file_path)
50
55
  end
51
56
 
52
- private
57
+ private
53
58
 
54
- # use the config options from the config file
55
- def self.configure_from(env_config)
56
- @database_path = env_config["database"] || ":memory:"
57
- @adapter = env_config["adapter"] || :active_record
58
- @writer = env_config["writer"] || :direct
59
- @beanstalk_daemon = env_config["beanstalk_daemon"]
60
- @language = env_config["language"]
61
- end
59
+ # use the config options from the config file
60
+ def self.configure_from(env_config)
61
+ @database_path = env_config["database"] || ":memory:"
62
+ @adapter = env_config["adapter"] || :active_record
63
+ @writer = env_config["writer"] || :direct
64
+ @beanstalk_daemon = env_config["beanstalk_daemon"]
65
+ @language = env_config["language"]
66
+ end
62
67
 
63
- # set default config options
64
- def self.configure_defaults
65
- Rails.env == "test" ? @database_path = ":memory:" : @database_path = "db/xapian_db/#{Rails.env}"
66
- @adapter = :active_record
67
- @writer = :direct
68
- @beanstalk_daemon = nil
69
- end
68
+ # set default config options
69
+ def self.configure_defaults
70
+ Rails.env == "test" ? @database_path = ":memory:" : @database_path = "db/xapian_db/#{Rails.env}"
71
+ @adapter = :active_record
72
+ @writer = :direct
73
+ @beanstalk_daemon = nil
74
+ end
70
75
 
71
76
  end
72
77
  end
data/lib/xapian_db.rb CHANGED
@@ -88,14 +88,14 @@ module XapianDb
88
88
  # Update an object in the index
89
89
  # @param [Object] obj An instance of a class with a blueprint configuration
90
90
  def self.index(obj)
91
- writer = @transactional_writer || XapianDb::Config.writer
91
+ writer = @block_writer || XapianDb::Config.writer
92
92
  writer.index obj
93
93
  end
94
94
 
95
95
  # Remove an object from the index
96
96
  # @param [Object] obj An instance of a class with a blueprint configuration
97
97
  def self.unindex(obj)
98
- writer = @transactional_writer || XapianDb::Config.writer
98
+ writer = @block_writer || XapianDb::Config.writer
99
99
  writer.unindex obj
100
100
  end
101
101
 
@@ -122,27 +122,47 @@ module XapianDb
122
122
 
123
123
  # Execute a block as a transaction
124
124
  def self.transaction(&block)
125
- # Temporarily use the transactional writer
126
- @transactional_writer = XapianDb::IndexWriters::TransactionalWriter.new
125
+ writer = XapianDb::IndexWriters::TransactionalWriter.new
126
+ execute_block :writer => writer, :error_message => "error in XapianDb transaction block, transaction aborted" do
127
+ block.call
128
+ writer.commit_using XapianDb::Config.writer
129
+ end
130
+ end
131
+
132
+ # Execute a block and do not update the index
133
+ def self.auto_indexing_disabled(&block)
134
+ execute_block :writer => XapianDb::IndexWriters::NoOpWriter.new do
135
+ block.call
136
+ end
137
+
138
+ end
139
+
140
+ # execute a block of code with a given writer and handle errors
141
+ # @param [Hash] opts Options
142
+ # @option opts [Object] :writer An index writer
143
+ # @option opts [String] :error_message the error message to log if an error occurs
144
+ def self.execute_block(opts, &block)
145
+ @block_writer = opts[:writer]
127
146
  begin
128
147
  block.call
129
- @transactional_writer.commit_using XapianDb::Config.writer
130
148
  rescue Exception => ex
131
- msg = "error in XapianDb transaction block: #{ex}, transaction aborted"
132
- if defined?(Rails)
133
- Rails.logger.error msg
134
- else
135
- puts msg
149
+ if opts[:error_message]
150
+ if defined?(Rails)
151
+ Rails.logger.error opts[:error_message]
152
+ else
153
+ puts opts[:error_message]
154
+ end
136
155
  end
156
+ raise
137
157
  ensure
138
- # release the transactional writer
139
- @transactional_writer = nil
158
+ # release the block writer
159
+ @block_writer = nil
140
160
  end
141
161
  end
142
162
 
143
163
  end
144
164
 
145
- do_not_require = %w(update_stopwords.rb railtie.rb base_adapter.rb beanstalk_writer.rb utilities.rb)
165
+ do_not_require = %w(update_stopwords.rb railtie.rb base_adapter.rb beanstalk_writer.rb utilities.rb install_generator.rb)
146
166
  files = Dir.glob("#{File.dirname(__FILE__)}/**/*.rb").reject{|path| do_not_require.include?(File.basename(path))}
147
167
  # Require these first
148
168
  require "#{File.dirname(__FILE__)}/xapian_db/utilities"
@@ -11,16 +11,18 @@ require 'yaml'
11
11
 
12
12
  namespace :xapian_db do
13
13
 
14
- desc "Run the beanstalk worker process to update the xapian index"
14
+ DEPRECATION_WARNING = "beanstalk_worker.rake is deprecated, use script/beanstalk_worker instead"
15
+ desc DEPRECATION_WARNING
15
16
  task :beanstalk_worker do
16
17
 
17
18
  url = XapianDb::Config.beanstalk_daemon_url
18
19
  beanstalk = Beanstalk::Pool.new([url])
19
20
  worker = XapianDb::IndexWriters::BeanstalkWorker.new
21
+ puts DEPRECATION_WARNING
20
22
  puts "XapianDb beanstalk worker is serving on #{url}..."
21
23
  loop do
22
- job = beanstalk.reserve
23
24
  begin
25
+ job = beanstalk.reserve
24
26
  params = YAML::load job.body
25
27
  Rails.logger.info "XapianDb beanstalk worker: executing task #{params}"
26
28
  task = params.delete :task
@@ -28,7 +30,13 @@ namespace :xapian_db do
28
30
  rescue Exception => ex
29
31
  Rails.logger.error "XapianDb beanstalk worker: could not process #{job.body} (#{ex})"
30
32
  end
31
- job.delete
33
+
34
+ begin
35
+ job.delete
36
+ rescue Exception => ex
37
+ Rails.logger.error "XapianDb beanstalk worker: could delete job #{job.body} (#{ex})"
38
+ end
39
+
32
40
  end
33
41
 
34
42
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 5
8
- - 9
9
- version: 0.5.9
8
+ - 10
9
+ version: 0.5.10
10
10
  platform: ruby
11
11
  authors:
12
12
  - Gernot Kogler
@@ -14,13 +14,28 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-03-25 00:00:00 +01:00
17
+ date: 2011-04-06 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- name: rspec
21
+ name: daemons
22
22
  prerelease: false
23
23
  requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 0
31
+ - 10
32
+ version: 1.0.10
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
24
39
  none: false
25
40
  requirements:
26
41
  - - ">="
@@ -31,11 +46,11 @@ dependencies:
31
46
  - 1
32
47
  version: 2.3.1
33
48
  type: :development
34
- version_requirements: *id001
49
+ version_requirements: *id002
35
50
  - !ruby/object:Gem::Dependency
36
51
  name: simplecov
37
52
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
53
+ requirement: &id003 !ruby/object:Gem::Requirement
39
54
  none: false
40
55
  requirements:
41
56
  - - ">="
@@ -46,11 +61,11 @@ dependencies:
46
61
  - 7
47
62
  version: 0.3.7
48
63
  type: :development
49
- version_requirements: *id002
64
+ version_requirements: *id003
50
65
  - !ruby/object:Gem::Dependency
51
66
  name: beanstalk-client
52
67
  prerelease: false
53
- requirement: &id003 !ruby/object:Gem::Requirement
68
+ requirement: &id004 !ruby/object:Gem::Requirement
54
69
  none: false
55
70
  requirements:
56
71
  - - ">="
@@ -61,7 +76,7 @@ dependencies:
61
76
  - 0
62
77
  version: 1.1.0
63
78
  type: :development
64
- version_requirements: *id003
79
+ version_requirements: *id004
65
80
  description: XapianDb is a ruby gem that combines features of nosql databases and fulltext indexing. It is based on Xapian, an efficient and powerful indexing library
66
81
  email: gernot.kogler (at) garaio (dot) com
67
82
  executables: []
@@ -71,6 +86,8 @@ extensions:
71
86
  extra_rdoc_files: []
72
87
 
73
88
  files:
89
+ - lib/generators/install_generator.rb
90
+ - lib/generators/templates/beanstalk_worker
74
91
  - lib/xapian_db/adapters/active_record_adapter.rb
75
92
  - lib/xapian_db/adapters/base_adapter.rb
76
93
  - lib/xapian_db/adapters/datamapper_adapter.rb
@@ -81,6 +98,7 @@ files:
81
98
  - lib/xapian_db/index_writers/beanstalk_worker.rb
82
99
  - lib/xapian_db/index_writers/beanstalk_writer.rb
83
100
  - lib/xapian_db/index_writers/direct_writer.rb
101
+ - lib/xapian_db/index_writers/no_op_writer.rb
84
102
  - lib/xapian_db/index_writers/transactional_writer.rb
85
103
  - lib/xapian_db/indexer.rb
86
104
  - lib/xapian_db/query_parser.rb
@@ -106,8 +124,8 @@ files:
106
124
  - lib/xapian_db/utilities.rb
107
125
  - lib/xapian_db.rb
108
126
  - tasks/beanstalk_worker.rake
109
- - xapian_source/xapian-bindings-1.2.4.tar.gz
110
- - xapian_source/xapian-core-1.2.4.tar.gz
127
+ - xapian_source/xapian-bindings-1.2.5.tar.gz
128
+ - xapian_source/xapian-core-1.2.5.tar.gz
111
129
  - LICENSE
112
130
  - README.rdoc
113
131
  - CHANGELOG.md
Binary file