thomas_utils 0.1.13.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 681af6043ae2f6638036ba67523a2b01687ae758
4
+ data.tar.gz: 6e0d5f0910cbf715d8857a69e9acd4386ca937af
5
+ SHA512:
6
+ metadata.gz: 9e05ff0e99623ecb608285132fef52fb8271dd4a9df03c593122aed37e0a08c5c4aaac18d30a3f9e1ee177fd159d5ceb4699070bf8497c14d874d8f99944b65d
7
+ data.tar.gz: a792c556f3d4716551e35f89e49ad66c373ed0d8d2db03f24ecaab58c8b77d64cb2de3bdedf04d32583bce33995703f099d1b2f27c8d18908c99307460704980
@@ -0,0 +1,13 @@
1
+ Copyright 2015 Thomas RM Rogers
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
@@ -0,0 +1,15 @@
1
+ # Thomas Utils
2
+
3
+ Thomas Utils is a gem to provide some basic helper classes to be used with my other projects.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'thomas_utils', git: 'https://github.com/thomasrogers03/thomas_utils.git'
10
+
11
+ ## Current Features
12
+
13
+ * FutureWrapper: Apply some additional logic to your futures before returning a value. Supports futures implementing #join and #get.
14
+ * ObjectStream: Incrementally write object values to a stream, flushing them in groups to a provided block.
15
+ * PeriodicFlusher: To be used with ObjectStream; periodically calls #flush on the buffer, running the block on regular intervals.
@@ -0,0 +1,25 @@
1
+ #--
2
+ # Copyright 2015 Thomas RM Rogers
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #++
16
+
17
+ require 'concurrent'
18
+
19
+ require 'thomas_utils/object_stream'
20
+ require 'thomas_utils/periodic_flusher'
21
+ require 'thomas_utils/future_wrapper'
22
+ require 'thomas_utils/multi_future_wrapper'
23
+ require 'thomas_utils/key_comparer'
24
+ require 'thomas_utils/key_indexer'
25
+ require 'thomas_utils/future'
@@ -0,0 +1,42 @@
1
+ module ThomasUtils
2
+ class Future
3
+ DEFAULT_EXECUTOR = ::Concurrent::CachedThreadPool.new
4
+
5
+ def initialize(options = {})
6
+ options[:executor] ||= DEFAULT_EXECUTOR
7
+
8
+ @mutex = Mutex.new
9
+ @future = ::Concurrent::Future.execute(executor: options[:executor]) do
10
+ begin
11
+ @result = yield
12
+ @result = @result.get if @result.is_a?(FutureWrapper)
13
+ @mutex.synchronize { @success_callback.call(@result) if @success_callback }
14
+ @result
15
+ rescue => e
16
+ @error = e
17
+ @mutex.synchronize { @failure_callback.call(e) if @failure_callback }
18
+ end
19
+ end
20
+ end
21
+
22
+ def get
23
+ result = @future.value
24
+ raise @error if @error
25
+ result
26
+ end
27
+
28
+ def join
29
+ get rescue nil
30
+ end
31
+
32
+ def on_success(&block)
33
+ @mutex.synchronize { @success_callback = block }
34
+ @success_callback.call(@result) if @future.fulfilled? && !@error
35
+ end
36
+
37
+ def on_failure(&block)
38
+ @mutex.synchronize { @failure_callback = block }
39
+ @failure_callback.call(@error) if @future.fulfilled? && @error
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,21 @@
1
+ module ThomasUtils
2
+ class FutureWrapper
3
+ extend Forwardable
4
+
5
+ def_delegator :@future, :join
6
+ def_delegator :@future, :on_failure
7
+
8
+ def initialize(future, &callback)
9
+ @future = future
10
+ @callback = callback
11
+ end
12
+
13
+ def get
14
+ @result ||= @callback.call(@future.get)
15
+ end
16
+
17
+ def on_success
18
+ @future.on_success { |result| yield @callback.call(result) }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,50 @@
1
+ module ThomasUtils
2
+ class KeyComparer
3
+ OPERATOR_MAP = {eq: '=', ge: '>=', gt: '>', le: '<=', lt: '<', ne: '!='}
4
+
5
+ attr_reader :key
6
+
7
+ def initialize(key, comparer)
8
+ @key = key
9
+ @comparer = comparer
10
+ end
11
+
12
+ def new_key(updated_key)
13
+ KeyComparer.new(updated_key, @comparer)
14
+ end
15
+
16
+ def to_s
17
+ "#{pretty_key} #{@comparer}"
18
+ end
19
+
20
+ def ==(rhs)
21
+ to_s == rhs.to_s
22
+ end
23
+
24
+ def eql?(rhs)
25
+ self == rhs
26
+ end
27
+
28
+ def hash
29
+ to_s.hash
30
+ end
31
+
32
+ private
33
+
34
+ def pretty_key
35
+ key.is_a?(Array) ? "(#{key * ','})" : key
36
+ end
37
+ end
38
+ end
39
+
40
+ class Symbol
41
+ ThomasUtils::KeyComparer::OPERATOR_MAP.each do |method, operator|
42
+ define_method(method) { ThomasUtils::KeyComparer.new(self, operator) }
43
+ end
44
+ end
45
+
46
+ class Array
47
+ ThomasUtils::KeyComparer::OPERATOR_MAP.each do |method, operator|
48
+ define_method(method) { ThomasUtils::KeyComparer.new(self, operator) }
49
+ end
50
+ end
@@ -0,0 +1,20 @@
1
+ module ThomasUtils
2
+ class KeyIndexer
3
+ attr_reader :key
4
+
5
+ def initialize(key, index)
6
+ @key = key
7
+ @index = index
8
+ end
9
+
10
+ def to_s
11
+ "#{@key}['#{@index}']"
12
+ end
13
+ end
14
+ end
15
+
16
+ class Symbol
17
+ def index(index)
18
+ ThomasUtils::KeyIndexer.new(self, index)
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ module ThomasUtils
2
+ class MultiFutureWrapper
3
+ def initialize(futures, leader = nil, &callback)
4
+ @futures = futures
5
+ @leader = leader
6
+ @callback = callback
7
+ end
8
+
9
+ def join
10
+ @futures.map(&:join)
11
+ end
12
+
13
+ def get
14
+ @futures.map(&:get).map(&@callback)
15
+ end
16
+
17
+ def on_failure(&block)
18
+ if @leader
19
+ @leader.on_failure(&block)
20
+ else
21
+ @futures.each { |future| future.on_failure(&block) }
22
+ end
23
+ end
24
+
25
+ def on_success
26
+ if @leader
27
+ @leader.on_success { |result| yield @callback.call(result) }
28
+ else
29
+ @futures.each { |future| future.on_success { |result| yield @callback.call(result) } }
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ module ThomasUtils
2
+ class ObjectStream
3
+
4
+ def initialize(&callback)
5
+ @buffer = Queue.new
6
+ @callback = callback
7
+ end
8
+
9
+ def <<(item)
10
+ @buffer << item
11
+ end
12
+
13
+ def flush
14
+ length = @buffer.size
15
+ items = length.times.map { @buffer.pop }
16
+ @callback.call(items)
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ module ThomasUtils
2
+ class PeriodicFlusher
3
+ @@streams = {}
4
+
5
+ def self.<<(stream_desc)
6
+ name = stream_desc[:name]
7
+ unless @@streams[name]
8
+ stream = stream_desc[:stream]
9
+ @@streams[name] = stream
10
+ Workers::PeriodicTimer.new(stream_desc[:timeout] || 1) { stream.flush }
11
+ end
12
+ end
13
+
14
+ def self.[](name)
15
+ @@streams[name]
16
+ end
17
+ end
18
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: thomas_utils
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.13.2
5
+ platform: ruby
6
+ authors:
7
+ - Thomas RM Rogers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: concurrent-ruby
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '0.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '0.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: workers
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '0.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '0.3'
41
+ description: |-
42
+ Helper utilities gem used in a number of my projects.
43
+ Includes future wrappers and provides some override methods for Ruby core classes
44
+ that make defining behaviours easier to code.
45
+ email: thomasrogers03@gmail.com
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - LICENSE.txt
51
+ - README.md
52
+ - lib/thomas_utils.rb
53
+ - lib/thomas_utils/future.rb
54
+ - lib/thomas_utils/future_wrapper.rb
55
+ - lib/thomas_utils/key_comparer.rb
56
+ - lib/thomas_utils/key_indexer.rb
57
+ - lib/thomas_utils/multi_future_wrapper.rb
58
+ - lib/thomas_utils/object_stream.rb
59
+ - lib/thomas_utils/periodic_flusher.rb
60
+ homepage: https://www.github.com/thomasrogers03/thomas_utils
61
+ licenses:
62
+ - Apache License 2.0
63
+ metadata: {}
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - '>='
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubyforge_project:
80
+ rubygems_version: 2.4.8
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: Helper utilities gem used in a number of my projects
84
+ test_files: []