plugg 0.0.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +5 -5
  2. data/lib/plugg.rb +131 -43
  3. metadata +43 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0988eac668e53bb82c2ddc8038fe404bc45c8c36
4
- data.tar.gz: 5637be96140af547726975c0b2368a11e0f08f71
2
+ SHA256:
3
+ metadata.gz: 7b0bf38d3e6aaddc835e122ca4186a378ed7a02bd32e13317dfa94165f39bd99
4
+ data.tar.gz: bcea21911dc7bce085bb53788c027f6ac95d7233985dc19626316bfec316931f
5
5
  SHA512:
6
- metadata.gz: 2739d5375074a4c7df289c99fd6c1a8bfb852d91c0fc1ac728385bf794458ebe610cf81554b748548a8eb8e88cb8a557d2a9c4f99a55a274830c9439269ff1c5
7
- data.tar.gz: c332fcc6861d947749393323daec08683634039de8ffd118a0dd12d06b02be069a174e9238946f72abaafc185b3132ffbb83564dbe1935a3c9df9bc9aad76f79
6
+ metadata.gz: a9052c09eb89ea8314d619d1eb377e11f26ebd533e7bdcbee931caeac7638a54cca6039cbe4a38efe445186ceb249915a34a8a6fd442e02ee4b38be745dd54da
7
+ data.tar.gz: 6ca5ca8dc2bfb25ab6bdcbc98b0e6efd2570976da0c3912d90ed98b2fb551a7fd5cfc7dbbae3512462b0e05f2e4bb3c09f582f2b04eada3ae6fd27e6dc859d85
@@ -1,12 +1,14 @@
1
1
  require 'singleton'
2
+ require 'timeout'
3
+ require 'ostruct'
2
4
 
3
5
  module Plugg
4
-
5
6
  ##
6
- # Set the source directory to load the plugins from
7
+ # Set the source directory to load the plugins & dependencies from
7
8
  #
9
+ # @param hash params
8
10
  # @param mixed path
9
- def Plugg.source(path)
11
+ def Plugg.source(path, params = {})
10
12
 
11
13
  load_path = []
12
14
 
@@ -19,14 +21,22 @@ module Plugg
19
21
  File.directory?(p)
20
22
  end
21
23
 
22
- load_path.concat path
24
+ load_path.concat(path)
23
25
  end
24
26
 
25
27
  if load_path.empty?
26
- raise "Plugin load paths contain no valid directories"
28
+ raise 'Unable to locate plugins in the provided load paths'
27
29
  end
28
30
 
29
- Dispatcher.plugin_path = load_path
31
+ Dispatcher.instance.start(load_path, params)
32
+ end
33
+
34
+ ##
35
+ # Set the dispatch plugin timeout value
36
+ #
37
+ # @param integer t
38
+ def Plugg.timeout(t = 30)
39
+ Dispatcher.instance.set_timeout(t)
30
40
  end
31
41
 
32
42
  ##
@@ -44,33 +54,79 @@ module Plugg
44
54
  # @param hash params
45
55
  # @return mixed
46
56
  def Plugg.send(evt, params = {})
47
- Dispatcher.instance.on(evt, params)
57
+ Dispatcher.instance.on(evt.to_sym, params)
58
+ end
59
+
60
+ private
61
+
62
+ class DispatchResponder
63
+ attr_reader :plugin
64
+ attr_reader :meta
65
+
66
+ def initialize(plugin = nil)
67
+ @meta = OpenStruct.new
68
+
69
+ @meta.start_time = Time.now
70
+ @meta.plugin = plugin
71
+ @meta.response = nil
72
+ @meta.runtime = nil
73
+ @meta.error = nil
74
+ end
75
+
76
+ def trap(timeout = 5)
77
+ Timeout::timeout(timeout) {
78
+ begin
79
+ @meta.response = yield
80
+ rescue Exception => e
81
+ @meta.error = e
82
+ end
83
+ }
84
+
85
+ @meta.runtime = (Time.now - @start_time) * 1000
86
+ end
87
+
88
+ def finalize
89
+ if @meta.plugin.respond_to?(:after)
90
+ @meta.plugin.send(:after)
91
+ end
92
+ end
93
+
94
+ def ok?
95
+ @meta.error.nil?
96
+ end
97
+
98
+ def error
99
+ @meta.error
100
+ end
101
+
102
+ def to_h
103
+ defaults = {
104
+ plugin: @meta.plugin.to_s,
105
+ runtime: @meta.runtime,
106
+ response: @meta.error,
107
+ success: ok?
108
+ }
109
+
110
+ defaults
111
+ end
48
112
  end
49
113
 
50
114
  class Dispatcher
51
115
  include Singleton
52
116
 
53
117
  attr_reader :registry
54
-
55
- @@plugin_path = []
118
+ attr_accessor :timeout
56
119
 
57
120
  ##
58
121
  # Assign a path where plugins should be loaded from
59
122
  #
60
- # @param string path
123
+ # @param mixed path
124
+ # @param hash params
61
125
  # @return void
62
- def self.plugin_path=(path)
63
- @@plugin_path = path
64
- end
65
-
66
- ##
67
- # Initialize the dispatcher and load the plugin instances
68
- #
69
- # @return void
70
- def initialize
126
+ def start(paths, params = {})
71
127
  @registry = []
72
128
 
73
- @@plugin_path.each do |path|
129
+ paths.each do |path|
74
130
  if path[-1] == '/'
75
131
  path.chop!
76
132
  end
@@ -80,49 +136,81 @@ module Plugg
80
136
  require File.expand_path(f)
81
137
 
82
138
  begin
83
- @registry.push(
84
- Object.const_get(File.basename(f, '.rb')).new
85
- )
139
+ instance = Object.const_get(File.basename(f, '.rb')).new
140
+
141
+ # `before` event callback
142
+ if instance.respond_to?(:before)
143
+ instance.send(:before)
144
+ end
145
+
146
+ # `setup` method
147
+ if instance.respond_to?(:setup)
148
+ instance.send(:setup, params)
149
+ end
150
+
151
+ @registry.push(instance)
152
+
86
153
  rescue Exception => e
87
- puts "#{f} Initialization Exception."
154
+ puts "#{f} Plugg Initialization Exception: #{e}"
88
155
  end
89
156
  end
90
157
  end
91
158
  end
92
159
 
160
+ ##
161
+ # Set the the thread execution timeout
162
+ #
163
+ # @param integer t
164
+ # @return void
165
+ def set_timeout(t)
166
+ @timeout = t
167
+ end
168
+
169
+ ##
170
+ # Initialize the dispatcher instance with a default timeout of 5s
171
+ #
172
+ # @return void
173
+ def initialize
174
+ @timeout = 5
175
+ end
176
+
93
177
  ##
94
178
  # Loop through all services and fire off the supported messages
95
179
  #
96
180
  # @param string method
97
181
  # @return void
98
182
  def on(method, *args, &block)
99
- buffer = []
100
183
 
101
- @registry.each do |s|
102
- if s.respond_to?(method.to_sym, include_private = false)
184
+ if [:initialize, :before, :setup, :after].include? method
185
+ raise "#{method} should not be called directly"
186
+ end
103
187
 
104
- start = Time.now
105
- response = nil
188
+ buffer = [] # Container for the response buffer
189
+ threads = [] # Container for the execution threads
106
190
 
107
- begin
108
- if s.method(method.to_sym).arity == 0
109
- response = s.send(method, &block)
110
- else
111
- response = s.send(method, *args, &block)
191
+ @registry.each do |s|
192
+ if s.respond_to?(method.to_sym, false)
193
+ threads << Thread.new do
194
+ responder = DispatchResponder.new(s)
195
+
196
+ responder.trap(@timeout) do
197
+ if s.method(method.to_sym).arity == 0
198
+ s.send(method, &block)
199
+ else
200
+ s.send(method, *args, &block)
201
+ end
112
202
  end
113
- rescue Exception => e
114
- response = e
115
- end
116
203
 
117
- buffer << {
118
- :plugin => s.to_s,
119
- :return => response,
120
- :timing => (Time.now - start) * 1000
121
- }
204
+ responder.finalize
205
+
206
+ buffer << responder.to_h
207
+ end
122
208
  end
123
209
  end
124
210
 
211
+ threads.map(&:join)
212
+
125
213
  buffer
126
214
  end
127
215
  end
128
- end
216
+ end
metadata CHANGED
@@ -1,26 +1,60 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: plugg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sean Nieuwoudt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-03 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2020-07-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.7'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 5.7.0
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '5.7'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 5.7.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '13.0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '13.0'
13
47
  description: Plugg allows you to easily extend your application by providing you with
14
- a bolt-on plugin framework
15
- email: sean@wixelhq.com
48
+ a plug and play plugin framework
49
+ email: sean@isean.co.za
16
50
  executables: []
17
51
  extensions: []
18
52
  extra_rdoc_files: []
19
53
  files:
20
54
  - lib/plugg.rb
21
- homepage: https://wixelhq.com
55
+ homepage: https://github.com/sn/plugg
22
56
  licenses:
23
- - GPL2
57
+ - GPL-2.0
24
58
  metadata: {}
25
59
  post_install_message:
26
60
  rdoc_options: []
@@ -37,9 +71,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
37
71
  - !ruby/object:Gem::Version
38
72
  version: '0'
39
73
  requirements: []
40
- rubyforge_project:
41
- rubygems_version: 2.4.5
74
+ rubygems_version: 3.1.4
42
75
  signing_key:
43
76
  specification_version: 4
44
- summary: Plugg is an independent plugin creation framework and DSL
77
+ summary: Plugg is a an asynchronous DSL for creating performant plugins
45
78
  test_files: []