skn_utils 5.4.0 → 5.8.0

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 (40) hide show
  1. checksums.yaml +5 -5
  2. data/.rspec +2 -0
  3. data/README.md +223 -72
  4. data/_config.yml +4 -4
  5. data/bin/concurrent_test_block +54 -0
  6. data/bin/concurrent_test_grouped +45 -0
  7. data/bin/concurrent_test_procs +45 -0
  8. data/bin/concurrent_test_wrapped +49 -0
  9. data/lib/skn_container.rb +2 -1
  10. data/lib/skn_failure.rb +2 -0
  11. data/lib/skn_hash.rb +2 -0
  12. data/lib/skn_registry.rb +25 -5
  13. data/lib/skn_settings.rb +2 -0
  14. data/lib/skn_success.rb +2 -0
  15. data/lib/skn_utils.rb +13 -2
  16. data/lib/skn_utils/concurrent_jobs.rb +117 -0
  17. data/lib/skn_utils/configurable.rb +55 -6
  18. data/lib/skn_utils/configuration.rb +2 -0
  19. data/lib/skn_utils/core_extensions.rb +29 -0
  20. data/lib/skn_utils/dotted_hash.rb +1 -0
  21. data/lib/skn_utils/env_string_handler.rb +2 -0
  22. data/lib/skn_utils/http_processor.rb +34 -0
  23. data/lib/skn_utils/job_commands.rb +247 -0
  24. data/lib/skn_utils/nested_result.rb +2 -0
  25. data/lib/skn_utils/notifier_base.rb +2 -0
  26. data/lib/skn_utils/null_object.rb +2 -0
  27. data/lib/skn_utils/page_controls.rb +2 -0
  28. data/lib/skn_utils/result_bean.rb +2 -0
  29. data/lib/skn_utils/version.rb +3 -1
  30. data/lib/skn_utils/wrappable.rb +32 -0
  31. data/skn_utils.gemspec +27 -22
  32. data/spec/lib/skn_utils/concurrent_jobs_spec.rb +279 -0
  33. data/spec/lib/skn_utils/configurable_spec.rb +23 -36
  34. data/spec/lib/skn_utils/registry_spec.rb +22 -0
  35. data/spec/lib/skn_utils/wrappers_spec.rb +80 -0
  36. data/spec/spec_helper.rb +5 -0
  37. data/spec/support/configurables.rb +36 -0
  38. data/spec/support/xml_matchers.rb +121 -0
  39. metadata +71 -24
  40. data/README.rdoc +0 -379
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: faaa010ea403a5bfbf20386ee86a9c68e8982da1
4
- data.tar.gz: 909be6bef4b46a41bfd293d35a3059396d4adba5
2
+ SHA256:
3
+ metadata.gz: bdbe2b2318e4841c25afdec1e118cc19ff445f8a8b1e08d116715f5b9df0f56e
4
+ data.tar.gz: d42c5e55def5f8c2789714d1fada2f341f59665ba633192732b9e6b48816e253
5
5
  SHA512:
6
- metadata.gz: 46f92868aaecee7ece92b3d1c4b5bc33b5643e8c2de3a5f442e5141edb2b45d5a4cb8d4bd29e24241a34001b253abec38fe381e8ca8d798dc8eb6d662fdc12c2
7
- data.tar.gz: 81c41c8dda9b50797a76005a29cb329b2d8bc9da0af585d1848124a54606ac1f3a9d8bb8bb1d6ec5b2806df0002d673849425ca68290121e4ac327c7b94f784d
6
+ metadata.gz: b48e34a868729ed2fe63cc77c456a9b9eef99540355d4de6135c7cd5fe96c88b78519cc8384f2eb13c0a29b9652b4e84fbc1624a4674df0ec73c4f95d3762392
7
+ data.tar.gz: c435de19604f41834446ca04084ffc7a559267786974130edc03ad2a540f07eb08111571b13995f67e6bcfc122b215a3d5bb5cf26a905d1e3e85b31e4f0dfad3
data/.rspec CHANGED
@@ -1,2 +1,4 @@
1
1
  --color
2
2
  --require spec_helper
3
+ --format html
4
+ --out coverage/rspec_results.html
data/README.md CHANGED
@@ -2,68 +2,94 @@
2
2
  [![Gem Version](https://badge.fury.io/rb/skn_utils.svg)](http://badge.fury.io/rb/skn_utils)
3
3
 
4
4
  # SknUtils
5
- ## SknUtils::NestedResult class; dynamic key/value container
6
- A Ruby Gem containing a Ruby PORO (Plain Old Ruby Object) that can be instantiated at runtime with an input hash. This library creates
7
- an Object with Dot and Hash notational accessors to each key's value. Additional key/value pairs can be added post-create
8
- by simply assigning it; `obj.my_new_var = "some value"`
9
-
10
- * Transforms the initialing hash into accessible object instance values, with their keys as method names.
11
- * If the key's value is also a hash, it too will become an Object.
12
- * if the key's value is a Array of Hashes, or Array of Arrays of Hashes, each hash element of the Arrays will become an Object.
13
- * The current key/value (including nested) pairs are returned via #to_hash or #to_json when and if needed.
14
- * Best described as dot notation wrapper over a Ruby (Concurrent-Ruby) Hash.
15
5
 
16
- Ruby's Hash object is already extremely flexible, even more so with the addition of dot-notation. As I work more with Ruby outside of Rails, I'm finding more use cases for the capabilities of this gem. Here are a few examples:
17
-
18
- 1. Application settings containers, SknSettings. Loads Yaml file based on `ENV['RACK_ENV']` value, or specified file-key.
19
- - Replaces Config and/or RBConfig Gems for yaml based settings
20
- 1. Substitute for Rails.root, via a little ERB/YAML/Marshal statement in settings.yml file, and a helper class
21
- - settings.yml (YAML)
22
- - `root: <%= Dir.pwd %>`
23
- - enables `SknSettings.root`
24
- - `env: !ruby/string:SknUtils::EnvStringHandler <%= ENV.fetch('RACK_ENV', 'development') %>`
25
- - enables `SknSettings.env.production?` ...
26
- 1. Since SknSettings is by necessity a global constant, it can serve as Session Storage to keep system objects; like a ROM-RB instance.
27
- 1. In-Memory Key-Store, use it to cache active user objects, or active Integration passwords, and/or objects that are not serializable.
28
- 1. Command registries used to dispatch command requests to proper command handler. see example app [SknBase](https://github.com/skoona/skn_base/blob/master/strategy/services/content/command_handler.rb)
29
- ```ruby
30
- SknSettings.command_handler = {
31
- Commands::RetrieveAvailableResources => method(:resources_metadata_service),
32
- Commands::RetrieveResourceContent => method(:resource_content_service)
33
- }
34
- ...
35
- SknSettings.command_handler[ cmd.class ].call( cmd )
36
- -- or --
37
- SknSettings.command_handler.key?( cmd.class ) && cmd.valid? ?
38
- SknSettings.command_handler[ cmd.class ].call( cmd ) : command_not_found_action()
39
- ```
40
- There are many more use cases for Ruby's Hash that this gem just makes easier to implement.
41
-
42
-
43
- ## Available Classes
44
- * SknSuccess
45
- * SknFailure
6
+ `SknUtils` is a collection of pure-ruby utility classes and modules, with limited
7
+ dependencies, to augment the development of Ruby applications. Examples of these
8
+ utilities in action can be found in my related projects `SknServices`, `SknWebApp`,
9
+ and `SknBase`.
10
+
11
+ * Most classes are standalone modules, or cleary documented, and can be copy/pasted into your project.
12
+ * The exchange or handoff of values between objects is addressed via the `NestedResults`
13
+ class which implements dot-notation and nesting over a concurrent hash: A ruby Hash can
14
+ use any valid ruby object as a key or value.
15
+ * `NestedResults` is later sub-classed as `Configuration` to provide application level
16
+ settings using YAML files with a API simular to the RbConfig gem.
17
+ * Object or method return values can be enclosed in `SknSuccess` or `SknFailure` classes
18
+ to prevent or minimize nil returns.
19
+ * Precise microsecond `duration`s, Number to `as_human_size`, and a `catch_exceptions`
20
+ retry-able feature are implemented on the SknUtils class directly for ease of use.
21
+ * `Configurable` module extends any class or module with configurable attribute method
22
+ as needed, with a set of defaults methods which emulate Rails.env, Rails.logger, and
23
+ Rails.root functionality.
24
+ * `CoreObjectExtensions` simular to ActiveSupport's, `#present?` and `#blank?` are
25
+ automatically applied, unless already present, when SknUtils gem is loaded.
26
+ * `SknRegistry` class is an advanced feature which allows you to manually register
27
+ classes, procs, or any value with a user-defined `label`. Initialization and dependency injection
28
+ requirements of service-like classes can be included in this registration process allowing
29
+ them to be centrally maintained. The `label` can be any valid ruby value; like a
30
+ classname, symbol, or string as needed
31
+ * `NullObject`, `NotifierBase`, and `Wrappable` are interesting classes which you might want to explore further.
32
+ * `ConcurrentJobs` is a feature implemented to allow concurrent/multi-threaded execution of jobs. The included
33
+ companion classes focus on HTTP GET,PUT,POST, and DELETE jobs as an example of how to use the `ConcurrentJobs` feature.
34
+
35
+ All classes and modules have RSpec test coverage (90+) of their originally intended
36
+ use-cases.
37
+
38
+
39
+ ### Available Classes
46
40
  * SknSettings
47
41
  * SknUtils::Configuration
48
42
  * SknUtils::EnvStringHandler
49
- * SknRegistry
50
- * SknContainer
51
43
  * SknHash
52
44
  * SknUtils::ResultBean
53
45
  * SknUtils::PageControls
54
46
  * SknUtils::NestedResult
55
- * SknUtils::NullObject
56
- * SknUtils::CoreObjectExtensions
47
+ * SknRegistry
48
+ * SknContainer
49
+ * SknSuccess
50
+ * SknFailure
57
51
  * SknUtils::Configurable
58
-
59
- ## Available Class.Methods
52
+ * SknUtils::CoreObjectExtensions
53
+ * SknUtils::NullObject
54
+ * SknUtils::NotifierBase
55
+ * SknUtils::Wrappable
56
+ * SknUtils::ConcurrentJobs
57
+ * SknUtils::JobWrapper (via ConcurrentJobs)
58
+ * SknUtils::CommandJSONPost (via JobCommands)
59
+ * SknUtils::CommandFORMPost
60
+ * SknUtils::CommandJSONGet
61
+ * SknUtils::CommandJSONPut
62
+ * SknUtils::CommandFORMDelete
63
+ * SknUtils::HttpProcessor
64
+
65
+ ### Available Class.Methods
60
66
  * SknUtils.catch_exceptions()
61
67
  * SknUtils.as_human_size()
62
68
  * SknUtils.duration(start_time=nil)
63
69
 
64
-
70
+ ### Available RSpec Helpers
71
+ * spec/support/xml_matchers.rb
72
+ * expect(bundle).to have_xpath('//witnesses/witness/role')
73
+ * expect(bundle).to have_nodes('//witnesses/witness/role', 3)
74
+ * expect(bundle).to match_xpath('//lossInformation/date', "2020-01-28")
75
+
65
76
 
66
77
  ## History
78
+ 2/3/2020 V5.7.0
79
+ Added
80
+ * RSpec XML_Matchers to spec/support folders
81
+ * Update ConcurrentJobs JobCommands to support HTTP Headers
82
+
83
+ 2/24/2019 V5.5.0
84
+ Added
85
+ * ConcurrentJobs feature set
86
+ - Executes (HTTP/any) jobs in parallel
87
+
88
+ 1/2/2019 V5.4.1
89
+ Added
90
+ - Wrappable module for evaluation.
91
+ - Ruby comment # frozen_string_literal, everywhere
92
+
67
93
  12/16/2018 V5.4.0
68
94
  Added :duration() utils to SknUtils module:
69
95
  #duration() #=> returns start_time value
@@ -154,27 +180,66 @@ There are many more use cases for Ruby's Hash that this gem just makes easier to
154
180
  06/2015 V1.5.1 commit #67ef656
155
181
  Last Version to depend on Rails (ActiveModel) for #to_json and #to_xml serialization
156
182
 
183
+ ### NestedResult class; dynamic key/value container
184
+ A class implementing a Ruby PORO (Plain Old Ruby Object) that can be instantiated at runtime with a hash. Creates
185
+ a nested object with Dot and Hash notational accessors to each key's value. Additional key/value pairs can be added post-create
186
+ by simply assigning it; `obj.my_new_var = "some value"`
187
+
188
+ * Transforms the initialing hash into accessible object instance values, with their keys as method names.
189
+ * If the key's value is also a hash, it too will become an Object.
190
+ * if the key's value is a Array of Hashes, or Array of Arrays of Hashes, each hash element of the Arrays will become an Object.
191
+ * The current key/value (including nested) pairs are returned via #to_hash or #to_json when and if needed.
192
+ * Best described as dot notation wrapper over a Ruby (Concurrent-Ruby) Hash.
193
+
194
+ Ruby's Hash object is already extremely flexible, even more so with the addition of dot-notation. As I work more with Ruby outside of Rails, I'm finding more use cases for the capabilities of this gem. Here are a few examples:
195
+
196
+ 1. Application settings containers, SknSettings. Loads Yaml file based on `ENV['RACK_ENV']` value, or specified file-key.
197
+ - Replaces Config and/or RBConfig Gems for yaml based settings
198
+ 1. Substitute for Rails.root, via a little ERB/YAML/Marshal statement in settings.yml file, and a helper class
199
+ - settings.yml (YAML)
200
+ - `root: <%= Dir.pwd %>`
201
+ - enables `SknSettings.root`
202
+ - `env: !ruby/string:SknUtils::EnvStringHandler <%= ENV.fetch('RACK_ENV', 'development') %>`
203
+ - enables `SknSettings.env.production?` ...
204
+
205
+ There are many more use cases for Ruby's Hash that this gem just makes easier to implement.
206
+
157
207
 
158
208
  ## Public Components
159
209
  SknUtils::NestedResult # Primary Key/Value Container with Dot/Hash notiation support.
160
- SknHash # Wrapper for name only, WITHOUT SknUtils namespace, inherits from SknUtils::NestedResult
161
- SknUtils::ResultBean # Wrapper for name only, inherits from SknUtils::NestedResult
162
- SknUtils::PageControls # Wrapper for name only, inherits from SknUtils::NestedResult
163
- SknUtils::DottedHash # Wrapper for name only, inherits from SknUtils::NestedResult
210
+ SknHash # Wrapper in name only, WITHOUT SknUtils namespace, inherits from SknUtils::NestedResult
211
+ SknUtils::ResultBean # Wrapper in name only, inherits from SknUtils::NestedResult
212
+ SknUtils::PageControls # Wrapper in name only, inherits from SknUtils::NestedResult
213
+ SknUtils::DottedHash # Wrapper in name only, inherits from SknUtils::NestedResult
164
214
 
165
- SknUtils::Configurable # Basic one-level class configuration Module
215
+ SknSettings # Multi-level application Configuration class, Key/Value Container with Dot/Hash notiation support.
216
+ - Reads YAML files from ./config/ directory based by environment (RACK_ENV)
217
+ - INITIALIZED WHEN GEM LOADS
166
218
 
167
- SknSettings # Multi-level application Configuration class, Key/Value Container with Dot/Hash notiation support.
219
+ SknUtils::Configurable # Add Class writers/getters to any Class, think class configuration
168
220
 
169
- SknContainer/SknRegistry # Basic Key/Value container which #registers and #resolves procs, classes, and/or object
221
+ SknContainer/SknRegistry # Key/Value container which #registers and #resolves procs, classes, and/or object
222
+ - Allows definition in one place, and label references as needed; dependency injection
223
+ - INITIALIZED WHEN GEM LOADS
170
224
 
171
- SknSuccess # Three attribute value containers for return codes -- #value, #message, #success
225
+ SknSuccess # Three attribute value containers for consistant return codes -- #value, #message, #success
172
226
  - Extra #payload method returns value as NestResult if value is_a Hash
173
227
  SknFailure # Three attribute value containers for return codes -- #value, #message, #success
228
+
229
+ SknUtils::ConcurrentJobs # Async/Sync Job executor pool with HTTP support
230
+ SknUtils::CommandJSONGet # HTTP Get Command class expecting `json` return, located inside `job_commands`
231
+ SknUtils::CommandJSONPut # HTTP Put Command class expecting `json` return, located inside `job_commands`
232
+ SknUtils::CommandJSONPost # HTTP Post Command class expecting `json` return, located inside `job_commands`
233
+ SknUtils::CommandFORMPost # HTTP Post Command class expecting `form` data return, located inside `job_commands`
234
+ SknUtils::CommandFORMDelete # HTTP Delete Command class expecting `form` data return, located inside `job_commands`
235
+ SknUtils::HttpProcessor # Command driven HTTP processing object supporting GET,PUT,POST, and DELETE
236
+ SknUtils::JobWrapper # Outer wrapper class to capture catastrophic exceptions (syntax normally)
174
237
 
175
238
 
176
239
  ## Public Methods: SknUtils::Configurable module
177
- For making an arbitrary class configurable and then specifying those configuration values.
240
+ For making an arbitrary class configurable and then specifying those configuration values. Intended to be used at the application
241
+ level, similar to the use of `Rails`, or for classes that would benefit from a configuration value when objects are created from it.
242
+
178
243
  ```ruby
179
244
  # (1) First establish the method names of class values desired.
180
245
  ################
@@ -239,21 +304,27 @@ There are many more use cases for Ruby's Hash that this gem just makes easier to
239
304
  ```
240
305
 
241
306
 
242
- ## Public Methods: SknContainer ONLY
243
- SknContainer is global constant assigned to an instantiated instance of SknRegistry.
244
- Returns the keyed value as the original instance/value or if provided a proc the result of calling that proc.
245
- To register a class or object for global retrieval, use the following API. Also review the RSpecs for additional useage info.
307
+ ## Public Methods: SknContainer and/or SknRegistry class
308
+ `SknContainer` is global constant assigned to an instantiated instance of `SknRegistry`. `SknRegistry` can
309
+ be instantiated in the regular way via `SknRegistry.new`; and is included in the SknConfigurable root options
310
+ by default under the key `registry`.
311
+
312
+ Either returns the labeled value as the original instance/value or if provided with a proc, the result of calling that proc.
313
+ To register, and `label`, a class or object for retrieval, use the following API. Also review the RSpecs for
314
+ additional useage info.
246
315
 
247
316
  #register(key, contents = nil, options = {})
248
317
  - example:
249
318
  SknContainer.register(:some_klass, MyClass) -- class as value
250
319
  SknContainer.register(:the_instance, MyClass.new) -- Object Instance as value
251
- SknContainer.register(:unique_instance, -> {MyClass.new}) -- New Object Instance for each #resolve
320
+ SknContainer.register(:unique_instance, -> {MyClass.new}, call: true) -- New Object Instance for each #resolve
321
+ SknContainer.register(:unique_instance2, ->(parms) {MyClass.new(parms)}, call: false) -- New Object with parms for each #resolve
322
+ SknContainer.register(:some_proc, -> {MyClass.new}, call: false) -- Return uncalled proc for each #resolve
252
323
 
253
324
  SknContainer -- #register returns self to enable chaining
254
325
  .register(:unique_instance, -> {MyClass.new})
255
- .register(:the_instance, MyClass.new)
256
- .register(:some_klass, MyClass)
326
+ .register(:the_instance, MyClass.new)
327
+ .register(:some_klass, MyClass)
257
328
 
258
329
  #resolve(key)
259
330
  - example:
@@ -261,15 +332,84 @@ There are many more use cases for Ruby's Hash that this gem just makes easier to
261
332
  instance = SknContainer.resolve(:some_klass).new
262
333
 
263
334
  obj_instance1 = SknContainer.resolve(:unique_instance)
264
- obj_instance2 = SknContainer.resolve(:unique_instance)
335
+ obj_instance2 = SknContainer.resolve(:unique_instance2).call(parms)
265
336
 
266
337
  same_instance = SknContainer.resolve(:the_instance)
338
+
339
+ some_proc = SknContainer.resolve(:some_proc).call
340
+
341
+ * Testing Support:
342
+ - #substitute(...) allows you to mock an existing entry. #substitute is an alias for #register_mock
343
+ - SknContainer.substitute(:the_instance, MyClass.new)
344
+ - #restore! clears all mocked entries. #restore! is an alias for #unregister_mock!
345
+ - SknContainer.restore!
346
+
347
+
348
+ ## Public Methods: SknUtils::ConcurrentJobs classes
349
+ `ConcurrentJobs` behaves as a concurrent thread pool by using Concurrent::Promise from the `concurrent-ruby` gem.
350
+ Enables the definition of Procs, or any callable class, which will be executed in parrallel with the available jobs
351
+ loaded into ConcurrentJobs. Meant to reduce user-sensitive response times when multiple APIs must be invoked.
352
+ Also review the RSpecs for additional useage info.
353
+
354
+ SknUtils::ConcurrentJobs
355
+ #call(async: true) - Instantiate ConcurrentJobs with Async Workers, false for Sync Workers
356
+ #register_jobs(cmds, callable) - Array of Command to be executed by single callable
357
+ #register_job(&block) - Adds callable block to internal worker queue
358
+ #render_jobs - Collect results from all jobs into a Result object
359
+ #elapsed_time_string - "0.012 seconds" string showing duration of last #render_jobs call
360
+
361
+ SknUtils::Result - Contains individual results from each job executed
362
+ #success? - Determines if any job failed
363
+ #messages - Retrieves messages from job results, assumed present when job fails
364
+ #values - Returns an array of individual results from job executions
365
+
366
+ Commands and HttpProcessors are included to demonstrate Job creating patterns. ConcurrentJobs is not restricted
367
+ to Http calls or the command to command handler pattern. Using the #register_job method you can pass callable BLOCK
368
+ and it will be executed when #render_jobs is invoked. HttpProcessor is what I needed and triggered me to add this feature.
369
+
370
+ Example here:
371
+
372
+ ```ruby
373
+ begin
374
+ # CommandJSONPost, CommandFORMGet, CommandJSONGet,
375
+ # CommandJSONPut, CommandFORMDelete
376
+ commands = [
377
+ SknUtils::CommandJSONGet.call(full_url: "http://jsonplaceholder.typicode.com/posts"),
378
+ SknUtils::CommandJSONGet.call(full_url: "https://jsonplaceholder.typicode.com/comments"),
379
+ SknUtils::CommandJSONGet.call(full_url: "https://jsonplaceholder.typicode.com/todos/1"),
380
+ SknUtils::CommandJSONGet.call(full_url: "http://jsonplaceholder.typicode.com/users")
381
+ ]
382
+
383
+ # Initialize the queue with Async Workers by default
384
+ provider = SknUtils::ConcurrentJobs.call
385
+
386
+ # Populate WorkQueue
387
+ provider.register_jobs(commands, SknUtils::HttpProcessor) # mis-spelling these params result in an immediate exception (line 43 below)
388
+
389
+ # Execute WorkQueue
390
+ result = provider.render_jobs
391
+
392
+ if result.success?
393
+ puts "Success: true"
394
+ puts "Values: #{result.values}"
395
+ puts "Messages: #{result.messages}"
396
+ else
397
+ puts "Success: false - errors: #{result.messages.join(', ')}"
398
+ puts "Values: #{result.values}"
399
+ end
267
400
 
401
+ # result.values
402
+ rescue => e
403
+ $stderr.puts e.message, e.backtrace
404
+ end
268
405
 
406
+ ```
407
+
408
+
409
+ ## Public Methods: SknSettings class
410
+ SknSettings is a global constant containing an initialized Object of SknUtils::Configuration using defaults.
411
+ To change the 'development'.yml default please use the following method early or in the case of Rails in 'application.rb
269
412
 
270
- ## Public Methods: SknSettings ONLY
271
- SknSettings is global constant containing an initialized Object of SknUtils::Configuration using defaults
272
- To change the 'development'.yml default please use the following method early or in the case of Rails in 'application.rb
273
413
  #load_config_basename!(config_name) -- Where config_name is the name of yml files stored in the `./config/settings` directory
274
414
  #config_path!(path) -- Where path format is './<dirs>/', default is: './config/'
275
415
  and contains a settings.yml file and a 'path/settings/' directory
@@ -302,9 +442,15 @@ There are many more use cases for Ruby's Hash that this gem just makes easier to
302
442
  #prepend_source!(file_path_or_hash) -- self, adds yaml_file or hash to start of filelist (:reload! required)
303
443
  -------------------------------------------------
304
444
 
445
+ Usage
446
+ -------------------------------------------------
447
+ Dot notation of yaml file contents
448
+ SknSettings.version # => version's value
449
+ -------------------------------------------------
305
450
 
306
451
  ## Public Methods: SknUtils::NestedResult, SknHash & SknSettings
307
- Each concrete Class supports the following utility methods:
452
+ Each concrete Class supports the following utility methods:
453
+
308
454
  #to_hash -- returns a hash of current key/value pairs, including nested
309
455
  #to_json -- returns a json string of current key/value pairs, including nested
310
456
  #hash_from(:base_key) -- exports the internal hash starting with this base level key
@@ -324,6 +470,7 @@ There are many more use cases for Ruby's Hash that this gem just makes easier to
324
470
 
325
471
 
326
472
  ## NestedResult Basic features include:
473
+
327
474
  ```ruby
328
475
  - provides the hash or dot notation methods of accessing values:
329
476
 
@@ -365,6 +512,7 @@ There are many more use cases for Ruby's Hash that this gem just makes easier to
365
512
 
366
513
  * The NestedResult produces these effects when given a params hash;
367
514
  * Follow VALUES that are Hashes, Arrays of Hashes, and Arrays of Arrays of Hashes
515
+
368
516
  ```ruby
369
517
  drb = SknUtils::NestedResult.new(params) Basic dot notation:
370
518
  ---------------------------------------------------- -----------------------------------------------------------------
@@ -389,6 +537,7 @@ There are many more use cases for Ruby's Hash that this gem just makes easier to
389
537
  ```
390
538
 
391
539
  * Expected usage
540
+
392
541
  ```ruby
393
542
  result = SknUtils::NestedResult.new({
394
543
  success: true,
@@ -404,6 +553,7 @@ There are many more use cases for Ruby's Hash that this gem just makes easier to
404
553
 
405
554
 
406
555
  * Wrap additional methods around the core NestedResult feature set
556
+
407
557
  ```ruby
408
558
  class MyPackage < SknUtils::NestedResult
409
559
  def initialize(params={})
@@ -420,10 +570,11 @@ There are many more use cases for Ruby's Hash that this gem just makes easier to
420
570
  ## Installation
421
571
 
422
572
  runtime prereqs:
423
- * V4+ None
424
- * V3+ None
425
- * V2+ None
426
- * V1+ gem 'active_model', '~> 3.0'
573
+ * V5+ None
574
+ * V4+ None
575
+ * V3+ None
576
+ * V2+ None
577
+ * V1+ gem 'active_model', '~> 3.0'
427
578
 
428
579
 
429
580
  Add this line to your application's Gemfile:
@@ -1,9 +1,10 @@
1
1
  title: SknUtils
2
2
  email: skoona@gmail.com
3
3
  description: > # this means to ignore newlines until "baseurl:"
4
- Ruby GEM containing utilitarian classes to help build Ruby applications. SknUtils::NestedResult is the primary class. It is
5
- a threadsafe wrapper over Ruby's Hash with dot.notation, ?.presence, and nested deep-merge features added. I use it for application
6
- settings via YAML files, and as a container for persistent objects.
4
+ Collection of pure-ruby utility classes and modules, with limited
5
+ dependencies, to augment the development of Ruby applications. Value containers supporting nested dot.notation access
6
+ over hashes, and utilities offering dependency injection/lookup, and language extensions support running in a non-rails
7
+ environment. Plus, examples of null objects, class customization, and concurrent processing.
7
8
  baseurl: ""
8
9
  url: https://skoona.github.io/SknServices
9
10
 
@@ -21,4 +22,3 @@ github:
21
22
  author:
22
23
  name: "James Scott, Jr. (a.k.a Skoona)"
23
24
  url: https://keybase.io/skoona
24
-
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # file: concurrent_test_block
4
+ #
5
+
6
+ require 'bundler/setup'
7
+ require 'skn_utils'
8
+
9
+
10
+ # ##
11
+ # MainLine
12
+ # ##
13
+ #
14
+ begin
15
+ # CommandJSONPost, CommandFORMGet, CommandJSONGet,
16
+ # CommandJSONPut, CommandFORMDelete
17
+ commands = [
18
+ SknUtils::CommandJSONGet.call(full_url: "http://jsonplaceholder.typicode.com/posts"),
19
+ SknUtils::CommandJSONGet.call(full_url: "https://jsonplaceholder.typicode.com/comments"),
20
+ SknUtils::CommandJSONGet.call(full_url: "https://jsonplaceholder.typicode.com/todos/1"),
21
+ SknUtils::CommandJSONGet.call(full_url: "http://jsonplaceholder.typicode.com/users")
22
+ ]
23
+
24
+ # Initialize the queue with Async Workers by default
25
+ provider = SknUtils::ConcurrentJobs.call
26
+
27
+ # Populate WorkQueue
28
+ commands.each do |command|
29
+ provider.register_job do
30
+ begin
31
+ SknUtils::HttpProcessor.call(command) # mis-spelling these params result in [SknFailure, SknFailure, ...] results
32
+ rescue => ex
33
+ $stderr.puts ex
34
+ SknFailure.(ex.class.name, "#{ex.message}; #{ex.backtrace[0]}")
35
+ end
36
+ end
37
+ end
38
+
39
+ # Execute WorkQueue
40
+ result = provider.render_jobs
41
+
42
+ if result.success?
43
+ puts "Success: true"
44
+ puts "Values: #{result.values}"
45
+ puts "Messages: #{result.messages}"
46
+ else
47
+ puts "Success: false - errors: #{result.messages.join(', ')}"
48
+ puts "Values: #{result.values}"
49
+ end
50
+
51
+ # result.values
52
+ rescue => e
53
+ $stderr.puts e.message, e.backtrace
54
+ end