module Garcon
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Resource
validations.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Include hooks to extend Resource
with class and instance methods.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com>
Copyright © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com>
Copyright © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com>
Copyright © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com>
Copyright © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
No not that kind! callback hooks.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Author: Stefano Harding <riddopic@gmail.com> License: Apache License, Version
2.0 Copyright: © 2014-2015 Stefano Harding
Licensed under the Apache License, Version
2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
The version number of the Garcon
Gem
@return [String]
@api public
Constants
- GLOBAL_MONOTONIC_CLOCK
Clock that cannot be set and represents monotonic time since some unspecified starting point. @!visibility private
- VERSION
Public Class Methods
Write to a file atomically. Useful for situations where you don’t want other processes or threads to see half-written files.
@param [String] file
fill path of the file to write to
@param [String] secret
content to write to file
@api private
# File lib/garcon/secret.rb, line 216 def self.atomic_write(file, secret, tmp_dir = Dir.tmpdir) tmp_file = Tempfile.new(File.basename(file), tmp_dir) tmp_file.write(secret) tmp_file.close FileUtils.mv(tmp_file.path, file) begin File.chmod(00400, file) rescue Errno::EPERM, Errno::EACCES # Changing file ownership/permissions failed end ensure tmp_file.close tmp_file.unlink end
@return [Boolean]
true when *all* thread pools will auto-terminate on application exit using an `at_exit` handler; false when no auto-termination will occur.
# File lib/garcon.rb, line 195 def self.auto_terminate_all_executors? Garcon.config.auto_terminate_all_executors.value end
@return [Boolean]
true when global thread pools will auto-terminate on application exit using an `at_exit` handler; false when no auto-termination will occur.
# File lib/garcon.rb, line 178 def self.auto_terminate_global_executors? Garcon.config.auto_terminate_global_executors.value end
# File lib/garcon/chef/coerce/coercer.rb, line 21 def self.coercer return @coercer if @coercer @coercer = Garcon::Coercer.new Garcon::Coercions.bind_to(@coercer) @coercer end
# File lib/garcon/chef/coerce/coercer.rb, line 28 def self.coercer=(coercer) @coercer = coercer end
Provides access to the global Garcon
configuration
@example
Garcon.config do |config| config.blender = true end
@return [Configuration]
@api public
# File lib/garcon.rb, line 151 def self.config(&block) yield configuration if block_given? configuration end
Global configuration instance.
@return [Configuration]
@api private
# File lib/garcon.rb, line 161 def self.configuration @configuration ||= Configuration.new end
Sets the global Crypto
configuration.
@example
Garcon.config do |c| c.crypto.password = "!mWh0!s@y!m" c.crypto.salt = "9e5f851900cad8892ac8b737b7370cbe" end
@return [Garcon::Crypto]
@api public
# File lib/garcon.rb, line 86 def self.crypto(&block) configuration.crypto(&block) end
Sets the global Crypto
configuration value.
@param [Boolean] value
@return [Garcon::Crypto]
@api public
# File lib/garcon.rb, line 97 def self.crypto=(value) configuration.crypto = value self end
Delete the secrets file
@return [undefined]
@api private
# File lib/garcon/secret.rb, line 194 def self.delete(file = nil) Garcon.secret.lock.synchronize do if file.nil? until Garcon.secret.queue.length == 0 tmpfile = Garcon.secret.queue.pop File.unlink(tmpfile) if File.exist?(tmpfile) end else File.unlink(file) if File.exist?(file) end end end
Defines if ALL executors should be auto-terminated with an ‘at_exit` callback. When set to `false` it will be the application programmer’s responsibility to ensure that all thread pools, including the global thread pools, are shutdown properly prior to application exit.
# File lib/garcon.rb, line 187 def self.disable_auto_termination_of_all_executors! Garcon.config.auto_terminate_all_executors.make_false end
Defines if global executors should be auto-terminated with an ‘at_exit` callback. When set to `false` it will be the application programmer’s responsibility to ensure that the global thread pools are shutdown properly prior to application exit.
# File lib/garcon.rb, line 170 def self.disable_auto_termination_of_global_executors! Garcon.config.auto_terminate_global_executors.make_false end
Global thread pool optimized for short, fast operations.
@return [ThreadPoolExecutor] the thread pool
# File lib/garcon.rb, line 202 def self.global_fast_executor Garcon.config.global_fast_executor.value end
Global thread pool optimized for long, blocking (IO) tasks.
@return [ThreadPoolExecutor] the thread pool
# File lib/garcon.rb, line 209 def self.global_io_executor Garcon.config.global_io_executor.value end
Global thread pool user for global timers.
@return [Garcon::TimerSet] the thread pool
@see Garcon::timer
# File lib/garcon.rb, line 218 def self.global_timer_set Garcon.config.global_timer_set.value end
# File lib/garcon.rb, line 228 def self.kill_global_executors global_fast_executor.kill global_io_executor.kill global_timer_set.kill end
Lock a file for a block so only one process can modify it at a time
@param [String] file
fill path of the file to lock
@yield [Block]
invokes the block
@yieldreturn [Object]
the result of evaluating the optional block
@api private
# File lib/garcon/secret.rb, line 244 def self.lock_file(file, &block) if File.exist?(file) File.open(file, 'r+') do |f| begin f.flock File::LOCK_EX yield ensure f.flock File::LOCK_UN end end else yield end end
@!macro [attach] monotonic_get_time
Returns the current time a tracked by the application monotonic clock. @return [Float] The current monotonic time when `since` not given else the elapsed monotonic time between `since` and the current time @!macro monotonic_clock_warning
# File lib/garcon/task/monotonic_time.rb, line 65 def monotonic_time GLOBAL_MONOTONIC_CLOCK.get_time end
# File lib/garcon.rb, line 242 def self.new_fast_executor(opts = {}) FixedThreadPool.new( [2, Garcon.processor_count].max, stop_on_exit: opts.fetch(:stop_on_exit, true), idletime: 60, # 1 minute max_queue: 0, # unlimited fallback_policy: :caller_runs # shouldn't matter -- 0 max queue ) end
# File lib/garcon.rb, line 252 def self.new_io_executor(opts = {}) ThreadPoolExecutor.new( min_threads: [2, Garcon.processor_count].max, max_threads: ThreadPoolExecutor::DEFAULT_MAX_POOL_SIZE, stop_on_exit: opts.fetch(:stop_on_exit, true), idletime: 60, # 1 minute max_queue: 0, # unlimited fallback_policy: :caller_runs # shouldn't matter -- 0 max queue ) end
@return [String] random_seed
@api private
# File lib/garcon/secret.rb, line 267 def self.random_seed SecureRandom.random_number(0x100000000).to_s(36) end
Sets the global Secret
configuration.
@return [Garcon::Secret]
@api public
# File lib/garcon.rb, line 116 def self.secret(&block) configuration.secret(&block) end
Sets the global Secret
configuration value.
@param [Boolean] value
@return [Garcon::Secret]
@api public
# File lib/garcon.rb, line 127 def self.secret=(value) configuration.secret = value self end
# File lib/garcon.rb, line 222 def self.shutdown_global_executors global_fast_executor.shutdown global_io_executor.shutdown global_timer_set.shutdown end
Perform the given operation asynchronously after the given number of seconds.
@param [Fixnum] seconds
The interval in seconds to wait before executing the task
@yield the task to execute
@return [Boolean] true
# File lib/garcon/task/timer.rb, line 34 def timer(seconds, *args, &block) raise ArgumentError, 'no block given' unless block_given? if seconds < 0 raise ArgumentError, 'interval must be greater than or equal to zero' end Garcon.global_timer_set.post(seconds, *args, &block) true end
@return [String] tmp_file @api private
# File lib/garcon/secret.rb, line 261 def self.tmpfile(tmp_dir = Dir.tmpdir) Tempfile.new(random_seed, tmp_dir).path.freeze end
# File lib/garcon.rb, line 234 def self.wait_for_global_executors_termination(timeout = nil) latch = CountDownLatch.new(3) [ global_fast_executor, global_io_executor, global_timer_set ].each do |ex| Thread.new { ex.wait_for_termination(timeout); latch.count_down } end latch.wait(timeout) end
@api private
# File lib/garcon.rb, line 282 def self.warn(msg) Kernel.warn(msg) end
Write the secrets file
@return [String]
the path to the file
@api private
# File lib/garcon/secret.rb, line 179 def self.write(key, file) Garcon.secret.lock.synchronize do begin atomic_write(file, get(key)) unless valid?(key, file) ensure File.chmod(00400, file) end end end
Private Class Methods
Extends an object with garcon extensions, called when module is extended, extends the object with class and instance methods.
@param [Object] object
The object including Garcon.
@return [self]
@api private
# File lib/garcon.rb, line 70 def self.extended(object) object.extend(Extensions) end
Extends base class or a module with garcon methods, called when module is included, extends the object with class and instance methods.
@param [Object] object
The object including Garcon
@return [self]
@api private
# File lib/garcon.rb, line 51 def self.included(object) super if Class === object object.send(:include, ClassInclusions) else object.extend(ModuleExtensions) end end
Public Instance Methods
@!visibility private
# File lib/garcon/task/single_thread_executor.rb, line 66 def alive? @thread && @thread.alive? end
@!visibility private
# File lib/garcon/task/dereferenceable.rb, line 135 def apply_deref_options(value) return nil if value.nil? return value if @nothing_on_deref value = @copy_on_deref.call(value) if @copy_on_deref value = value.dup if @dup_on_deref value = value.freeze if @freeze_on_deref value end
# File lib/garcon/utility/memstash.rb, line 352 def check_expired(time) @monitor.synchronize do if (@operations += 1) % @interval == 0 while (key_value_pair = @expires_at.first) && (entry = key_value_pair.first).expires_at <= time key = @expires_at.delete(entry) @stash.delete(key) end end end end
# File lib/garcon/task/copy_on_write_observer_set.rb, line 144 def clear_observers_and_return_old @mutex.lock old_observers = @observers @observers = {} old_observers ensure @mutex.unlock end
# File lib/garcon/task/processor_count.rb, line 86 def compute_physical_count ppc = case RbConfig::CONFIG["target_os"] when /darwin1/ IO.popen("/usr/sbin/sysctl -n hw.physicalcpu").read.to_i when /linux/ cores = {} # unique physical ID / core ID combinations phy = 0 IO.read("/proc/cpuinfo").scan(/^physical id.*|^core id.*/) do |ln| if ln.start_with?("physical") phy = ln[/\d+/] elsif ln.start_with?("core") cid = phy + ":" + ln[/\d+/] cores[cid] = true if not cores[cid] end end cores.count when /mswin|mingw/ require 'win32ole' result_set = WIN32OLE.connect("winmgmts://").ExecQuery( "select NumberOfCores from Win32_Processor") result_set.to_enum.collect(&:NumberOfCores).reduce(:+) else processor_count end # fall back to logical count if physical info is invalid ppc > 0 ? ppc : processor_count rescue return 1 end
# File lib/garcon/utility/hookers.rb, line 128 def continue_execution?(result) @options[:halts_on_falsey] ? result : true end
# File lib/garcon/task/executor.rb, line 101 def create_at_exit_handler!(this) at_exit do this.kill if Garcon.auto_terminate_all_executors? end end
# File lib/garcon/task/executor.rb, line 92 def create_mri_at_exit_handler!(id) at_exit do if Garcon.auto_terminate_all_executors? this = ObjectSpace._id2ref(id) this.kill if this end end end
Create a single worker thread to be added to the pool.
@return [Thread] the new thread.
@!visibility private
# File lib/garcon/task/thread_pool/executor.rb, line 284 def create_worker_thread wrkr = ThreadPoolWorker.new(@queue, self) Thread.new(wrkr, self) do |worker, parent| Thread.current.abort_on_exception = false worker.run parent.on_worker_exit(worker) end return wrkr end
Reclaim all threads in the pool.
@!visibility private
# File lib/garcon/task/thread_pool/executor.rb, line 274 def drain_pool @pool.each { |worker| worker.kill } @pool.clear end
# File lib/garcon/task/copy_on_notify_observer_set.rb, line 136 def duplicate_observers @mutex.lock observers = @observers.dup @mutex.unlock observers end
Check the thread pool configuration and determine if the pool has enought capacity to handle the request. Will grow the size of the pool if necessary.
@return [Boolean] true if the pool has enough capacity else false
@!visibility private
# File lib/garcon/task/thread_pool/executor.rb, line 225 def ensure_capacity? additional = 0 capacity = true if @pool.size < @min_length additional = @min_length - @pool.size elsif @queue.empty? && @queue.num_waiting >= 1 additional = 0 elsif @pool.size == 0 && @min_length == 0 additional = 1 elsif @pool.size < @max_length || @max_length == 0 additional = 1 elsif @max_queue == 0 || @queue.size < @max_queue additional = 0 else capacity = false end additional.times do @pool << create_worker_thread end if additional > 0 @largest_length = [@largest_length, @pool.length].max end capacity end
@!visibility private
# File lib/garcon/task/obligation.rb, line 192 def event @event end
@!visibility private
# File lib/garcon/task/timer_task.rb, line 353 def execute_task(completion) return unless @running.true? Garcon::timer(execution_interval, completion, &method(:timeout_task)) _success, value, reason = @executor.execute(self) if completion.try? self.value = value schedule_next_task time = Time.now observers.notify_observers do [time, self.value, reason] end end end
# File lib/garcon/utility/memstash.rb, line 305 def get(key) @monitor.synchronize do time = Time.now.to_f check_expired(time) found = true entry = @stash.delete(key) { found = false } if found if entry.expires_at <= time @expires_at.delete(entry) return false, nil else @stash[key] = entry return true, entry.value end else return false, nil end end end
executes the block within mutex if current state is included in expected_states
@return block value if executed, false otherwise
@!visibility private
# File lib/garcon/task/obligation.rb, line 243 def if_state(*expected_states) mutex.lock raise ArgumentError, 'no block given' unless block_given? if expected_states.include? @state yield else false end ensure mutex.unlock end
Initializes the internal ‘Mutex`.
@note
This method *must* be called from within the constructor of the including class.
@see mutex
# File lib/garcon/task/dereferenceable.rb, line 102 def init_mutex @mutex = Mutex.new end
@!visibility private
# File lib/garcon/task/obligation.rb, line 186 def init_obligation init_mutex @event = Event.new end
@return [String] object inspection @api public
# File lib/garcon.rb, line 265 def inspect instance_variables.inject([ "\n#<#{self.class}:0x#{object_id.to_s(16)}>", "\tInstance variables:" ]) do |result, item| result << "\t\t#{item} = #{instance_variable_get(item)}" result end.join("\n") end
@!visibility private
# File lib/garcon/task/single_thread_executor.rb, line 60 def kill_execution @queue.clear @thread.kill if alive? end
@!visibility private
# File lib/garcon/task/read_write_lock.rb, line 295 def max_readers?(c = @counter.value) (c & MAX_READERS) == MAX_READERS end
@!visibility private
# File lib/garcon/task/read_write_lock.rb, line 300 def max_writers?(c = @counter.value) (c & MAX_WRITERS) == MAX_WRITERS end
A mutex lock used for synchronizing thread-safe operations. Methods defined by ‘Dereferenceable` are synchronized using the `Mutex` returned from this method. Operations performed by the including class that operate on the `@value` instance variable should be locked with this `Mutex`.
@return [Mutex]
the synchronization object
# File lib/garcon/task/dereferenceable.rb, line 91 def mutex @mutex end
@!visibility private
# File lib/garcon/task/single_thread_executor.rb, line 76 def new_worker_thread Thread.new do Thread.current.abort_on_exception = false work end end
# File lib/garcon/task/copy_on_notify_observer_set.rb, line 144 def notify_to(observers, *args) if block_given? && !args.empty? raise ArgumentError.new 'cannot give arguments and a block' end observers.each do |observer, function| args = yield if block_given? observer.send(function, *args) end end
# File lib/garcon/task/copy_on_write_observer_set.rb, line 130 def observers @mutex.lock @observers ensure @mutex.unlock end
# File lib/garcon/task/copy_on_write_observer_set.rb, line 137 def observers=(new_set) @mutex.lock @observers = new_set ensure @mutex.unlock end
Are the items at the given indexes ordered based on the priority order specified at construction?
@param [Integer] x
The first index from which to retrieve a comparable value.
@param [Integer] y
The second index from which to retrieve a comparable value.
@return [Boolean]
True if the two elements are in the correct priority order else false.
@!visibility private
# File lib/garcon/task/priority_queue.rb, line 200 def ordered?(x, y) (@queue[x] <=> @queue[y]) == @comparator end
Scan all threads in the pool and reclaim any that are dead or have been idle too long. Will check the last time the pool was pruned and only run if the configured garbage collection interval has passed.
@!visibility private
# File lib/garcon/task/thread_pool/executor.rb, line 260 def prune_pool if Garcon.monotonic_time - @gc_interval >= @last_gc_time @pool.delete_if { |worker| worker.dead? } # send :stop for each thread over idletime @pool.select { |worker| @idletime != 0 && Garcon.monotonic_time - @idletime > worker.last_activity }.each { @queue << :stop } @last_gc_time = Garcon.monotonic_time end end
Provides recursive interpolation of node objects, using standard string interpolation methods.
@param [String] item
The string to interpolate.
@param [String, Hash] parent
The string used for substitution.
@return [String]
@api private
# File lib/garcon/utility/interpolation.rb, line 76 def render(item, parent = nil) item = item.to_hash if item.respond_to?(:to_hash) if item.is_a?(Hash) item = item.inject({}) { |memo, (k,v)| memo[sym(k)] = v; memo } item.inject({}) {|memo, (k,v)| memo[sym(k)] = render(v, item); memo} elsif item.is_a?(Array) item.map { |i| render(i, parent) } elsif item.is_a?(String) item % parent rescue item else item end end
# File lib/garcon/utility/hookers.rb, line 83 def run_hooker(name, *args) self.class.run_hooker_for(name, self, *args) end
@!visibility private
# File lib/garcon/task/read_write_lock.rb, line 275 def running_readers?(c = @counter.value) (c & MAX_READERS) > 0 end
@!visibility private
# File lib/garcon/task/read_write_lock.rb, line 280 def running_writer?(c = @counter.value) c >= RUNNING_WRITER end
@!visibility private
# File lib/garcon/task/timer_task.rb, line 348 def schedule_next_task(interval = execution_interval) Garcon::timer(interval, Garcon::Event.new, &method(:execute_task)) end
Set the options which define the operations value performs before returning data to the caller (dereferencing).
@note
Most classes that include this module will call `#set_deref_options` from within the constructor, thus allowing these options to be set at object creation.
@param [Hash] opts
the options defining dereference behavior.
@option opts [String] :dup_on_deref (false)
call `#dup` before returning the data
@option opts [String] :freeze_on_deref (false)
call `#freeze` before returning the data
@option opts [String] :copy_on_deref (nil)
call the given `Proc` passing the internal value and returning the value returned from the proc
# File lib/garcon/task/dereferenceable.rb, line 123 def set_deref_options(opts = {}) mutex.lock @dup_on_deref = opts[:dup_on_deref] || opts[:dup] @freeze_on_deref = opts[:freeze_on_deref] || opts[:freeze] @copy_on_deref = opts[:copy_on_deref] || opts[:copy] @nothing_on_deref = !(@dup_on_deref || @freeze_on_deref || @copy_on_deref) nil ensure mutex.unlock end
@!visibility private
# File lib/garcon/task/obligation.rb, line 197 def set_state(success, value, reason) if success @value = value @state = :fulfilled else @reason = reason @state = :rejected end end
# File lib/garcon/utility/memstash.rb, line 343 def shrink_if_needed @monitor.synchronize do if @stash.length > @max_entries entry = delete(@stash.shift) @expires_at.delete(entry) end end end
@!visibility private
# File lib/garcon/task/single_thread_executor.rb, line 54 def shutdown_execution @queue << :stop stopped_event.set unless alive? end
Percolate down to maintain heap invariant.
@param [Integer] k
The index at which to start the percolation.
@!visibility private
# File lib/garcon/task/priority_queue.rb, line 210 def sink(k) while (j = (2 * k)) <= @length do j += 1 if j < @length && ! ordered?(j, j+1) break if ordered?(k, j) swap(k, j) k = j end end
@!visibility private
# File lib/garcon/task/obligation.rb, line 208 def state=(value) mutex.lock @state = value ensure mutex.unlock end
# File lib/garcon/utility/memstash.rb, line 325 def store(key, val) @monitor.synchronize do expires_at = Time.now.to_f + @ttl_seconds entry = Entry.new(val, expires_at) store_entry(key, entry) val end end
# File lib/garcon/utility/memstash.rb, line 334 def store_entry(key, entry) @monitor.synchronize do @stash.delete(key) @stash[key] = entry @expires_at[entry] = key shrink_if_needed end end
@!visibility private
# File lib/garcon/task/single_thread_executor.rb, line 71 def supervise @thread = new_worker_thread unless alive? end
Percolate up to maintain heap invariant.
@param [Integer] k
The index at which to start the percolation.
@!visibility private
# File lib/garcon/task/priority_queue.rb, line 225 def swim(k) while k > 1 && ! ordered?(k/2, k) do swap(k, k/2) k = k/2 end end
Returns the columns and lines of the current tty.
@return [Integer]
Number of columns and lines of tty, returns [0, 0] if no tty is present.
# File lib/garcon/utility/misc.rb, line 26 def terminal_dimensions [0, 0] unless STDOUT.tty? [80, 40] if OS.windows? if ENV['COLUMNS'] && ENV['LINES'] [ENV['COLUMNS'].to_i, ENV['LINES'].to_i] elsif ENV['TERM'] && command_in_path?('tput') [`tput cols`.to_i, `tput lines`.to_i] elsif command_in_path?('stty') `stty size`.scan(/\d+/).map {|s| s.to_i } else [0, 0] end rescue [0, 0] end
@!visibility private
# File lib/garcon/task/timer_task.rb, line 368 def timeout_task(completion) return unless @running.true? if completion.try? self.value = value schedule_next_task observers.notify_observers(Time.now, nil, Garcon::TimeoutError.new) end end
@return [String] string of instance @api public
# File lib/garcon.rb, line 277 def to_s "<#{self.class}:0x#{object_id.to_s(16)}>" end
@!visibility private
# File lib/garcon/task/read_write_lock.rb, line 290 def waiting_writer?(c = @counter.value) c >= WAITING_WRITER end
@!visibility private
# File lib/garcon/task/read_write_lock.rb, line 285 def waiting_writers(c = @counter.value) (c & MAX_WRITERS) / WAITING_WRITER end
@!visibility private
# File lib/garcon/task/single_thread_executor.rb, line 84 def work loop do task = @queue.pop break if task == :stop begin task.last.call(*task.first) rescue => e Chef::Log.debug "Caught exception => #{e}" end end stopped_event.set end
Private Instance Methods
@!macro [attach] monotonic_get_time
Returns the current time a tracked by the application monotonic clock. @return [Float] The current monotonic time when `since` not given else the elapsed monotonic time between `since` and the current time @!macro monotonic_clock_warning
# File lib/garcon/task/monotonic_time.rb, line 65 def monotonic_time GLOBAL_MONOTONIC_CLOCK.get_time end
Perform the given operation asynchronously after the given number of seconds.
@param [Fixnum] seconds
The interval in seconds to wait before executing the task
@yield the task to execute
@return [Boolean] true
# File lib/garcon/task/timer.rb, line 34 def timer(seconds, *args, &block) raise ArgumentError, 'no block given' unless block_given? if seconds < 0 raise ArgumentError, 'interval must be greater than or equal to zero' end Garcon.global_timer_set.post(seconds, *args, &block) true end