plugg 0.0.1 → 1.0.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.
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: []