def add_audio(customization_id:, audio_name:, audio_resource:, contained_content_type: nil, allow_overwrite: nil, content_type: nil)
      raise ArgumentError.new("customization_id must be provided") if customization_id.nil?

      raise ArgumentError.new("audio_name must be provided") if audio_name.nil?

      raise ArgumentError.new("audio_resource must be provided") if audio_resource.nil?

      headers = {
        "Contained-Content-Type" => contained_content_type,
        "Content-Type" => content_type
      }
      sdk_headers = Common.new.get_sdk_headers("speech_to_text", "V1", "add_audio")
      headers.merge!(sdk_headers)

      params = {
        "allow_overwrite" => allow_overwrite
      }

      data = audio_resource

      method_url = "/v1/acoustic_customizations/%s/audio/%s" % [ERB::Util.url_encode(customization_id), ERB::Util.url_encode(audio_name)]

      request(
        method: "POST",
        url: method_url,
        headers: headers,
        params: params,
        data: data,
        accept_json: true
      )
      nil
    end

Custom audio resources

 @!method add_audio(customization_id:, audio_name:, audio_resource:, contained_content_type: nil, allow_overwrite: nil, content_type: nil)
 Add an audio resource.
 Adds an audio resource to a custom acoustic model. Add audio content that reflects
   the acoustic characteristics of the audio that you plan to transcribe. You must
   use credentials for the instance of the service that owns a model to add an audio
   resource to it. Adding audio data does not affect the custom acoustic model until
   you train the model for the new data by using the **Train a custom acoustic
   model** method.

   You can add individual audio files or an archive file that contains multiple audio
   files. Adding multiple audio files via a single archive file is significantly more
   efficient than adding each file individually. You can add audio resources in any
   format that the service supports for speech recognition.

   You can use this method to add any number of audio resources to a custom model by
   calling the method once for each audio or archive file. But the addition of one
   audio resource must be fully complete before you can add another. You must add a
   minimum of 10 minutes and a maximum of 100 hours of audio that includes speech,
   not just silence, to a custom acoustic model before you can train it. No audio
   resource, audio- or archive-type, can be larger than 100 MB. To add an audio
   resource that has the same name as an existing audio resource, set the
   `allow_overwrite` parameter to `true`; otherwise, the request fails.

   The method is asynchronous. It can take several seconds to complete depending on
   the duration of the audio and, in the case of an archive file, the total number of
   audio files being processed. The service returns a 201 response code if the audio
   is valid. It then asynchronously analyzes the contents of the audio file or files
   and automatically extracts information about the audio such as its length,
   sampling rate, and encoding. You cannot submit requests to add additional audio
   resources to a custom acoustic model, or to train the model, until the service's
   analysis of all audio files for the current request completes.

   To determine the status of the service's analysis of the audio, use the **Get an
   audio resource** method to poll the status of the audio. The method accepts the
   customization ID of the custom model and the name of the audio resource, and it
   returns the status of the resource. Use a loop to check the status of the audio
   every few seconds until it becomes `ok`.

   **See also:** [Add audio to the custom acoustic
   model](https://cloud.ibm.com/docs/services/speech-to-text/acoustic-create.html#addAudio).

   ### Content types for audio-type resources

    You can add an individual audio file in any format that the service supports for
   speech recognition. For an audio-type resource, use the `Content-Type` parameter
   to specify the audio format (MIME type) of the audio file, including specifying
   the sampling rate, channels, and endianness where indicated.
   * `audio/alaw` (Specify the sampling rate (`rate`) of the audio.)
   * `audio/basic` (Use only with narrowband models.)
   * `audio/flac`
   * `audio/g729` (Use only with narrowband models.)
   * `audio/l16` (Specify the sampling rate (`rate`) and optionally the number of
   channels (`channels`) and endianness (`endianness`) of the audio.)
   * `audio/mp3`
   * `audio/mpeg`
   * `audio/mulaw` (Specify the sampling rate (`rate`) of the audio.)
   * `audio/ogg` (The service automatically detects the codec of the input audio.)
   * `audio/ogg;codecs=opus`
   * `audio/ogg;codecs=vorbis`
   * `audio/wav` (Provide audio with a maximum of nine channels.)
   * `audio/webm` (The service automatically detects the codec of the input audio.)
   * `audio/webm;codecs=opus`
   * `audio/webm;codecs=vorbis`

   The sampling rate of an audio file must match the sampling rate of the base model
   for the custom model: for broadband models, at least 16 kHz; for narrowband
   models, at least 8 kHz. If the sampling rate of the audio is higher than the
   minimum required rate, the service down-samples the audio to the appropriate rate.
   If the sampling rate of the audio is lower than the minimum required rate, the
   service labels the audio file as `invalid`.

    **See also:** [Audio
   formats](https://cloud.ibm.com/docs/services/speech-to-text/audio-formats.html).

   ### Content types for archive-type resources

    You can add an archive file (**.zip** or **.tar.gz** file) that contains audio
   files in any format that the service supports for speech recognition. For an
   archive-type resource, use the `Content-Type` parameter to specify the media type
   of the archive file:
   * `application/zip` for a **.zip** file
   * `application/gzip` for a **.tar.gz** file.

   When you add an archive-type resource, the `Contained-Content-Type` header is
   optional depending on the format of the files that you are adding:
   * For audio files of type `audio/alaw`, `audio/basic`, `audio/l16`, or
   `audio/mulaw`, you must use the `Contained-Content-Type` header to specify the
   format of the contained audio files. Include the `rate`, `channels`, and
   `endianness` parameters where necessary. In this case, all audio files contained
   in the archive file must have the same audio format.
   * For audio files of all other types, you can omit the `Contained-Content-Type`
   header. In this case, the audio files contained in the archive file can have any
   of the formats not listed in the previous bullet. The audio files do not need to
   have the same format.

   Do not use the `Contained-Content-Type` header when adding an audio-type resource.

   ### Naming restrictions for embedded audio files

    The name of an audio file that is embedded within an archive-type resource must
   meet the following restrictions:
   * Include a maximum of 128 characters in the file name; this includes the file
   extension.
   * Do not include spaces, slashes, or backslashes in the file name.
   * Do not use the name of an audio file that has already been added to the custom
   model as part of an archive-type resource.
 @param customization_id [String] The customization ID (GUID) of the custom acoustic model that is to be used for
   the request. You must make the request with credentials for the instance of the
   service that owns the custom model.
 @param audio_name [String] The name of the new audio resource for the custom acoustic model. Use a localized
   name that matches the language of the custom model and reflects the contents of
   the resource.
   * Include a maximum of 128 characters in the name.
   * Do not include spaces, slashes, or backslashes in the name.
   * Do not use the name of an audio resource that has already been added to the
   custom model.
 @param audio_resource [String] The audio resource that is to be added to the custom acoustic model, an individual
   audio file or an archive file.
 @param contained_content_type [String] **For an archive-type resource,** specify the format of the audio files that are
   contained in the archive file if they are of type `audio/alaw`, `audio/basic`,
   `audio/l16`, or `audio/mulaw`. Include the `rate`, `channels`, and `endianness`
   parameters where necessary. In this case, all audio files that are contained in
   the archive file must be of the indicated type.

   For all other audio formats, you can omit the header. In this case, the audio
   files can be of multiple types as long as they are not of the types listed in the
   previous paragraph.

   The parameter accepts all of the audio formats that are supported for use with
   speech recognition. For more information, see **Content types for audio-type
   resources** in the method description.

   **For an audio-type resource,** omit the header.
 @param allow_overwrite [Boolean] If `true`, the specified audio resource overwrites an existing audio resource with
   the same name. If `false`, the request fails if an audio resource with the same
   name already exists. The parameter has no effect if an audio resource with the
   same name does not already exist.
 @param content_type [String] For an audio-type resource, the format (MIME type) of the audio. For more
   information, see **Content types for audio-type resources** in the method
   description.

   For an archive-type resource, the media type of the archive file. For more
   information, see **Content types for archive-type resources** in the method
   description.
 @return [nil]


def create_event(type:, data:)
      raise ArgumentError.new("type must be provided") if type.nil?

      raise ArgumentError.new("data must be provided") if data.nil?

      headers = {
      }
      sdk_headers = Common.new.get_sdk_headers("discovery", "V1", "create_event")
      headers.merge!(sdk_headers)

      params = {
        "version" => @version
      }

      data = {
        "type" => type,
        "data" => data
      }

      method_url = "/v1/events"

      response = request(
        method: "POST",
        url: method_url,
        headers: headers,
        params: params,
        json: data,
        accept_json: true
      )
      response
    end

def
create_event
(
type
:
,
data
:
)
raise
ArgumentError
.
new
(
"type must be provided"
)
if
type
.
nil?
raise
ArgumentError
.
new
(
"data must be provided"
)
if
data
.
nil?
headers
=
{
}
sdk_headers
=
Common
.
new
.
get_sdk_headers
(
"discovery"
,
"V1"
,
"create_event"
)
headers
.
merge!
(
sdk_headers
)
params
=
{
"version"
=>
@version
}
data
=
{
"type"
=>
type
,
"data"
=>
data
}
method_url
=
"/v1/events"
response
=
request
(
method
:
"POST"
,
url
:
method_url
,
headers
:
headers
,
params
:
params
,
json
:
data
,
accept_json
:
true
)
response
end

Events and feedback

 @!method create_event(type:, data:)
 Create event.
 The **Events** API can be used to create log entries that are associated with
   specific queries. For example, you can record which documents in the results set
   were \"clicked\" by a user and when that click occured.
 @param type [String] The event type to be created.
 @param data [EventData] Query event data object.
 @return [IBMCloudSdkCore::DetailedResponse] A `IBMCloudSdkCore::DetailedResponse` object representing the response.


def zero_pad(n, message)
      len = message.bytesize
      if len == n
        message
      elsif len > n
        raise LengthError, "String too long for zero-padding to #{n} bytes"
      else
        message + zeros(n - len)
      end
    end

Pad a string out to n characters with zeros

 @param [Integer] n The length of the resulting string
 @param [String]  message the message to be padded

 @raise [RbNaCl::LengthError] If the string is too long

 @return [String] A string, n bytes long


def check_length(string, length, description)
      if string.nil?
        # code below is runs only in test cases
        # nil can't be converted to str with #to_str method
        raise LengthError,
              "#{description} was nil (Expected #{length.to_int})",
              caller
      end

      if string.bytesize != length.to_int
        raise LengthError,
              "#{description} was #{string.bytesize} bytes (Expected #{length.to_int})",
              caller
      end
      true
    end

Check the length of the passed in string

 In several places through the codebase we have to be VERY strict with
 what length of string we accept.  This method supports that.

 @raise [RbNaCl::LengthError] If the string is not the right length

 @param string [String] The string to compare
 @param length [Integer] The desired length
 @param description [String] Description of the string (used in the error)


def check_string(string, length, description)
      check_string_validation(string)
      string = string.to_s
      check_length(string, length, description)

      string
    end

def check_string ( string , length , description ) check_string_validation ( string ) string = string . to_s check_length ( string , length , description ) string end

Check a passed in string, converting the argument if necessary

 In several places through the codebase we have to be VERY strict with
 the strings we accept.  This method supports that.

 @raise [ArgumentError] If we cannot convert to a string with #to_str
 @raise [RbNaCl::LengthError] If the string is not the right length

 @param string [#to_str] The input string
 @param length [Integer] The only acceptable length of the string
 @param description [String] Description of the string (used in the error)

Check a passed in string converting the argument if necessary


def check_hmac_key(string, _description)
      check_string_validation(string)

      string = string.to_str

      if string.bytesize.zero?
        raise LengthError,
              "#{Description} was #{string.bytesize} bytes (Expected more than 0)",
              caller
      end

      string
    end

Check a passed in string, convertion if necessary

 This method will check the key, and raise error
 if argument is not a string, and if it's empty string.

 RFC 2104 HMAC
 The key for HMAC can be of any length (keys longer than B bytes are
 first hashed using H). However, less than L bytes is strongly
 discouraged as it would decrease the security strength of the
 function.  Keys longer than L bytes are acceptable but the extra
 length would not significantly increase the function strength. (A
 longer key may be advisable if the randomness of the key is
 considered weak.)

 see https://tools.ietf.org/html/rfc2104#section-3

 @raise [ArgumentError] If we cannot convert to a string with #to_str
 @raise [RbNaCl::LengthError] If the string is empty

 @param string [#to_str] The input string

Check a passed in string convertion if necessary


def check_string_validation(string)
      raise TypeError, "can't convert #{string.class} into String with #to_str" unless string.respond_to? :to_str

      string = string.to_str

      raise EncodingError, "strings must use BINARY encoding (got #{string.encoding})" if string.encoding != Encoding::BINARY
    end

Check a passed string is it valid

 Raise an error if passed argument is invalid

 @raise [TypeError] If string cannot convert to a string with #to_str
 @raise [EncodingError] If string have wrong encoding

 @param string [#to_str] The input string


def auth(message)
      authenticator = Util.zeros(tag_bytes)
      message = message.to_str
      compute_authenticator(authenticator, message)
      authenticator
    end

def auth ( message ) authenticator = Util . zeros ( tag_bytes ) message = message . to_str compute_authenticator ( authenticator , message ) authenticator end

Compute authenticator for message

 @param [#to_str] message the message to authenticate

 @return [String] the authenticator as raw bytes


def verify(authenticator, message)
      auth = authenticator.to_s
      Util.check_length(auth, tag_bytes, "Provided authenticator")
      verify_message(auth, message) || raise(BadAuthenticatorError, "Invalid authenticator provided, message is corrupt")
    end

Verifies the given authenticator with the message.

 @param [#to_str] authenticator to be checked
 @param [#to_str] message the message to be authenticated

 @raise [BadAuthenticatorError] if the tag isn't valid
 @raise [LengthError]  if the tag is of the wrong length

 @return [Boolean] Was it valid?

Verifies the given authenticator with the message .


def box(message)
      nonce = generate_nonce
      cipher_text = @box.box(nonce, message)
      nonce + cipher_text
    end

def box ( message ) nonce = generate_nonce cipher_text = @box . box ( nonce , message ) nonce + cipher_text end

Encrypts the message with a random nonce

 Encrypts the message with a random nonce, then returns the ciphertext with
 the nonce prepended.  Optionally encodes the message using an encoder.

 @param message [String] The message to encrypt

 @return [String] The enciphered message


def open(enciphered_message)
      nonce, ciphertext = extract_nonce(enciphered_message.to_s)
      @box.open(nonce, ciphertext)
    end

def open ( enciphered_message ) nonce , ciphertext = extract_nonce ( enciphered_message . to_s ) @box . open ( nonce , ciphertext ) end

Decrypts the ciphertext with a random nonce

 Takes a ciphertext, optionally decodes it, then splits the nonce off the
 front and uses this to decrypt.  Returns the message.

 @param enciphered_message [String] The message to decrypt.

 @raise [CryptoError] If the message has been tampered with.

 @return [String] The decoded message


def reopen
      each do |appender|
        begin
          next unless appender.respond_to?(:reopen)

          logger.trace "Reopening appender: #{appender.name}"
          appender.reopen
        rescue Exception => exc
          logger.error "Failed to re-open appender: #{appender.inspect}", exc
        end
      end
      logger.trace 'All appenders re-opened'
    end

After a fork the appender thread is not running, start it if it is not running.

After a fork the appender thread is not running start it if it is not running .


def logger
      @logger ||= begin
        logger      = SemanticLogger::Processor.logger.clone
        logger.name = self.class.name
        logger
      end
    end

def logger @logger ||= begin logger = SemanticLogger :: Processor . logger . clone logger . name = self . class . name logger end end

Give each appender its own logger for logging.
 For example trace messages sent to services or errors when something fails.

Give each appender its own logger for logging . For example trace messages sent to services or errors when something fails .


def measure(level, message, params = {}, &block)
      index = Levels.index(level)
      if level_index <= index
        measure_internal(level, index, message, params, &block)
      elsif block
        yield(params)
      end
    end

def measure ( level , message , params = { } , & block ) index = Levels . index ( level ) if level_index <= index measure_internal ( level , index , message , params , block ) elsif block yield ( params ) end end

Dynamically supply the log level with every measurement call


def backtrace(thread: Thread.current,
                  level: :warn,
                  message: 'Backtrace:',
                  payload: nil,
                  metric: nil,
                  metric_amount: nil)

      log = Log.new(name, level)
      return false unless meets_log_level?(log)

      backtrace =
        if thread == Thread.current
          Utils.extract_backtrace
        else
          log.thread_name = thread.name
          log.tags        = (thread[:semantic_logger_tags] || []).clone
          log.named_tags  = (thread[:semantic_logger_named_tags] || {}).clone
          thread.backtrace
        end
      # TODO: Keep backtrace instead of transforming into a text message at this point
      # Maybe log_backtrace: true
      if backtrace
        message += "\n"
        message << backtrace.join("\n")
      end

      if log.assign(message:       message,
                    backtrace:     backtrace,
                    payload:       payload,
                    metric:        metric,
                    metric_amount: metric_amount) && !filtered?(log)
        self.log(log)
      else
        false
      end
    end


def tagged(*tags, &block)
      # Allow named tags to be passed into the logger
      if tags.size == 1
        tag = tags[0]
        return yield if tag.nil? || tag == ''
        return tag.is_a?(Hash) ? SemanticLogger.named_tagged(tag, &block) : SemanticLogger.fast_tag(tag.to_s, &block)
      end

      # Need to flatten and reject empties to support calls from Rails 4
      new_tags = tags.flatten.collect(&:to_s).reject(&:empty?)
      SemanticLogger.tagged(*new_tags, &block)
    end

Add the tags or named tags to the list of tags to log for this thread whilst the supplied block is active.

 Returns result of block.

 Tagged example:
   SemanticLogger.tagged(12345, 'jack') do
     logger.debug('Hello World')
   end

 Named Tags (Hash) example:
   SemanticLogger.tagged(tracking_number: 12345) do
     logger.debug('Hello World')
   end

 Notes:
 - Named tags are the recommended approach since the tag consists of a name value pair this is more useful
   than just a string value in the logs, or centralized logging system.
 - This method is slow when using multiple text tags since it needs to flatten the tags and
   remove empty elements to support Rails 4.
 - It is recommended to keep tags as a list without any empty values, or contain any child arrays.
   However, this api will convert:
     `logger.tagged([['first', nil], nil, ['more'], 'other'])`
   to:
     `logger.tagged('first', 'more', 'other')`
 - For better performance with clean tags, see `SemanticLogger.tagged`.

Add the tags or named tags to the list of tags to log for this thread whilst the supplied block is active .


def push_tags(*tags)
      # Need to flatten and reject empties to support calls from Rails 4
      new_tags = tags.flatten.collect(&:to_s).reject(&:empty?)
      SemanticLogger.push_tags(*new_tags)
    end

Returns the list of tags pushed after flattening them out and removing blanks

 Note:
 - This method is slow since it needs to flatten the tags and remove empty elements
   to support Rails 4.
 - For better performance with clean tags, use `SemanticLogger.push_tags`


def filtered?(log)
      return false if @filter.nil?

      @filter.is_a?(Regexp) ? (@filter =~ log.name).nil? : @filter.call(log) != true
    end

def filtered? ( log ) return false if @filter . nil? @filter . is_a? ( Regexp ) ? ( @filter =~ log . name ) . nil? : @filter . call ( log ) != true end

Whether to log the supplied message based on the current filter if any


def log_internal(level, index, message = nil, payload = nil, exception = nil, &block)
      log        = Log.new(name, level, index)
      should_log =
        if payload.nil? && exception.nil? && message.is_a?(Hash)
          # Check if someone just logged a hash payload instead of meaning to call semantic logger
          if message.key?(:message) || message.key?(:payload) || message.key?(:exception) || message.key?(:metric)
            log.assign(message)
          else
            log.assign_positional(nil, message, nil, &block)
          end
        else
          log.assign_positional(message, payload, exception, &block)
        end

      # Log level may change during assign due to :on_exception_level
      self.log(log) if should_log && should_log?(log)
    end


def measure_internal(level, index, message, params)
      exception = nil
      result    = nil
      # Single parameter is a hash
      if params.empty? && message.is_a?(Hash)
        params  = message
        message = nil
      end
      start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
      begin
        if block_given?
          result =
            if (silence_level = params[:silence])
              # In case someone accidentally sets `silence: true` instead of `silence: :error`
              silence_level = :error if silence_level == true
              silence(silence_level) { yield(params) }
            else
              yield(params)
            end
        end
      rescue Exception => exc
        exception = exc
      ensure
        # Must use ensure block otherwise a `return` in the yield above will skip the log entry
        log       = Log.new(name, level, index)
        exception ||= params[:exception]
        message   = params[:message] if params[:message]
        duration  =
          if block_given?
            1_000.0 * (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start)
          else
            params[:duration] || raise('Mandatory block missing when :duration option is not supplied')
          end

        # Extract options after block completes so that block can modify any of the options
        payload = params[:payload]

        # May return false due to elastic logging
        should_log = log.assign(
          message:            message,
          payload:            payload,
          min_duration:       params[:min_duration] || 0.0,
          exception:          exception,
          metric:             params[:metric],
          metric_amount:      params[:metric_amount],
          duration:           duration,
          log_exception:      params[:log_exception] || :partial,
          on_exception_level: params[:on_exception_level]
        )

        # Log level may change during assign due to :on_exception_level
        self.log(log) if should_log && should_log?(log)
        raise exception if exception
        result
      end
    end

Measure the supplied block and log the message


def measure_method(index:,
                       level:,
                       message:,
                       min_duration:,
                       metric:,
                       log_exception:,
                       on_exception_level:)

      # Ignores filter, silence, payload
      exception = nil
      start     = Process.clock_gettime(Process::CLOCK_MONOTONIC)
      begin
        yield
      rescue Exception => exc
        exception = exc
      ensure
        log = Log.new(name, level, index)
        # May return false due to elastic logging
        should_log = log.assign(
          message:            message,
          min_duration:       min_duration,
          exception:          exception,
          metric:             metric,
          duration:           1_000.0 * (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start),
          log_exception:      log_exception,
          on_exception_level: on_exception_level
        )

        # Log level may change during assign due to :on_exception_level
        log(log) if should_log && should_log?(log)
        raise exception if exception
      end
    end

For measuring methods and logging their duration.

For measuring methods and logging their duration .


def log(log, message = nil, progname = nil, &block)
      # Compatibility with ::Logger
      return add(log, message, progname, &block) unless log.is_a?(SemanticLogger::Log)

      Logger.call_subscribers(log)

      Logger.processor.log(log)
    end

def
log
(
log
,
message
=
,
progname
=
,
&
block
)
# Compatibility with ::Logger
return
add
(
log
,
message
,
progname
,
block
)
unless
log
.
is_a?
(
SemanticLogger
::
Log
)
Logger
.
call_subscribers
(
log
)
Logger
.
processor
.
log
(
log
)
end

Returns a Logger instance

 Return the logger for a specific class, supports class specific log levels
   logger = SemanticLogger::Logger.new(self)
 OR
   logger = SemanticLogger::Logger.new('MyClass')

 Parameters:
  klass
    A class, module or a string with the application/class name
    to be used in the logger

  level
    The initial log level to start with for this logger instance
    Default: SemanticLogger.default_level

  filter [Regexp|Proc]
    RegExp: Only include log messages where the class name matches the supplied
    regular expression. All other messages will be ignored
    Proc: Only include log messages where the supplied Proc returns true
          The Proc must return true or false
 Place log request on the queue for the Appender thread to write to each
 appender in the order that they were registered

 Subscribers are called inline before handing off to the queue so that
 they can capture additional context information as needed.


def assign(message: nil,
               payload: nil,
               min_duration: 0.0,
               exception: nil,
               metric: nil,
               metric_amount: nil,
               duration: nil,
               backtrace: nil,
               log_exception: :full,
               on_exception_level: nil,
               dimensions: nil)
      # Elastic logging: Log when :duration exceeds :min_duration
      # Except if there is an exception when it will always be logged
      if duration
        self.duration = duration
        return false if (duration < min_duration) && exception.nil?
      end

      self.message = message
      if payload && payload.is_a?(Hash)
        self.payload = payload
      elsif payload
        self.message = message.nil? ? payload.to_s : "#{message} -- #{payload}"
        self.payload = nil
      end

      if exception
        case log_exception
        when :full
          self.exception = exception
        when :partial
          self.message = "#{message} -- Exception: #{exception.class}: #{exception.message}"
        when nil, :none
          # Log the message without the exception that was raised
          nil
        else
          raise(ArgumentError, "Invalid value:#{log_exception.inspect} for argument :log_exception")
        end
        # On exception change the log level
        if on_exception_level
          self.level       = on_exception_level
          self.level_index = Levels.index(level)
        end
      end

      if backtrace
        self.backtrace = Utils.extract_backtrace(backtrace)
      elsif level_index >= SemanticLogger.backtrace_level_index
        self.backtrace = Utils.extract_backtrace
      end

      if metric
        self.metric        = metric
        self.metric_amount = metric_amount
        self.dimensions    = dimensions
      end

      true
    end

Assign named arguments to this log entry, supplying defaults where applicable

 Returns [true|false] whether this log entry should be logged

 Example:
   logger.info(name: 'value')

Assign named arguments to this log entry supplying defaults where applicable


def assign_positional(message = nil, payload = nil, exception = nil)
      # Exception being logged?
      # Under JRuby a java exception is not a Ruby Exception
      #   Java::JavaLang::ClassCastException.new.is_a?(Exception) => false
      if exception.nil? && payload.nil? && message.respond_to?(:backtrace) && message.respond_to?(:message)
        exception = message
        message   = nil
      elsif exception.nil? && payload && payload.respond_to?(:backtrace) && payload.respond_to?(:message)
        exception = payload
        payload   = nil
      elsif payload && !payload.is_a?(Hash)
        message = message.nil? ? payload : "#{message} -- #{payload}"
        payload = nil
      end

      # Add result of block as message or payload if not nil
      if block_given? && (result = yield)
        if result.is_a?(String)
          message = message.nil? ? result : "#{message} -- #{result}"
          assign(message: message, payload: payload, exception: exception)
        elsif message.nil? && result.is_a?(Hash) && %i[message payload exception].any? { |k| result.key? k }
          assign(result)
        elsif payload&.respond_to?(:merge)
          assign(message: message, payload: payload.merge(result), exception: exception)
        else
          assign(message: message, payload: result, exception: exception)
        end
      else
        assign(message: message, payload: payload, exception: exception)
      end
    end

Assign positional arguments to this log entry, supplying defaults where applicable

 Returns [true|false] whether this log entry should be logged

 Example:
   logger.info('value', :debug, 0, "hello world")

Assign positional arguments to this log entry supplying defaults where applicable


def each_exception
      # With thanks to https://github.com/bugsnag/bugsnag-ruby/blob/6348306e44323eee347896843d16c690cd7c4362/lib/bugsnag/notification.rb#L81
      depth      = 0
      exceptions = []
      ex         = exception
      while !ex.nil? && !exceptions.include?(ex) && exceptions.length < MAX_EXCEPTIONS_TO_UNWRAP
        exceptions << ex
        yield(ex, depth)

        depth += 1
        ex    =
          if ex.respond_to?(:cause) && ex.cause
            ex.cause
          elsif ex.respond_to?(:continued_exception) && ex.continued_exception
            ex.continued_exception
          elsif ex.respond_to?(:original_exception) && ex.original_exception
            ex.original_exception
          end
      end
    end

Call the block for exception and any nested exception


def extract_file_and_line(stack, short_name = false)
      match = CALLER_REGEXP.match(stack.first)
      [short_name ? File.basename(match[1]) : match[1], match[2].to_i]
    end

def extract_file_and_line ( stack , short_name = false ) match = CALLER_REGEXP . match ( stack . first ) [ short_name ? File . basename ( match [ 1 ] ) : match [ 1 ] , match [ 2 ] . to_i ] end

Extract the filename and line number from the last entry in the supplied backtrace


def message_for(corrections)
      return "" if corrections.empty?

      output = "\n\n    Did you mean? ".dup
      output << corrections.join("\n                  ")
      output << "\n "
    end

def
message_for
(
corrections
)
return
""
if
corrections
.
empty?
output
=
"\n\n    Did you mean? "
.
dup
output
<<
corrections
.
join
(
"\n                  "
)
output
<<
"\n "
end

Returns a human readable string that contains +corrections+. This
 formatter is designed to be less verbose to not take too much screen
 space while being helpful enough to the user.

 @example

   formatter = DidYouMean::PlainFormatter.new

   puts formatter.message_for(["methods", "method"])

       Did you mean? methods
                     method

   # => nil

Returns a human readable string that contains + corrections + . This formatter is designed to be less verbose to not take too much screen space while being helpful enough to the user .


def gather_vars(executor, tconf, message)

      # try to return before a potentially costly call to executor.vars(nid)

      return nil if (tconf.keys & %w[ include_vars exclude_vars ]).empty?
        # default behaviour, don't pass variables to taskers

      iv = expand_filter(tconf['include_vars'])
      return nil if iv == false

      ev = expand_filter(tconf['exclude_vars'])
      return {} if ev == true

      vars = executor.vars(message['nid'])

      return vars if iv == true

      vars = vars.select { |k, v| var_match(k, iv) } if iv
      vars = vars.reject { |k, v| var_match(k, ev) } if ev

      vars
    end

By default, taskers don't see the flor variables in the execution.
 If 'include_vars' or 'exclude_vars' is present in the configuration
 of the tasker, some or all of the variables are passed.

By default taskers don t see the flor variables in the execution . If include_vars or exclude_vars is present in the configuration of the tasker some or all of the variables are passed .


def do_run

      @unit.logger.log_run_start(self)

      counter_next('runs')

      t0 = Time.now

      (@unit.conf['exe_max_messages'] || 77).times do |i|

        break if @shutdown

        m = @messages.shift
        break unless m

        m = (@messages << m).shift \
          if m['point'] == 'terminated' && @messages.any?
            #
            # handle 'terminated' messages last

        ms = process(m)

        @consumed << m

        ims, oms = ms.partition { |mm| mm['exid'] == @exid }
          # qui est "in", qui est "out"?

        counter_add('omsgs', oms.size)
          # keep track of "out" messages, messages to other executions

        @messages.concat(ims)
        @unit.storage.put_messages(oms)
      end

      @alive = false

      @execution.merge!(
        closing_messages: @consumed.select { |m|
          CLOSING_POINTS.include?(m['point']) })

      @unit.storage.put_execution(@execution)
      @unit.storage.consume(@consumed)

      @unit.storage.put_messages(@messages)

      du = Time.now - t0
      t0 = Flor.tstamp(t0)

      @unit.logger.log_run_end(self, t0, du)
      @unit.hooker.notify(self, make_end_message(t0, du, @execution['size']))

      @consumed.clear

    rescue Exception => exc

# TODO eventually, have a dump dir
      fn =
        [
          'flor',
          @unit.conf['env'], @unit.identifier, @exid,
          'r' + counter('runs').to_s
        ].collect(&:to_s).join('_') + '.dump'

      @unit.logger.error(
        "#{self.class}#do_run()", exc, "(dumping to #{fn})")

      File.open(fn, 'wb') do |f|
        f.puts(Flor.to_pretty_s({
          execution: @execution,
          messages: @messages,
          consumed: @consumed,
          traps: @traps.collect(&:to_h),
          exid: @exid,
          alive: @alive,
          shutdown: @shutdown,
          thread: [ @thread.object_id, @thread.to_s ]
        }))
        f.puts('-' * 80)
        f.puts(on_do_run_exc(exc))
      end

      #puts on_do_run_exc(exc)
        # dump notification above
    end

point for messages that, after consumption, are conserved
 in the execution's "closing_messages" array

point for messages that after consumption are conserved in the execution s closing_messages array


def route(name)

      if name.is_a?(String)

        [ Flor.dup_and_merge(
            @message,
            'tasker' => name, 'original_tasker' => @message['tasker'],
            'routed' => true) ]

      else

        [ Flor.dup_and_merge(
            @message,
            'routed' => !! name) ]
      end
    end

def route ( name ) if name . is_a? ( String ) [ Flor . dup_and_merge ( @message , 'tasker' => name , 'original_tasker' => @message [ 'tasker' ] , 'routed' => true ) ] else [ Flor . dup_and_merge ( @message , 'routed' => ! ! name ) ] end end


def row_waiter?

      @serie.find { |_, points|
        points.find { |po|
          pos = po.split(':')
          pos.length > 1 && ROW_PSEUDO_POINTS.include?(pos[0]) } }
    end

def row_waiter? @serie . find { | _ , points | points . find { | po | pos = po . split ( ':' ) pos . length > 1 && ROW_PSEUDO_POINTS . include? ( pos [ 0 ] ) } } end

"tasker", not "task", since "task" is already a message point

tasker not task since task is already a message point


def node(reload=false)

      nid = @values[:nid]; return nil unless nid
      exe = execution(reload); return nil unless exe

      nodes = exe.data['nodes']; return nil unless nodes
      nodes[nid]
    end

def node ( reload = false ) nid = @values [ :nid ] ; return nil unless nid exe = execution ( reload ) ; return nil unless exe nodes = exe . data [ 'nodes' ] ; return nil unless nodes nodes [ nid ] end

Returns the node hash linked to this model


def vars(nid, vs={})

      n = node(nid); return vs unless n

      (n['vars'] || {})
        .each { |k, v| vs[k] = Flor.dup(v) unless vs.has_key?(k) }

      pnid = n['parent']

      if @unit.loader && pnid == nil && n['vdomain'] != false

        @unit.loader.variables(n['vdomain'] || Flor.domain(@exid))
          .each { |k, v| vs[k] = Flor.dup(v) unless vs.has_key?(k) }
      end

      if cn = n['cnid']; vars(cn, vs); end
      vars(pnid, vs) if pnid

      vs
    end

def vars ( nid , vs = { } ) n = node ( nid ) ; return vs unless n ( n [ 'vars' ] || { } ) . each { | k , v | vs [ k ] = Flor . dup ( v ) unless vs . has_key? ( k ) } pnid = n [ 'parent' ] if @unit . loader && pnid == nil && n [ 'vdomain' ] != false @unit . loader . variables ( n [ 'vdomain' ] || Flor . domain ( @exid ) ) . each { | k , v | vs [ k ] = Flor . dup ( v ) unless vs . has_key? ( k ) } end if cn = n [ 'cnid' ] ; vars ( cn , vs ) ; end vars ( pnid , vs ) if pnid vs end

Given a nid, returns a copy of all the var the node sees at that point.

Given a nid returns a copy of all the var the node sees at that point .


def lookup_on_error_parent(message)

      nd = Flor::Node.new(self, nil, message).on_error_parent
      nd ? nd.to_procedure_node : nil
    end

def lookup_on_error_parent ( message ) nd = Flor :: Node . new ( self , nil , message ) . on_error_parent nd ? nd . to_procedure_node : nil end

Return an empty array of new messages. No direct effect.

 Some trap, hook, and/or waiter might lie in wait though.

Return an empty array of new messages . No direct effect .


def decrement

      c = data['count']
      return false unless c

      c = c - 1
      data['count'] = c
      self[:status] = s = (c > 0) ? 'active' : 'consumed'

      self.update(
        content: Flor::Storage.to_blob(@flor_model_cache_data),
        status: s)

      c < 1
    end

def decrement c = data [ 'count' ] return false unless c c = c - 1 data [ 'count' ] = c self [ :status ] = s = ( c > 0 ) ? 'active' : 'consumed' self . update ( content : Flor :: Storage . to_blob ( @flor_model_cache_data ) , status : s ) c < 1 end

returns true if the trap should be removed from the execution's list
 of traps

returns true if the trap should be removed from the execution s list of traps


def work
      queue, job = lock_job
      if queue && job
        QC.log_yield(:at => "work", :job => job[:id]) do
          process(queue, job)
        end
      end
    end

def work queue , job = lock_job if queue && job QC . log_yield ( :at => "work" , :job => job [ :id ] ) do process ( queue , job ) end end end

Blocks on locking a job, and once a job is locked,
 it will process the job.

Blocks on locking a job and once a job is locked it will process the job .


def lock_job
      log(:at => "lock_job")
      job = nil
      while @running
        @queues.each do |queue|
          if job = queue.lock
            return [queue, job]
          end
        end
        @conn_adapter.wait(@wait_interval, *@queues.map {|q| q.name})
      end
    end

def lock_job log ( :at => "lock_job" ) job = nil while @running @queues . each do | queue | if job = queue . lock return [ queue , job ] end end @conn_adapter . wait ( @wait_interval , @queues . map { | q | q . name } ) end end

Attempt to lock a job in the queue's table.
 If a job can be locked, this method returns an array with
 2 elements. The first element is the queue from which the job was locked
 and the second is a hash representation of the job.
 If a job is returned, its locked_at column has been set in the
 job's row. It is the caller's responsibility to delete the job row
 from the table when the job is complete.

Attempt to lock a job in the queue s table . If a job can be locked this method returns an array with 2 elements . The first element is the queue from which the job was locked and the second is a hash representation of the job . If a job is returned its locked_at column has been set in the job s row . It is the caller s responsibility to delete the job row from the table when the job is complete .


def call(job)
      args = job[:args]
      receiver_str, _, message = job[:method].rpartition('.')
      receiver = eval(receiver_str)
      receiver.send(message, *args)
    end

def call ( job ) args = job [ :args ] receiver_str , _ , message = job [ :method ] . rpartition ( '.' ) receiver = eval ( receiver_str ) receiver . send ( message , args ) end

Each job includes a method column. We will use ruby's eval
 to grab the ruby object from memory. We send the method to
 the object and pass the args.

Each job includes a method column . We will use ruby s eval to grab the ruby object from memory . We send the method to the object and pass the args .


def method_missing(meth, opts = {})
      if meth.to_s == 'to_ary'
        super
      end

      if meth.to_s.end_with? '!'
        deep_merge_options meth[0..-2].to_sym, opts
      else
        merge_options meth, opts
      end
    end

def method_missing ( meth , opts = { } ) if meth . to_s == 'to_ary' super end if meth . to_s . end_with? '!' deep_merge_options meth [ 0 .. - 2 ] . to_sym , opts else merge_options meth , opts end end

Pass other methods through to the javascript high_chart object.

 For instance: <tt>high_chart.grid(:color => "#699")</tt>

Pass other methods through to the javascript high_chart object .


def remove_params(params)
      self.tap do |u|
        u.query_values = (u.query_values || {}).tap do |qv|
          params.each do |key, value|
            qv.delete key
          end
        end
        if u.query_values.empty?
          u.query_values = nil
        end
      end
    end

def remove_params ( params ) self . tap do | u | u . query_values = ( u . query_values || { } ) . tap do | qv | params . each do | key , value | qv . delete key end end if u . query_values . empty? u . query_values = nil end end end


def parse_user_info(node)
      return nil if node.nil?
      {}.tap do |hash|
        node.children.each do |e|
          unless e.kind_of?(Nokogiri::XML::Text) || e.name == 'proxies'
            # There are no child elements
            if e.element_children.count == 0
              if hash.has_key?(e.name)
                hash[e.name] = [hash[e.name]] if hash[e.name].is_a? String
                hash[e.name] << e.content
              else
                hash[e.name] = e.content
              end
            elsif e.element_children.count
              # JASIG style extra attributes
              if e.name == 'attributes'
                hash.merge!(parse_user_info(e))
              else
                hash[e.name] = [] if hash[e.name].nil?
                hash[e.name] = [hash[e.name]] if hash[e.name].is_a? String
                hash[e.name].push(parse_user_info(e))
              end
            end
          end
        end
      end
    end

def
parse_user_info
(
node
)
return
if
node
.
nil?
{
}
.
tap
do
|
hash
|
node
.
children
.
each
do
|
e
|
unless
e
.
kind_of?
(
Nokogiri
::
XML
::
Text
)
||
e
.
name
==
'proxies'
# There are no child elements
if
e
.
element_children
.
count
==
0
if
hash
.
has_key?
(
e
.
name
)
hash
[
e
.
name
]
=
[
hash
[
e
.
name
]
]
if
hash
[
e
.
name
]
.
is_a?
String
hash
[
e
.
name
]
<<
e
.
content
else
hash
[
e
.
name
]
=
e
.
content
end
elsif
e
.
element_children
.
count
# JASIG style extra attributes
if
e
.
name
==
'attributes'
hash
.
merge!
(
parse_user_info
(
e
)
)
else
hash
[
e
.
name
]
=
[
]
if
hash
[
e
.
name
]
.
nil?
hash
[
e
.
name
]
=
[
hash
[
e
.
name
]
]
if
hash
[
e
.
name
]
.
is_a?
String
hash
[
e
.
name
]
.
push
(
parse_user_info
(
e
)
)
end
end
end
end
end
end


def run_async(command)
      raise 'Async command already in progress' if @started
      @started = false
      @user_method.reset

      session.open_channel do |channel|
        channel.request_pty
        channel.on_data do |ch, data|
          publish_data(data, 'stdout') unless @user_method.filter_password?(data)
          @user_method.on_data(data, ch)
        end
        channel.on_extended_data { |ch, type, data| publish_data(data, 'stderr') }
        # standard exit of the command
        channel.on_request('exit-status') { |ch, data| publish_exit_status(data.read_long) }
        # on signal: sending the signal value (such as 'TERM')
        channel.on_request('exit-signal') do |ch, data|
          publish_exit_status(data.read_string)
          ch.close
          # wait for the channel to finish so that we know at the end
          # that the session is inactive
          ch.wait
        end
        channel.exec(command) do |_, success|
          @started = true
          raise('Error initializing command') unless success
        end
      end
      session.process(0) { !run_started? }
      return true
    end

Initiates run of the remote command and yields the data when
 available. The yielding doesn't happen automatically, but as
 part of calling the `refresh` method.

Initiates run of the remote command and yields the data when available . The yielding doesn t happen automatically but as part of calling the refresh method .


def exit_code
      fail_chance   = ENV.fetch('REX_SIMULATE_FAIL_CHANCE', 0).to_i
      fail_exitcode = ENV.fetch('REX_SIMULATE_EXIT', 0).to_i
      if fail_exitcode == 0 || fail_chance < (Random.rand * 100).round
        0
      else
        fail_exitcode
      end
    end

def exit_code fail_chance = ENV . fetch ( 'REX_SIMULATE_FAIL_CHANCE' , 0 ) . to_i fail_exitcode = ENV . fetch ( 'REX_SIMULATE_EXIT' , 0 ) . to_i if fail_exitcode == 0 || fail_chance < ( Random . rand * 100 ) . round 0 else fail_exitcode end end

Decide if the execution should fail or not


def import_method(source, name, new_name = name)
      from = name.to_sym
      to   = new_name.to_sym

      fn = source.is_a?(Registry) ? source.fetch(from) : source.method(from)
      self.class.new(methods.merge(to => fn))
    end

def import_method ( source , name , new_name = name ) from = name . to_sym to = new_name . to_sym fn = source . is_a? ( Registry ) ? source . fetch ( from ) : source . method ( from ) self . class . new ( methods . merge ( to => fn ) ) end

Creates new immutable collection from the current one,
 updated with either the module's singleton method,
 or the proc having been imported from another module.

 @param [Module] source
 @param [Symbol] name
 @param [Symbol] new_name

 @return [Transproc::Store]

Creates new immutable collection from the current one updated with either the module s singleton method or the proc having been imported from another module .


def import_methods(source, names)
      names.inject(self) { |a, e| a.import_method(source, e) }
    end

def import_methods ( source , names ) names . inject ( self ) { | a , e | a . import_method ( source , e ) } end

Creates new immutable collection from the current one,
 updated with either the module's singleton methods,
 or the procs having been imported from another module.

 @param [Module] source
 @param [Array<Symbol>] names

 @return [Transproc::Store]

Creates new immutable collection from the current one updated with either the module s singleton methods or the procs having been imported from another module .


def import_all(source)
      names = source.public_methods - Registry.instance_methods - Module.methods
      names -= [:initialize] # for compatibility with Rubinius
      names += source.store.methods.keys if source.is_a? Registry

      import_methods(source, names)
    end

def
import_all
(
source
)
names
=
source
.
public_methods
Registry
.
instance_methods
Module
.
methods
names
-=
[
:initialize
]
# for compatibility with Rubinius
names
+=
source
.
store
.
methods
.
keys
if
source
.
is_a?
Registry
import_methods
(
source
,
names
)
end

Creates new immutable collection from the current one,
 updated with all singleton methods and imported methods
 from the other module

 @param [Module] source The module to import procedures from

 @return [Transproc::Store]

Creates new immutable collection from the current one updated with all singleton methods and imported methods from the other module


def [](fn, *args)
      fetched = fetch(fn)

      return Function.new(fetched, args: args, name: fn) unless already_wrapped?(fetched)
      args.empty? ? fetched : fetched.with(*args)
    end

def [] ( fn , * args ) fetched = fetch ( fn ) return Function . new ( fetched , args : args , name : fn ) unless already_wrapped? ( fetched ) args . empty? ? fetched : fetched . with ( args ) end

Builds the transformation

 @param [Proc, Symbol] fn
   A proc, a name of the module's own function, or a name of imported
   procedure from another module
 @param [Object, Array] args
   Args to be carried by the transproc

 @return [Transproc::Function]

 @alias :t


def fetch(fn)
      return fn unless fn.instance_of? Symbol
      respond_to?(fn) ? method(fn) : store.fetch(fn)
    rescue
      raise FunctionNotFoundError.new(fn, self)
    end

def fetch ( fn ) return fn unless fn . instance_of? Symbol respond_to? ( fn ) ? method ( fn ) : store . fetch ( fn ) rescue raise FunctionNotFoundError . new ( fn , self ) end

Gets the procedure for creating a transproc

 @param [#call, Symbol] fn
   Either the procedure, or the name of the method of the current module,
   or the registered key of imported procedure in a store.

 @return [#call]


def to_ast
      args_ast = args.map { |arg| arg.respond_to?(:to_ast) ? arg.to_ast : arg }
      [name, args_ast]
    end

def to_ast args_ast = args . map { | arg | arg . respond_to? ( :to_ast ) ? arg . to_ast : arg } [ name , args_ast ] end

Return a simple AST representation of this function

 @return [Array]

 @api public


def to_proc
      if args.size > 0
        proc { |*value| fn.call(*value, *args) }
      else
        fn.to_proc
      end
    end

def to_proc if args . size > 0 proc { | * value | fn . call ( value , args ) } else fn . to_proc end end

Converts a transproc to a simple proc

 @return [Proc]


def from_pattern_match(keys, pattern, match)
      keys.each_with_index.map do |key, idx|
        # Check if there is any replacement specified
        if pattern[key]
          interpolate(pattern[key], match)
        else
          # No replacement defined, just return correct match group
          match[idx + 1]
        end
      end
    end


def interpolate(replacement, match)
      group_idx = replacement.index('$')
      return replacement if group_idx.nil?

      group_nbr = replacement[group_idx + 1]
      replacement.sub("$#{group_nbr}", match[group_nbr.to_i])
    end

def interpolate ( replacement , match ) group_idx = replacement . index ( '$' ) return replacement if group_idx . nil? group_nbr = replacement [ group_idx + 1 ] replacement . sub ( "$#{group_nbr}" , match [ group_nbr . to_i ] ) end

Interpolates a string with data from matches if specified


def before(*commands, &block)
      context = (@_context[:before] ||= [])
      block_given? ? run_context(context, &block) : context.concat(commands)
    end

def before ( * commands , & block ) context = ( @_context [ :before ] ||= [ ] ) block_given? ? run_context ( context , block ) : context . concat ( commands ) end

Run commands prior to each tab context.

 @param [Array<String>] commands
   Commands to be executed.
 @param [Proc] block
   Proc of commands to run

 @example
   # Executes `whoami` before tab with `ls` and `gitx`
   window do
     before { run 'whoami' }
     tab 'ls'
     tab 'gitx'
   end

 @api public

Run commands prior to each tab context .


def window(*args, &block)
      key            = "window#{@_windows.keys.size}"
      options        = args.extract_options!
      options[:name] = args.first unless args.empty?
      context = (@_windows[key] = window_hash.merge(:options => options))
      run_context context, &block
    end

def window ( * args , & block ) key = "window#{@_windows.keys.size}" options = args . extract_options! options [ :name ] = args . first unless args . empty? context = ( @_windows [ key ] = window_hash . merge ( :options => options ) ) run_context context , block end

Run commands in the conext of a window.

 @param [Array] args
   Hash to pass options to each context of a window. Each core can
   implement the desired behavior for the window based on the options set here.
   Can also pass a string as first parameter which will be set as
   the :name
 @param [Proc] block
   block of commands to run in window context.

 @example
   window 'my project', :size => [80, 30] do
     run 'ps aux'
   end

 @api public

Run commands in the conext of a window .


def tab(*args, &block)
      tabs = @_context[:tabs]
      key  = "tab#{tabs.keys.size}"
      return (tabs[key] = { :commands => args }) unless block_given?

      context           = (tabs[key] = {:commands => []})
      options           = args.extract_options!
      options[:name]    = args.first unless args.empty?
      context[:options] = options

      run_context context, &block
      @_context = @_windows[@_windows.keys.last] # Jump back out into the context of the last window.
    end

Run commands in the context of a tab.

 @param [Array] args
   Accepts either:
     - an array of string commands
     - a hash containing options for the tab.
 @param [Proc] block

 @example
   tab 'first tab', :settings => 'Grass' do
     run 'ps aux'
   end

   tab 'ls', 'gitx'

 @api public


def run(*commands)
      context = case
                when @_context.is_a?(Hash) && @_context[:tabs]
                  @_context[:tabs]['default'][:commands]
                when @_context.is_a?(Hash)
                  @_context[:commands]
                else
                  @_context
                end
      context << commands.map { |c| c =~ /&$/ ? "(#{c})" : c }.join(" && ")
    end

def
run
(
*
commands
)
context
=
case
when
@_context
.
is_a?
(
Hash
)
&&
@_context
[
:tabs
]
@_context
[
:tabs
]
[
'default'
]
[
:commands
]
when
@_context
.
is_a?
(
Hash
)
@_context
[
:commands
]
else
@_context
end
context
<<
commands
.
map
{
|
c
|
c
=~
/
/
"(#{c})"
:
c
}
.
join
(
" && "
)
end

Store commands to run in context.

 @param [Array<String>] commands
   Array of commands to be executed.

 @example
   run 'brew update', 'gitx'

 @api public


def set_write(policy, operation, key, bins)
      begin_cmd
      field_count = estimate_key_size(key, policy)

      bins.each do |bin|
        estimate_operation_size_for_bin(bin)
      end

      size_buffer

      write_header_with_policy(policy, 0, INFO2_WRITE, field_count, bins.length)
      write_key(key, policy)

      bins.each do |bin|
        write_operation_for_bin(bin, operation)
      end

      end_cmd
    end

def set_write ( policy , operation , key , bins ) begin_cmd field_count = estimate_key_size ( key , policy ) bins . each do | bin | estimate_operation_size_for_bin ( bin ) end size_buffer write_header_with_policy ( policy , 0 , INFO2_WRITE , field_count , bins . length ) write_key ( key , policy ) bins . each do | bin | write_operation_for_bin ( bin , operation ) end end_cmd end


def set_delete(policy, key)
      begin_cmd
      field_count = estimate_key_size(key)
      size_buffer
      write_header_with_policy(policy, 0, INFO2_WRITE|INFO2_DELETE, field_count, 0)
      write_key(key)
      end_cmd
    end

Writes the command for delete operations


def set_touch(policy, key)
      begin_cmd
      field_count = estimate_key_size(key)
      estimate_operation_size
      size_buffer
      write_header_with_policy(policy, 0, INFO2_WRITE, field_count, 1)
      write_key(key)
      write_operation_for_operation_type(Aerospike::Operation::TOUCH)
      end_cmd
    end

def set_touch ( policy , key ) begin_cmd field_count = estimate_key_size ( key ) estimate_operation_size size_buffer write_header_with_policy ( policy , 0 , INFO2_WRITE , field_count , 1 ) write_key ( key ) write_operation_for_operation_type ( Aerospike :: Operation :: TOUCH ) end_cmd end


def set_exists(policy, key)
      begin_cmd
      field_count = estimate_key_size(key)
      size_buffer
      write_header(policy, INFO1_READ|INFO1_NOBINDATA, 0, field_count, 0)
      write_key(key)
      end_cmd
    end


def set_read_header(policy, key)
      begin_cmd
      field_count = estimate_key_size(key)
      estimate_operation_size_for_bin_name('')
      size_buffer

      # The server does not currently return record header data with _INFO1_NOBINDATA attribute set.
      # The workaround is to request a non-existent bin.
      # TODO: Fix this on server.
      #command.set_read(INFO1_READ | _INFO1_NOBINDATA);
      write_header(policy, INFO1_READ, 0, field_count, 1)

      write_key(key)
      write_operation_for_bin_name('', Aerospike::Operation::READ)
      end_cmd
    end

Writes the command for getting metadata operations


def set_operate(policy, key, operations)
      begin_cmd
      field_count = estimate_key_size(key, policy)
      read_attr = 0
      write_attr = 0
      read_header = false

      operations.each do |operation|
        case operation.op_type
        when Aerospike::Operation::READ
            read_attr |= INFO1_READ

          # Read all bins if no bin is specified.
          read_attr |= INFO1_GET_ALL unless operation.bin_name

        when Aerospike::Operation::READ_HEADER
            # The server does not currently return record header data with _INFO1_NOBINDATA attribute set.
            # The workaround is to request a non-existent bin.
            # TODO: Fix this on server.
            # read_attr |= _INFO1_READ | _INFO1_NOBINDATA
            read_attr |= INFO1_READ
          read_header = true

        else
          write_attr = INFO2_WRITE
        end

        estimate_operation_size_for_operation(operation)
      end
      size_buffer

      if write_attr != 0
        write_header_with_policy(policy, read_attr, write_attr, field_count, operations.length)
      else
        write_header(policy, read_attr, write_attr, field_count, operations.length)
      end
      write_key(key, policy)

      operations.each do |operation|
        write_operation_for_operation(operation)
      end

      write_operation_for_bin(nil, Aerospike::Operation::READ) if read_header

      end_cmd
    end


def write_header(policy, read_attr, write_attr, field_count, operation_count)
      read_attr |= INFO1_CONSISTENCY_ALL if policy.consistency_level == Aerospike::ConsistencyLevel::CONSISTENCY_ALL

      # Write all header data except total size which must be written last.
      @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message heade.length.
      @data_buffer.write_byte(read_attr, 9)
      @data_buffer.write_byte(write_attr, 10)

      i = 11
      while i <= 25
        @data_buffer.write_byte(0, i)
        i = i.succ
      end

      @data_buffer.write_int16(field_count, 26)
      @data_buffer.write_int16(operation_count, 28)

      @data_offset = MSG_TOTAL_HEADER_SIZE
    end


def write_header_with_policy(policy, read_attr, write_attr, field_count, operation_count)
      # Set flags.
      generation = Integer(0)
      info_attr = Integer(0)

      case policy.record_exists_action
      when Aerospike::RecordExistsAction::UPDATE
      when Aerospike::RecordExistsAction::UPDATE_ONLY
        info_attr |= INFO3_UPDATE_ONLY
      when Aerospike::RecordExistsAction::REPLACE
        info_attr |= INFO3_CREATE_OR_REPLACE
      when Aerospike::RecordExistsAction::REPLACE_ONLY
        info_attr |= INFO3_REPLACE_ONLY
      when Aerospike::RecordExistsAction::CREATE_ONLY
        write_attr |= INFO2_CREATE_ONLY
      end

      case policy.generation_policy
      when Aerospike::GenerationPolicy::NONE
      when Aerospike::GenerationPolicy::EXPECT_GEN_EQUAL
        generation = policy.generation
        write_attr |= INFO2_GENERATION
      when Aerospike::GenerationPolicy::EXPECT_GEN_GT
        generation = policy.generation
        write_attr |= INFO2_GENERATION_GT
      end

      info_attr |= INFO3_COMMIT_MASTER if policy.commit_level == Aerospike::CommitLevel::COMMIT_MASTER
      read_attr |= INFO1_CONSISTENCY_ALL if policy.consistency_level == Aerospike::ConsistencyLevel::CONSISTENCY_ALL
      write_attr |= INFO2_DURABLE_DELETE if policy.durable_delete

      # Write all header data except total size which must be written last.
      @data_buffer.write_byte(MSG_REMAINING_HEADER_SIZE, 8) # Message heade.length.
      @data_buffer.write_byte(read_attr, 9)
      @data_buffer.write_byte(write_attr, 10)
      @data_buffer.write_byte(info_attr, 11)
      @data_buffer.write_byte(0, 12) # unused
      @data_buffer.write_byte(0, 13) # clear the result code
      @data_buffer.write_uint32(generation, 14)
      @data_buffer.write_uint32(policy.ttl, 18)

      # Initialize timeout. It will be written later.
      @data_buffer.write_byte(0, 22)
      @data_buffer.write_byte(0, 23)
      @data_buffer.write_byte(0, 24)
      @data_buffer.write_byte(0, 25)

      @data_buffer.write_int16(field_count, 26)
      @data_buffer.write_int16(operation_count, 28)

      @data_offset = MSG_TOTAL_HEADER_SIZE
    end


def all_nodes_done?

      if @scan
        command = 'scan-list'
      else
        command = 'query-list'
      end

      nodes = @cluster.nodes
      done = false

      nodes.each do |node|
        conn = node.get_connection(0)
        responseMap, _ = Info.request(conn, command)
        node.put_connection(conn)

        response = responseMap[command]
        find = "job_id=#{@task_id}:"
        index = response.index(find)

        unless index
          # don't return on first check
          done = true
          next
        end

        b = index + find.length
        response = response[b, response.length]
        find = 'job_status='
        index = response.index(find)

        next unless index

        b = index + find.length
        response = response[b, response.length]
        e = response.index(':')
        status = response[0, e]

        case status
        when 'ABORTED'
          raise raise Aerospike::Exceptions::QueryTerminated
        when 'IN PROGRESS'
          return false
        when 'DONE'
          done = true
        end
      end

      done
    end

def
all_nodes_done?
if
@scan
command
=
'scan-list'
else
command
=
'query-list'
end
nodes
=
@cluster
.
nodes
done
=
false
nodes
.
each
do
|
node
|
conn
=
node
.
get_connection
(
0
)
responseMap
,
_
=
Info
.
request
(
conn
,
command
)
node
.
put_connection
(
conn
)
response
=
responseMap
[
command
]
find
=
"job_id=#{@task_id}:"
index
=
response
.
index
(
find
)
unless
index
# don't return on first check
done
=
true
next
end
b
=
index
+
find
.
length
response
=
response
[
b
,
response
.
length
]
find
=
'job_status='
index
=
response
.
index
(
find
)
next
unless
index
b
=
index
+
find
.
length
response
=
response
[
b
,
response
.
length
]
e
=
response
.
index
(
':'
)
status
=
response
[
0
,
e
]
case
status
when
'ABORTED'
raise
raise
Aerospike
::
Exceptions
::
QueryTerminated
when
'IN PROGRESS'
return
false
when
'DONE'
done
=
true
end
end
done
end

NewExecuteTask initializes task with fields needed to query server nodes.
 IsDone queries all nodes for task completion status.

NewExecuteTask initializes task with fields needed to query server nodes . IsDone queries all nodes for task completion status .


def get_connection(timeout)
      loop do
        conn = @connections.poll
        if conn.connected?
          conn.timeout = timeout.to_f
          return conn
        end
      end
    end

def get_connection ( timeout ) loop do conn = @connections . poll if conn . connected? conn . timeout = timeout . to_f return conn end end end

Initialize server node with connection parameters.
 Get a connection to the node. If no cached connection is not available,
 a new connection will be created

Initialize server node with connection parameters . Get a connection to the node . If no cached connection is not available a new connection will be created


def parse_record(key, op_count, generation, expiration)
      bins = op_count > 0 ? {} : nil
      i = 0
      while i < op_count
        raise Aerospike::Exceptions::QueryTerminated.new unless valid?

        read_bytes(8)

        op_size = @data_buffer.read_int32(0).ord
        particle_type = @data_buffer.read(5).ord
        name_size = @data_buffer.read(7).ord

        read_bytes(name_size)
        name = @data_buffer.read(0, name_size).force_encoding('utf-8')

        particle_bytes_size = op_size - (4 + name_size)
        read_bytes(particle_bytes_size)
        value = Aerospike.bytes_to_particle(particle_type, @data_buffer, 0, particle_bytes_size)

        bins[name] = value

        i = i.succ
      end

      Record.new(@node, key, bins, generation, expiration)
    end

def parse_record ( key , op_count , generation , expiration ) bins = op_count > 0 ? { } : nil i = 0 while i < op_count raise Aerospike :: Exceptions :: QueryTerminated . new unless valid? read_bytes ( 8 ) op_size = @data_buffer . read_int32 ( 0 ) . ord particle_type = @data_buffer . read ( 5 ) . ord name_size = @data_buffer . read ( 7 ) . ord read_bytes ( name_size ) name = @data_buffer . read ( 0 , name_size ) . force_encoding ( 'utf-8' ) particle_bytes_size = op_size - ( 4 + name_size ) read_bytes ( particle_bytes_size ) value = Aerospike . bytes_to_particle ( particle_type , @data_buffer , 0 , particle_bytes_size ) bins [ name ] = value i = i . succ end Record . new ( @node , key , bins , generation , expiration ) end

Parses the given byte buffer and populate the result object.
 Returns the number of bytes that were parsed from the given buffer.

Parses the given byte buffer and populate the result object . Returns the number of bytes that were parsed from the given buffer .


def random_node
      # Must copy array reference for copy on write semantics to work.
      node_array = nodes
      length = node_array.length
      i = 0
      while i < length
        # Must handle concurrency with other non-tending threads, so node_index is consistent.
        index = (@node_index.update{ |v| v+1 } % node_array.length).abs
        node = node_array[index]

        return node if node.active?

        i = i.succ
      end
      raise Aerospike::Exceptions::InvalidNode
    end


def get_node_by_name(node_name)
      node = find_node_by_name(node_name)

      raise Aerospike::Exceptions::InvalidNode unless node

      node
    end

def get_node_by_name ( node_name ) node = find_node_by_name ( node_name ) raise Aerospike :: Exceptions :: InvalidNode unless node node end

Find a node by name and returns an error if not found


def prepend(key, bins, options = nil)
      policy = create_policy(options, WritePolicy, default_write_policy)
      command = WriteCommand.new(@cluster, policy, key, hash_to_bins(bins), Aerospike::Operation::PREPEND)
      execute_command(command)
    end

def prepend ( key , bins , options = nil ) policy = create_policy ( options , WritePolicy , default_write_policy ) command = WriteCommand . new ( @cluster , policy , key , hash_to_bins ( bins ) , Aerospike :: Operation :: PREPEND ) execute_command ( command ) end

Prepends bin values string to existing record bin values.
  The policy specifies the transaction timeout, record expiration and
  how the transaction is handled when the record already exists.

  This call works only for string values.

  If no policy options are provided, +@default_write_policy+ will be used.
  Examples:

  client.prepend key, {'bin', 'value to prepend'}, :timeout => 0.001

Prepends bin values string to existing record bin values . The policy specifies the transaction timeout record expiration and how the transaction is handled when the record already exists .


def get_header(key, options = nil)
      policy = create_policy(options, Policy, default_read_policy)
      command = ReadHeaderCommand.new(@cluster, policy, key)
      execute_command(command)
      command.record
    end

def get_header ( key , options = nil ) policy = create_policy ( options , Policy , default_read_policy ) command = ReadHeaderCommand . new ( @cluster , policy , key ) execute_command ( command ) command . record end

Read record generation and expiration only for specified key.  Bins are not read.
  The policy can be used to specify timeouts.

Read record generation and expiration only for specified key . Bins are not read . The policy can be used to specify timeouts .


def batch_exists(keys, options = nil)
      policy = create_policy(options, BatchPolicy, default_batch_policy)
      results = Array.new(keys.length)

      if policy.use_batch_direct
        key_map = BatchItem.generate_map(keys)
        execute_batch_direct_commands(keys) do |node, batch|
          BatchDirectExistsCommand.new(node, batch, policy, key_map, results)
        end
      else
        execute_batch_index_commands(keys) do |node, batch|
          BatchIndexExistsCommand.new(node, batch, policy, results)
        end
      end

      results
    end

def batch_exists ( keys , options = nil ) policy = create_policy ( options , BatchPolicy , default_batch_policy ) results = Array . new ( keys . length ) if policy . use_batch_direct key_map = BatchItem . generate_map ( keys ) execute_batch_direct_commands ( keys ) do | node , batch | BatchDirectExistsCommand . new ( node , batch , policy , key_map , results ) end else execute_batch_index_commands ( keys ) do | node , batch | BatchIndexExistsCommand . new ( node , batch , policy , results ) end end results end

Check if multiple record keys exist in one batch call.
  The returned boolean array is in positional order with the original key array order.
  The policy can be used to specify timeouts and protocol type.

Check if multiple record keys exist in one batch call . The returned boolean array is in positional order with the original key array order . The policy can be used to specify timeouts and protocol type .


def register_udf(udf_body, server_path, language, options = nil)
      policy = create_policy(options, Policy, default_info_policy)

      content = Base64.strict_encode64(udf_body).force_encoding('binary')
      str_cmd = "udf-put:filename=#{server_path};content=#{content};"
      str_cmd << "content-len=#{content.length};udf-type=#{language};"

      # Send UDF to one node. That node will distribute the UDF to other nodes.
      response_map = @cluster.request_info(policy, str_cmd)

      res = {}
      response_map.each do |k, response|
        vals = response.to_s.split(';')
        vals.each do |pair|
          k, v = pair.split("=", 2)
          res[k] = v
        end
      end

      if res['error']
        raise Aerospike::Exceptions::CommandRejected.new("Registration failed: #{res['error']}\nFile: #{res['file']}\nLine: #{res['line']}\nMessage: #{res['message']}")
      end

      UdfRegisterTask.new(@cluster, server_path)
    end

Register package containing user defined functions with server.
  This asynchronous server call will return before command is complete.
  The user can optionally wait for command completion by using the returned
  RegisterTask instance.

  This method is only supported by Aerospike 3 servers.

Register package containing user defined functions with server . This asynchronous server call will return before command is complete . The user can optionally wait for command completion by using the returned RegisterTask instance .


def remove_udf(udf_name, options = nil)
      policy = create_policy(options, Policy, default_info_policy)

      str_cmd = "udf-remove:filename=#{udf_name};"

      # Send command to one node. That node will distribute it to other nodes.
      # Send UDF to one node. That node will distribute the UDF to other nodes.
      response_map = @cluster.request_info(policy, str_cmd)
      _, response = response_map.first

      if response == 'ok'
        UdfRemoveTask.new(@cluster, udf_name)
      else
        raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::SERVER_ERROR, response)
      end
    end

RemoveUDF removes a package containing user defined functions in the server.
  This asynchronous server call will return before command is complete.
  The user can optionally wait for command completion by using the returned
  RemoveTask instance.

  This method is only supported by Aerospike 3 servers.

RemoveUDF removes a package containing user defined functions in the server . This asynchronous server call will return before command is complete . The user can optionally wait for command completion by using the returned RemoveTask instance .


def list_udf(options = nil)
      policy = create_policy(options, Policy, default_info_policy)

      str_cmd = 'udf-list'

      # Send command to one node. That node will distribute it to other nodes.
      response_map = @cluster.request_info(policy, str_cmd)
      _, response = response_map.first

      vals = response.split(';')

      vals.map do |udf_info|
        next if udf_info.strip! == ''

        udf_parts = udf_info.split(',')
        udf = UDF.new
        udf_parts.each do |values|
          k, v = values.split('=', 2)
          case k
          when 'filename'
            udf.filename = v
          when 'hash'
            udf.hash = v
          when 'type'
            udf.language = v
          end
        end
        udf
      end
    end

ListUDF lists all packages containing user defined functions in the server.
  This method is only supported by Aerospike 3 servers.

ListUDF lists all packages containing user defined functions in the server . This method is only supported by Aerospike 3 servers .


def execute_udf_on_query(statement, package_name, function_name, function_args=[], options = nil)
      policy = create_policy(options, QueryPolicy, default_query_policy)

      nodes = @cluster.nodes
      if nodes.empty?
        raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::SERVER_NOT_AVAILABLE, "Executing UDF failed because cluster is empty.")
      end

      # TODO: wait until all migrations are finished
      statement.set_aggregate_function(package_name, function_name, function_args, false)

      # Use a thread per node
      nodes.each do |node|
        Thread.new do
          Thread.current.abort_on_exception = true
          begin
            command = QueryCommand.new(node, policy, statement, nil)
            execute_command(command)
          rescue => e
            Aerospike.logger.error(e)
            raise e
          end
        end
      end

      ExecuteTask.new(@cluster, statement)
    end

execute_udf_on_query applies user defined function on records that match the statement filter.
 Records are not returned to the client.
 This asynchronous server call will return before command is complete.
 The user can optionally wait for command completion by using the returned
 ExecuteTask instance.

 This method is only supported by Aerospike 3 servers.
 If the policy is nil, the default relevant policy will be used.

execute_udf_on_query applies user defined function on records that match the statement filter . Records are not returned to the client . This asynchronous server call will return before command is complete . The user can optionally wait for command completion by using the returned ExecuteTask instance .


def create_index(namespace, set_name, index_name, bin_name, index_type, collection_type = nil, options = nil)
      if options.nil? && collection_type.is_a?(Hash)
        options, collection_type = collection_type, nil
      end
      policy = create_policy(options, Policy, default_info_policy)

      str_cmd = "sindex-create:ns=#{namespace}"
      str_cmd << ";set=#{set_name}" unless set_name.to_s.strip.empty?
      str_cmd << ";indexname=#{index_name};numbins=1"
      str_cmd << ";indextype=#{collection_type.to_s.upcase}" if collection_type
      str_cmd << ";indexdata=#{bin_name},#{index_type.to_s.upcase}"
      str_cmd << ";priority=normal"

      # Send index command to one node. That node will distribute the command to other nodes.
      response = send_info_command(policy, str_cmd).upcase
      if response == 'OK'
        # Return task that could optionally be polled for completion.
        return IndexTask.new(@cluster, namespace, index_name)
      end

      if response.start_with?('FAIL:200')
        # Index has already been created.  Do not need to poll for completion.
        return IndexTask.new(@cluster, namespace, index_name, true)
      end

      raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::INDEX_GENERIC, "Create index failed: #{response}")
    end

Create secondary index.
  This asynchronous server call will return before command is complete.
  The user can optionally wait for command completion by using the returned
  IndexTask instance.

  This method is only supported by Aerospike 3 servers.
  index_type should be :string, :numeric or :geo2dsphere (requires server version 3.7 or later)
  collection_type should be :list, :mapkeys or :mapvalues

Create secondary index . This asynchronous server call will return before command is complete . The user can optionally wait for command completion by using the returned IndexTask instance .


def drop_index(namespace, set_name, index_name, options = nil)
      policy = create_policy(options, Policy, default_info_policy)

      str_cmd = "sindex-delete:ns=#{namespace}"
      str_cmd << ";set=#{set_name}" unless set_name.to_s.strip.empty?
      str_cmd << ";indexname=#{index_name}"

      # Send index command to one node. That node will distribute the command to other nodes.
      response = send_info_command(policy, str_cmd).upcase
      return if response == 'OK'

      # Index did not previously exist. Return without error.
      return if response.start_with?('FAIL:201')

      raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::INDEX_GENERIC, "Drop index failed: #{response}")
    end

Delete secondary index.
  This method is only supported by Aerospike 3 servers.

Delete secondary index . This method is only supported by Aerospike 3 servers .


def scan_node(node, namespace, set_name, bin_names = nil, options = nil)
      policy = create_policy(options, ScanPolicy, default_scan_policy)
      # wait until all migrations are finished
      # TODO: implement
      # @cluster.WaitUntillMigrationIsFinished(policy.timeout)

      # Retry policy must be one-shot for scans.
      # copy on write for policy
      new_policy = policy.clone
      new_policy.max_retries = 0

      node = @cluster.get_node_by_name(node) unless node.is_a?(Aerospike::Node)

      recordset = Recordset.new(policy.record_queue_size, 1, :scan)

      Thread.new do
        Thread.current.abort_on_exception = true
        command = ScanCommand.new(node, new_policy, namespace, set_name, bin_names, recordset)
        begin
          execute_command(command)
        rescue => e
          Aerospike.logger.error(e.backtrace.join("\n")) unless e == SCAN_TERMINATED_EXCEPTION
          recordset.cancel(e)
        ensure
          recordset.thread_finished
        end
      end

      recordset
    end

ScanNode reads all records in specified namespace and set, from one node only.
 The policy can be used to specify timeouts.

ScanNode reads all records in specified namespace and set from one node only . The policy can be used to specify timeouts .


def drop_user(user, options = nil)
      policy = create_policy(options, AdminPolicy, default_admin_policy)
      command = AdminCommand.new
      command.drop_user(@cluster, policy, user)
    end

def drop_user ( user , options = nil ) policy = create_policy ( options , AdminPolicy , default_admin_policy ) command = AdminCommand . new command . drop_user ( @cluster , policy , user ) end


def change_password(user, password, options = nil)
      raise Aerospike::Exceptions::Aerospike.new(INVALID_USER) unless @cluster.user && @cluster.user != ""
      policy = create_policy(options, AdminPolicy, default_admin_policy)

      hash = AdminCommand.hash_password(password)
      command = AdminCommand.new

      if user == @cluster.user
        # Change own password.
        command.change_password(@cluster, policy, user, hash)
      else
        # Change other user's password by user admin.
        command.set_password(@cluster, policy, user, hash)
      end

      @cluster.change_password(user, hash)
    end

Change user's password. Clear-text password will be hashed using bcrypt before sending to server.

Change user s password . Clear - text password will be hashed using bcrypt before sending to server .


def grant_roles(user, roles, options = nil)
      policy = create_policy(options, AdminPolicy, default_admin_policy)
      command = AdminCommand.new
      command.grant_roles(@cluster, policy, user, roles)
    end

def grant_roles ( user , roles , options = nil ) policy = create_policy ( options , AdminPolicy , default_admin_policy ) command = AdminCommand . new command . grant_roles ( @cluster , policy , user , roles ) end


def query_users(options = nil)
      policy = create_policy(options, AdminPolicy, default_admin_policy)
      command = AdminCommand.new
      command.query_users(@cluster, policy)
    end

def query_users ( options = nil ) policy = create_policy ( options , AdminPolicy , default_admin_policy ) command = AdminCommand . new command . query_users ( @cluster , policy ) end


def next_record
      raise @thread_exception.get unless @thread_exception.get.nil?

      r = @records.deq

      set_exception if r.nil?

      r
    end

def next_record raise @thread_exception . get unless @thread_exception . get . nil? r = @records . deq set_exception if r . nil? r end

fetches and return the first record from the queue
 if the operation is not finished and the queue is empty it blocks and waits for new records
 it sets the exception if it reaches the EOF mark, and returns nil
 EOF means the operation has finished and no more records are comming from server nodes
 it re-raises the exception occurred in threads, or which was set after reaching the EOF in the previous call

fetches and return the first record from the queue if the operation is not finished and the queue is empty it blocks and waits for new records it sets the exception if it reaches the EOF mark and returns nil EOF means the operation has finished and no more records are comming from server nodes it re - raises the exception occurred in threads or which was set after reaching the EOF in the previous call


def each(&block)
      r = true
      while r
        r = next_record
        # nil means EOF
        unless r.nil?
          block.call(r)
        else
          # reached the EOF
          break
        end
      end
    end

def
each
(
&
block
)
r
=
true
while
r
r
=
next_record
# nil means EOF
unless
r
.
nil?
block
.
call
(
r
)
else
# reached the EOF
break
end
end
end

fetches and returns all the records from the queue until the whole operation is finished and it reaches an EOF mark
 calling cancel inside the each block raises an exception to signal other consumer threads


def intercom_script_tag(user_details = nil, options={})
      controller.instance_variable_set(IntercomRails::SCRIPT_TAG_HELPER_CALLED_INSTANCE_VARIABLE, true) if defined?(controller)
      options[:user_details] = user_details if user_details.present?
      options[:find_current_user_details] = !options[:user_details]
      options[:find_current_company_details] = !(options[:user_details] && options[:user_details][:company])
      options[:controller] = controller if defined?(controller)
      ScriptTag.new(options)
    end

Generate an intercom script tag.

 @param user_details [Hash] a customizable hash of user details
 @param options [Hash] an optional hash for Identity Verification and widget customization
 @option user_details [String] :app_id Your application id
 @option user_details [String] :user_id unique id of this user within your application
 @option user_details [String] :email email address for this user
 @option user_details [String] :name the users name, _optional_ but useful for identify people in the Intercom App.
 @option user_details [Hash] :custom_data custom attributes you'd like saved for this user on Intercom.
 @option options [String] :widget a hash containing a css selector for an element which when clicked should show the Intercom widget
 @option options [String] :secret Your app secret for Identity Verification
 @option options [String] :nonce a nonce generated by your CSP framework to be included inside the javascript tag
 @return [String] Intercom script tag
 @example basic example
   <%= intercom_script_tag({ :app_id => "your-app-id",
                             :user_id => current_user.id,
                             :email => current_user.email,
                             :custom_data => { :plan => current_user.plan.name },
                             :name => current_user.name }) %>
 @example with widget activator for launching then widget when an element matching the css selector '#Intercom' is clicked.
   <%= intercom_script_tag({ :app_id => "your-app-id",
                             :user_id => current_user.id,
                             :email => current_user.email,
                             :custom_data => { :plan => current_user.plan.name },
                             :name => current_user.name },
                             {:widget => {:activator => "#Intercom"}},) %>


def move_free(aim, speed)
      if aim.is_a? Vector
        x_d = aim.x - @x; y_d = aim.y - @y
        distance = Math.sqrt(x_d**2 + y_d**2)

        if distance == 0
          @speed.x = @speed.y = 0
          return
        end

        @speed.x = 1.0 * x_d * speed / distance
        @speed.y = 1.0 * y_d * speed / distance

        if (@speed.x < 0 and @x + @speed.x <= aim.x) or (@speed.x >= 0 and @x + @speed.x >= aim.x)
          @x = aim.x
          @speed.x = 0
        else
          @x += @speed.x
        end

        if (@speed.y < 0 and @y + @speed.y <= aim.y) or (@speed.y >= 0 and @y + @speed.y >= aim.y)
          @y = aim.y
          @speed.y = 0
        else
          @y += @speed.y
        end
      else
        rads = aim * Math::PI / 180
        @speed.x = speed * Math.cos(rads)
        @speed.y = speed * Math.sin(rads)
        @x += @speed.x
        @y += @speed.y
      end
    end

def move_free ( aim , speed ) if aim . is_a? Vector x_d = aim . x - @x ; y_d = aim . y - @y distance = Math . sqrt ( x_d ** 2 + y_d ** 2 ) if distance == 0 @speed . x = @speed . y = 0 return end @speed . x = 1.0 * x_d * speed / distance @speed . y = 1.0 * y_d * speed / distance if ( @speed . x < 0 and @x + @speed . x <= aim . x ) or ( @speed . x >= 0 and @x + @speed . x >= aim . x ) @x = aim . x @speed . x = 0 else @x += @speed . x end if ( @speed . y < 0 and @y + @speed . y <= aim . y ) or ( @speed . y >= 0 and @y + @speed . y >= aim . y ) @y = aim . y @speed . y = 0 else @y += @speed . y end else rads = aim * Math :: PI / 180 @speed . x = speed * Math . cos ( rads ) @speed . y = speed * Math . sin ( rads ) @x += @speed . x @y += @speed . y end end

Moves this object, without performing any collision checking, towards
 a specified point or in a specified direction.

 Parameters:
 [aim] A +Vector+ specifying where the object will move to or an angle (in
       degrees) indicating the direction of the movement. Angles are
       measured starting from the right (i.e., to move to the right, the
       angle must be 0) and raising clockwise.
 [speed] The constant speed at which the object will move. This must be
         provided as a scalar, not a vector.

Moves this object without performing any collision checking towards a specified point or in a specified direction .


def get_absolute_size
      return Vector.new(@tile_size.x * @size.x, @tile_size.y * @size.y) unless @isometric
      avg = (@size.x + @size.y) * 0.5
      Vector.new (avg * @tile_size.x).to_i, (avg * @tile_size.y).to_i
    end

def get_absolute_size return Vector . new ( @tile_size . x * @size . x , @tile_size . y * @size . y ) unless @isometric avg = ( @size . x + @size . y ) * 0.5 Vector . new ( avg * @tile_size . x ) . to_i , ( avg * @tile_size . y ) . to_i end

Creates a new map.

 Parameters:
 [t_w] The width of the tiles.
 [t_h] The height of the tiles.
 [t_x_count] The horizontal count of tiles in the map.
 [t_y_count] The vertical count of tiles in the map.
 [scr_w] Width of the viewport for the map.
 [scr_h] Height of the viewport for the map.
 [isometric] Whether to use a isometric map. By default, an ortogonal map
             is used.
 [limit_cam] Whether the camera should respect the bounds of the map
             (i.e., when given coordinates that would imply regions
             outside the map to appear in the screen, the camera would
             move to the nearest position where only the map shows up
             in the screen).
 Returns a Vector with the total size of the map, in pixels (x for the
 width and y for the height).


def get_screen_pos(map_x, map_y)
      return Vector.new(map_x * @tile_size.x - @cam.x, map_y * @tile_size.y - @cam.y) unless @isometric
      Vector.new ((map_x - map_y - 1) * @tile_size.x * 0.5) - @cam.x + @x_offset,
                 ((map_x + map_y) * @tile_size.y * 0.5) - @cam.y
    end

def get_screen_pos ( map_x , map_y ) return Vector . new ( map_x * @tile_size . x - @cam . x , map_y * @tile_size . y - @cam . y ) unless @isometric Vector . new ( ( map_x - map_y - 1 ) * @tile_size . x * 0.5 ) - @cam . x + @x_offset , ( ( map_x + map_y ) * @tile_size . y * 0.5 ) - @cam . y end

Returns the position in the screen corresponding to the given tile
 indices.

 Parameters:
 [map_x] The index of the tile in the horizontal direction. It must be in
         the interval 0..t_x_count.
 [map_y] The index of the tile in the vertical direction. It must be in
         the interval 0..t_y_count.

Returns the position in the screen corresponding to the given tile indices .


def get_map_pos(scr_x, scr_y)
      return Vector.new((scr_x + @cam.x) / @tile_size.x, (scr_y + @cam.y) / @tile_size.y) unless @isometric

      # Gets the position transformed to isometric coordinates
      v = get_isometric_position scr_x, scr_y

      # divides by the square size to find the position in the matrix
      Vector.new((v.x * @inverse_square_size).to_i, (v.y * @inverse_square_size).to_i)
    end

Returns the tile in the map that corresponds to the given position in
 the screen, as a Vector, where x is the horizontal index and y the
 vertical index.

 Parameters:
 [scr_x] The x-coordinate in the screen.
 [scr_y] The y-coordinate in the screen.

Returns the tile in the map that corresponds to the given position in the screen as a Vector where x is the horizontal index and y the vertical index .


def is_in_map(v)
      v.x >= 0 && v.y >= 0 && v.x < @size.x && v.y < @size.y
    end

def is_in_map ( v ) v . x >= 0 && v . y >= 0 && v . x < @size . x && v . y < @size . y end

Verifies whether a tile is inside the map.

 Parameters:
 [v] A Vector representing the tile, with x as the horizontal index and
     y as the vertical index.

Verifies whether a tile is inside the map .


def animate_once(indices, interval)
      if @animate_once_control == 2
        return if indices == @animate_once_indices && interval == @animate_once_interval
        @animate_once_control = 0
      end

      unless @animate_once_control == 1
        @anim_counter = 0
        @img_index = indices[0]
        @index_index = 0
        @animate_once_indices = indices
        @animate_once_interval = interval
        @animate_once_control = 1
        return
      end

      @anim_counter += 1
      return unless @anim_counter >= interval

      @index_index += 1
      @img_index = indices[@index_index]
      @anim_counter = 0
      @animate_once_control = 2 if @index_index == indices.length - 1
    end

Causes the sprite to animate through the +indices+ array exactly once,
 so that the animation stops once it reaches the last index in the array.
 Subsequent calls with the same parameters will have no effect, but if
 the index or interval changes, or if +set_animation+ is called, then a
 new animation cycle will begin.

 Parameters:
 [indices] The sequence of image indices used in the animation. See
           +animate+ for details.
 [interval] The amount of frames between each change in the image index.
            See +animate+ for details.

Causes the sprite to animate through the + indices + array exactly once so that the animation stops once it reaches the last index in the array . Subsequent calls with the same parameters will have no effect but if the index or interval changes or if + set_animation + is called then a new animation cycle will begin .