Update version according to OSCI-856
[packages/precise/mcollective.git] / lib / mcollective / rpc / client.rb
index 21efd74d9ca196ba73ea9704a2c44480b1f78c15..9a5fa85f2d33e6b70845d2402097a496171ec6e8 100644 (file)
@@ -5,7 +5,7 @@ module MCollective
     class Client
       attr_accessor :timeout, :verbose, :filter, :config, :progress, :ttl, :reply_to
       attr_reader :client, :stats, :ddl, :agent, :limit_targets, :limit_method, :output_format, :batch_size, :batch_sleep_time, :batch_mode
-      attr_reader :discovery_options, :discovery_method, :limit_seed
+      attr_reader :discovery_options, :discovery_method, :default_discovery_method, :limit_seed
 
       @@initial_options = nil
 
@@ -57,7 +57,13 @@ module MCollective
         @output_format = initial_options[:output_format] || :console
         @force_direct_request = false
         @reply_to = initial_options[:reply_to]
-        @discovery_method = initial_options[:discovery_method] || Config.instance.default_discovery_method
+        @discovery_method = initial_options[:discovery_method]
+        if !@discovery_method
+          @discovery_method = Config.instance.default_discovery_method
+          @default_discovery_method = true
+        else
+          @default_discovery_method = false
+        end
         @discovery_options = initial_options[:discovery_options] || []
         @force_display_mode = initial_options[:force_display_mode] || false
 
@@ -71,6 +77,8 @@ module MCollective
 
         @collective = @client.collective
         @ttl = initial_options[:ttl] || Config.instance.ttl
+        @publish_timeout = initial_options[:publish_timeout] || Config.instance.publish_timeout
+        @threaded = initial_options[:threaded] || Config.instance.threaded
 
         # if we can find a DDL for the service override
         # the timeout of the client so we always magically
@@ -367,6 +375,7 @@ module MCollective
       # since that is the user supplied timeout either via initial options
       # or via specifically setting it on the client.
       def discovery_method=(method)
+        @default_discovery_method = false
         @discovery_method = method
 
         if @initial_options[:discovery_options]
@@ -387,7 +396,7 @@ module MCollective
 
       # Sets the class filter
       def class_filter(klass)
-        @filter["cf_class"] << klass
+        @filter["cf_class"] = @filter["cf_class"] | [klass]
         @filter["cf_class"].compact!
         reset
       end
@@ -399,10 +408,10 @@ module MCollective
 
         if value.nil?
           parsed = Util.parse_fact_string(fact)
-          @filter["fact"] << parsed unless parsed == false
+          @filter["fact"] = @filter["fact"] | [parsed] unless parsed == false
         else
           parsed = Util.parse_fact_string("#{fact}#{operator}#{value}")
-          @filter["fact"] << parsed unless parsed == false
+          @filter["fact"] = @filter["fact"] | [parsed] unless parsed == false
         end
 
         @filter["fact"].compact!
@@ -411,21 +420,21 @@ module MCollective
 
       # Sets the agent filter
       def agent_filter(agent)
-        @filter["agent"] << agent
+        @filter["agent"] = @filter["agent"] | [agent]
         @filter["agent"].compact!
         reset
       end
 
       # Sets the identity filter
       def identity_filter(identity)
-        @filter["identity"] << identity
+        @filter["identity"] = @filter["identity"] | [identity]
         @filter["identity"].compact!
         reset
       end
 
       # Set a compound filter
       def compound_filter(filter)
-        @filter["compound"] <<  Matcher.create_compound_callstack(filter)
+        @filter["compound"] = @filter["compound"] |  [Matcher.create_compound_callstack(filter)]
         reset
       end
 
@@ -491,24 +500,8 @@ module MCollective
             @discovered_agents = hosts
             @force_direct_request = true
 
-          # if an identity filter is supplied and it is all strings no regex we can use that
-          # as discovery data, technically the identity filter is then redundant if we are
-          # in direct addressing mode and we could empty it out but this use case should
-          # only really be for a few -I's on the CLI
-          #
-          # For safety we leave the filter in place for now, that way we can support this
-          # enhancement also in broadcast mode.
-          #
-          # This is only needed for the 'mc' discovery method, other methods might change
-          # the concept of identity to mean something else so we should pass the full
-          # identity filter to them
-          elsif options[:filter]["identity"].size > 0 && @discovery_method == "mc"
-            regex_filters = options[:filter]["identity"].select{|i| i.match("^\/")}.size
-
-            if regex_filters == 0
-              @discovered_agents = options[:filter]["identity"].clone
-              @force_direct_request = true if Config.instance.direct_addressing
-            end
+          else
+            identity_filter_discovery_optimization
           end
         end
 
@@ -571,7 +564,9 @@ module MCollective
          :discovery_method => @discovery_method,
          :discovery_options => @discovery_options,
          :force_display_mode => @force_display_mode,
-         :config => @config}
+         :config => @config,
+         :publish_timeout => @publish_timeout,
+         :threaded => @threaded}
       end
 
       # Sets the collective we are communicating with
@@ -715,6 +710,8 @@ module MCollective
       def fire_and_forget_request(action, args, filter=nil)
         validate_request(action, args)
 
+        identity_filter_discovery_optimization
+
         req = new_request(action.to_s, args)
 
         filter = options[:filter] unless filter
@@ -722,7 +719,34 @@ module MCollective
         message = Message.new(req, nil, {:agent => @agent, :type => :request, :collective => @collective, :filter => filter, :options => options})
         message.reply_to = @reply_to if @reply_to
 
-        return @client.sendreq(message, nil)
+        if @force_direct_request || @client.discoverer.force_direct_mode?
+          message.discovered_hosts = discover.clone
+          message.type = :direct_request
+        end
+
+        client.sendreq(message, nil)
+      end
+
+      # if an identity filter is supplied and it is all strings no regex we can use that
+      # as discovery data, technically the identity filter is then redundant if we are
+      # in direct addressing mode and we could empty it out but this use case should
+      # only really be for a few -I's on the CLI
+      #
+      # For safety we leave the filter in place for now, that way we can support this
+      # enhancement also in broadcast mode.
+      #
+      # This is only needed for the 'mc' discovery method, other methods might change
+      # the concept of identity to mean something else so we should pass the full
+      # identity filter to them
+      def identity_filter_discovery_optimization
+        if options[:filter]["identity"].size > 0 && @discovery_method == "mc"
+          regex_filters = options[:filter]["identity"].select{|i| i.match("^\/")}.size
+
+          if regex_filters == 0
+            @discovered_agents = options[:filter]["identity"].clone
+            @force_direct_request = true if Config.instance.direct_addressing
+          end
+        end
       end
 
       # Calls an agent in a way very similar to call_agent but it supports batching