bento_search 1.0.1 → 1.0.2

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.
@@ -1,118 +1,131 @@
1
- require 'celluloid'
1
+ begin
2
+ require 'celluloid'
2
3
 
3
- # Based on Celluloid, concurrently runs multiple searches in
4
- # seperate threads. You must include 'celluloid' gem dependency
5
- # into your local app to use this class. Requires celluloid 0.12.0
6
- # or above (for new preferred async syntax).
7
- #
8
- # I am not an expert at use of Celluloid, it's possible there's a better
9
- # way to do this all, but seems to work.
10
- #
11
- # ## Usage
12
- #
13
- # initialize with id's of registered engines:
14
- # searcher = BentoBox::MultiSearcher.new(:gbs, :scopus)
15
- #
16
- # start the concurrent searches, params same as engine.search
17
- # searcher.search( query_params )
18
- #
19
- # retrieve results, blocking until each is completed:
20
- # searcher.results
21
- #
22
- # returns a Hash keyed by engine id, values BentoSearch::Results objects.
23
- #
24
- # Can only call #results once per #start, after that it'll return empty hash.
25
- # (should we make it actually raise instead?). .
26
- #
27
- # important to call results at some point after calling start, in order
28
- # to make sure Celluloid::Actors are properly terminated to avoid
29
- # resource leakage. May want to do it in an ensure block.
30
- #
31
- # Note that celluloid uses multi-threading in such a way that you
32
- # may have to set config.cache_classes=true even in development
33
- # to avoid problems. Rails class reloading is not thread-safe.
34
- #
35
- #
36
- # TODO: have a method that returns Futures instead of only supplying the blocking
37
- # results method? Several tricks, including making sure to properly terminate actors.
38
- class BentoSearch::MultiSearcher
39
-
40
- def initialize(*engine_ids)
41
- @engines = []
42
- @actors = []
43
- engine_ids.each do |id|
44
- add_engine( BentoSearch.get_engine id )
45
- end
46
- end
47
-
48
- # Adds an instantiated engine directly, rather than by id from global
49
- # registry.
50
- def add_engine(engine)
51
- @engines << engine
52
- end
53
-
54
- # Starts all searches, returns self so you can chain method calls if you like.
55
- def search(*search_args)
56
- @engines.each do |engine|
57
- a = Actor.new(engine)
58
- @actors << a
59
- a.async.start *search_args
60
- end
61
- return self
62
- end
63
- alias_method :start, :search # backwards compat
64
-
65
- # Call after #start. Blocks until each included engine is finished
66
- # then returns a Hash keyed by engine registered id, value is a
67
- # BentoSearch::Results object.
4
+ # Based on Celluloid, concurrently runs multiple searches in
5
+ # seperate threads. You must include 'celluloid' gem dependency
6
+ # into your local app to use this class. Requires celluloid 0.12.0
7
+ # or above (for new preferred async syntax).
8
+ #
9
+ # Warning, if you don't have celluloid in your app, this class simply
10
+ # won't load. TODO: We should put this file in a different directory
11
+ # so it's never auto-loaded, and requires a "require 'bento_search/multi_searcher'",
12
+ # such that it will raise without celluloid only then, and we don't need this
13
+ # rescue LoadError stuff.
14
+ #
15
+ # I am not an expert at use of Celluloid, it's possible there's a better
16
+ # way to do this all, but seems to work.
17
+ #
18
+ # ## Usage
19
+ #
20
+ # initialize with id's of registered engines:
21
+ # searcher = BentoBox::MultiSearcher.new(:gbs, :scopus)
22
+ #
23
+ # start the concurrent searches, params same as engine.search
24
+ # searcher.search( query_params )
68
25
  #
69
- # Can only call _once_ per invocation of #start, after that it'll return
70
- # an empty hash.
71
- def results
72
- results = {}
26
+ # retrieve results, blocking until each is completed:
27
+ # searcher.results
28
+ #
29
+ # returns a Hash keyed by engine id, values BentoSearch::Results objects.
30
+ #
31
+ # Can only call #results once per #start, after that it'll return empty hash.
32
+ # (should we make it actually raise instead?). .
33
+ #
34
+ # important to call results at some point after calling start, in order
35
+ # to make sure Celluloid::Actors are properly terminated to avoid
36
+ # resource leakage. May want to do it in an ensure block.
37
+ #
38
+ # Note that celluloid uses multi-threading in such a way that you
39
+ # may have to set config.cache_classes=true even in development
40
+ # to avoid problems. Rails class reloading is not thread-safe.
41
+ #
42
+ #
43
+ # TODO: have a method that returns Futures instead of only supplying the blocking
44
+ # results method? Several tricks, including making sure to properly terminate actors.
45
+ class BentoSearch::MultiSearcher
73
46
 
74
- # we use #delete_if to get an iterator that deletes
75
- # each item after iteration.
76
- @actors.delete_if do |actor|
77
- result_key = (actor.engine.configuration.id || actor.engine.class.name)
78
- results[result_key] = actor.results
79
- actor.terminate
80
-
81
- true
47
+ def initialize(*engine_ids)
48
+ @engines = []
49
+ @actors = []
50
+ engine_ids.each do |id|
51
+ add_engine( BentoSearch.get_engine id )
52
+ end
82
53
  end
83
54
 
84
- return results
85
- end
86
-
87
-
88
- class Actor
89
- include Celluloid
90
-
91
- attr_accessor :engine
55
+ # Adds an instantiated engine directly, rather than by id from global
56
+ # registry.
57
+ def add_engine(engine)
58
+ @engines << engine
59
+ end
92
60
 
93
- def initialize(a_engine)
94
- self.engine = a_engine
61
+ # Starts all searches, returns self so you can chain method calls if you like.
62
+ def search(*search_args)
63
+ @engines.each do |engine|
64
+ a = Actor.new(engine)
65
+ @actors << a
66
+ a.async.start *search_args
67
+ end
68
+ return self
95
69
  end
70
+ alias_method :start, :search # backwards compat
96
71
 
97
- # call as .async.start, to invoke async.
98
- def start(*search_args)
99
- begin
100
- @results = self.engine.search(*search_args)
101
- rescue Exception => e
102
- Rails.logger.error("\nBentoSearch:MultiSearcher caught exception: #{e}\n#{e.backtrace.join(" \n")}")
103
- # Make a fake results with caught exception.
104
- @results = BentoSearch::Results.new
105
- self.engine.fill_in_search_metadata_for(@results, self.engine.normalized_search_arguments(search_args))
72
+ # Call after #start. Blocks until each included engine is finished
73
+ # then returns a Hash keyed by engine registered id, value is a
74
+ # BentoSearch::Results object.
75
+ #
76
+ # Can only call _once_ per invocation of #start, after that it'll return
77
+ # an empty hash.
78
+ def results
79
+ results = {}
80
+
81
+ # we use #delete_if to get an iterator that deletes
82
+ # each item after iteration.
83
+ @actors.delete_if do |actor|
84
+ result_key = (actor.engine.configuration.id || actor.engine.class.name)
85
+ results[result_key] = actor.results
86
+ actor.terminate
106
87
 
107
- @results.error ||= {}
108
- @results.error["exception"] = e
88
+ true
109
89
  end
90
+
91
+ return results
110
92
  end
111
93
 
112
- def results
113
- @results
94
+
95
+ class Actor
96
+ include Celluloid
97
+
98
+ attr_accessor :engine
99
+
100
+ def initialize(a_engine)
101
+ self.engine = a_engine
102
+ end
103
+
104
+ # call as .async.start, to invoke async.
105
+ def start(*search_args)
106
+ begin
107
+ @results = self.engine.search(*search_args)
108
+ rescue Exception => e
109
+ Rails.logger.error("\nBentoSearch:MultiSearcher caught exception: #{e}\n#{e.backtrace.join(" \n")}")
110
+ # Make a fake results with caught exception.
111
+ @results = BentoSearch::Results.new
112
+ self.engine.fill_in_search_metadata_for(@results, self.engine.normalized_search_arguments(search_args))
113
+
114
+ @results.error ||= {}
115
+ @results.error["exception"] = e
116
+ end
117
+ end
118
+
119
+ def results
120
+ @results
121
+ end
122
+
114
123
  end
115
124
 
116
125
  end
117
-
126
+
127
+ rescue LoadError
128
+ # you can use bento_search without celluloid, just not
129
+ # this class.
118
130
  end
131
+
@@ -1,3 +1,3 @@
1
1
  module BentoSearch
2
- VERSION = "1.0.1"
2
+ VERSION = "1.0.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bento_search
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -400,7 +400,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
400
400
  version: '0'
401
401
  segments:
402
402
  - 0
403
- hash: -975980968364822597
403
+ hash: 4585903005501564692
404
404
  required_rubygems_version: !ruby/object:Gem::Requirement
405
405
  none: false
406
406
  requirements:
@@ -409,7 +409,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
409
409
  version: '0'
410
410
  segments:
411
411
  - 0
412
- hash: -975980968364822597
412
+ hash: 4585903005501564692
413
413
  requirements: []
414
414
  rubyforge_project:
415
415
  rubygems_version: 1.8.24