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

atomic_write(file, secret, tmp_dir = Dir.tmpdir) click to toggle source

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
auto_terminate_all_executors?() click to toggle source

@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
auto_terminate_global_executors?() click to toggle source

@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
coercer() click to toggle source
# 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
coercer=(coercer) click to toggle source
# File lib/garcon/chef/coerce/coercer.rb, line 28
def self.coercer=(coercer)
  @coercer = coercer
end
config() { |configuration| ... } click to toggle source

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
configuration() click to toggle source

Global configuration instance.

@return [Configuration]

@api private

# File lib/garcon.rb, line 161
def self.configuration
  @configuration ||= Configuration.new
end
crypto(&block) click to toggle source

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
crypto=(value) click to toggle source

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(file = nil) click to toggle source

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
disable_auto_termination_of_all_executors!() click to toggle source

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
disable_auto_termination_of_global_executors!() click to toggle source

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_fast_executor() click to toggle source

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_io_executor() click to toggle source

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_timer_set() click to toggle source

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
kill_global_executors() click to toggle source
# 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_file(file) { || ... } click to toggle source

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
monotonic_time() click to toggle source

@!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
new_fast_executor(opts = {}) click to toggle source
# 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
new_io_executor(opts = {}) click to toggle source
# 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
random_seed() click to toggle source

@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
secret(&block) click to toggle source

Sets the global Secret configuration.

@return [Garcon::Secret]

@api public

# File lib/garcon.rb, line 116
def self.secret(&block)
  configuration.secret(&block)
end
secret=(value) click to toggle source

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
shutdown_global_executors() click to toggle source
# File lib/garcon.rb, line 222
def self.shutdown_global_executors
  global_fast_executor.shutdown
  global_io_executor.shutdown
  global_timer_set.shutdown
end
timer(seconds, *args, &block) click to toggle source

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
tmpfile(tmp_dir = Dir.tmpdir) click to toggle source

@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
wait_for_global_executors_termination(timeout = nil) click to toggle source
# 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
warn(msg) click to toggle source

@api private

# File lib/garcon.rb, line 282
def self.warn(msg)
  Kernel.warn(msg)
end
write(key, file) click to toggle source

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

extended(object) click to toggle source

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
included(object) click to toggle source

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

Calls superclass method
# 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

alive?() click to toggle source

@!visibility private

# File lib/garcon/task/single_thread_executor.rb, line 66
def alive?
  @thread && @thread.alive?
end
apply_deref_options(value) click to toggle source

@!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
check_expired(time) click to toggle source
# 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
clear_observers_and_return_old() click to toggle source
# 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
compute_physical_count() click to toggle source
# 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
continue_execution?(result) click to toggle source
# File lib/garcon/utility/hookers.rb, line 128
def continue_execution?(result)
  @options[:halts_on_falsey] ? result : true
end
create_at_exit_handler!(this) click to toggle source
# 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
create_mri_at_exit_handler!(id) click to toggle source
# 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_worker_thread() click to toggle source

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
drain_pool() click to toggle source

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
duplicate_observers() click to toggle source
# File lib/garcon/task/copy_on_notify_observer_set.rb, line 136
def duplicate_observers
  @mutex.lock
  observers = @observers.dup
  @mutex.unlock

  observers
end
ensure_capacity?() click to toggle source

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
event() click to toggle source

@!visibility private

# File lib/garcon/task/obligation.rb, line 192
def event
  @event
end
execute_task(completion) click to toggle source

@!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
get(key) click to toggle source
# 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
if_state(*expected_states) { || ... } click to toggle source

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
init_mutex() click to toggle source

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
init_obligation() click to toggle source

@!visibility private

# File lib/garcon/task/obligation.rb, line 186
def init_obligation
  init_mutex
  @event = Event.new
end
inspect() click to toggle source

@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
kill_execution() click to toggle source

@!visibility private

# File lib/garcon/task/single_thread_executor.rb, line 60
def kill_execution
  @queue.clear
  @thread.kill if alive?
end
max_readers?(c = @counter.value) click to toggle source

@!visibility private

# File lib/garcon/task/read_write_lock.rb, line 295
def max_readers?(c = @counter.value)
  (c & MAX_READERS) == MAX_READERS
end
max_writers?(c = @counter.value) click to toggle source

@!visibility private

# File lib/garcon/task/read_write_lock.rb, line 300
def max_writers?(c = @counter.value)
  (c & MAX_WRITERS) == MAX_WRITERS
end
mutex() click to toggle source

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
new_worker_thread() click to toggle source

@!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
notify_to(observers, *args) { || ... } click to toggle source
# 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
observers() click to toggle source
# File lib/garcon/task/copy_on_write_observer_set.rb, line 130
def observers
  @mutex.lock
  @observers
ensure
  @mutex.unlock
end
observers=(new_set) click to toggle source
# 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
ordered?(x, y) click to toggle source

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
prune_pool() click to toggle source

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
render(item, parent = nil) click to toggle source

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
run_hooker(name, *args) click to toggle source
# File lib/garcon/utility/hookers.rb, line 83
def run_hooker(name, *args)
  self.class.run_hooker_for(name, self, *args)
end
running_readers?(c = @counter.value) click to toggle source

@!visibility private

# File lib/garcon/task/read_write_lock.rb, line 275
def running_readers?(c = @counter.value)
  (c & MAX_READERS) > 0
end
running_writer?(c = @counter.value) click to toggle source

@!visibility private

# File lib/garcon/task/read_write_lock.rb, line 280
def running_writer?(c = @counter.value)
  c >= RUNNING_WRITER
end
schedule_next_task(interval = execution_interval) click to toggle source

@!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_deref_options(opts = {}) click to toggle source

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
set_state(success, value, reason) click to toggle source

@!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
shrink_if_needed() click to toggle source
# 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
shutdown_execution() click to toggle source

@!visibility private

# File lib/garcon/task/single_thread_executor.rb, line 54
def shutdown_execution
  @queue << :stop
  stopped_event.set unless alive?
end
sink(k) click to toggle source

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
state=(value) click to toggle source

@!visibility private

# File lib/garcon/task/obligation.rb, line 208
def state=(value)
  mutex.lock
  @state = value
ensure
  mutex.unlock
end
store(key, val) click to toggle source
# 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
store_entry(key, entry) click to toggle source
# 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
supervise() click to toggle source

@!visibility private

# File lib/garcon/task/single_thread_executor.rb, line 71
def supervise
  @thread = new_worker_thread unless alive?
end
swim(k) click to toggle source

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
terminal_dimensions() click to toggle source

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
timeout_task(completion) click to toggle source

@!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
to_s() click to toggle source

@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
waiting_writer?(c = @counter.value) click to toggle source

@!visibility private

# File lib/garcon/task/read_write_lock.rb, line 290
def waiting_writer?(c = @counter.value)
  c >= WAITING_WRITER
end
waiting_writers(c = @counter.value) click to toggle source

@!visibility private

# File lib/garcon/task/read_write_lock.rb, line 285
def waiting_writers(c = @counter.value)
  (c & MAX_WRITERS) / WAITING_WRITER
end
work() click to toggle source

@!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

monotonic_time() click to toggle source

@!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
timer(seconds, *args, &block) click to toggle source

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