diff --git a/lib/syskit/actions/interface_model_extension.rb b/lib/syskit/actions/interface_model_extension.rb index 0d99e2bb6..23b692557 100644 --- a/lib/syskit/actions/interface_model_extension.rb +++ b/lib/syskit/actions/interface_model_extension.rb @@ -185,20 +185,6 @@ def use_profile_object( register_action_from_profile(definition.to_action_model) end end - - include MetaRuby::DSLs::FindThroughMethodMissing - - def has_through_method_missing?(name) - MetaRuby::DSLs.has_through_method_missing?( - profile, name, "_tag" => :has_tag? - ) || super - end - - def find_through_method_missing(name, args) - MetaRuby::DSLs.find_through_method_missing( - profile, name, args, "_tag" => :find_tag - ) || super - end end # @api private @@ -217,32 +203,44 @@ def setup_main_profile(profile) end end - Roby::Actions::Models::Library.include LibraryExtension - Roby::Actions::Interface.extend LibraryExtension - Roby::Actions::Interface.extend InterfaceModelExtension - # @api private # - # Module injected in {Roby::Actions::Interface}, i.e. instance-level methods - module InterfaceExtension - def profile - self.class.profile - end + # Definition of the delegation of the `_tag` methods to `profile` + module FindTag + HAS_THROUGH_METHOD_MISSING = { "_tag" => :has_tag? }.freeze + FIND_THROUGH_METHOD_MISSING = { "_tag" => :find_tag }.freeze def has_through_method_missing?(name) MetaRuby::DSLs.has_through_method_missing?( - profile, name, "_tag" => :has_tag? + profile, name, HAS_THROUGH_METHOD_MISSING ) || super end def find_through_method_missing(name, args) MetaRuby::DSLs.find_through_method_missing( - profile, name, args, "_tag" => :find_tag + profile, name, args, FIND_THROUGH_METHOD_MISSING ) || super end include MetaRuby::DSLs::FindThroughMethodMissing end + + # @api private + # + # Module injected in {Roby::Actions::Interface}, i.e. instance-level methods + module InterfaceExtension + def profile + self.class.profile + end + end + + Roby::Actions::Models::Library.include LibraryExtension + Roby::Actions::Models::Library.include FindTag + Roby::Actions::Interface.extend LibraryExtension + Roby::Actions::Interface.extend InterfaceModelExtension + Roby::Actions::Interface.extend FindTag + Roby::Actions::Interface.include InterfaceExtension + Roby::Actions::Interface.include FindTag end end diff --git a/lib/syskit/actions/profile.rb b/lib/syskit/actions/profile.rb index e1669460f..48a51bf7d 100644 --- a/lib/syskit/actions/profile.rb +++ b/lib/syskit/actions/profile.rb @@ -701,25 +701,31 @@ def find_device_requirements_by_name(name) end end + HAS_THROUGH_METHOD_MISSING = { + "_tag" => :has_tag?, + "_def" => :has_definition?, + "_dev" => :has_device?, + "_task" => :has_deployed_task?, + "_deployment_group" => :has_deployment_group? + }.freeze + def has_through_method_missing?(m) MetaRuby::DSLs.has_through_method_missing?( - self, m, - "_tag" => :has_tag?, - "_def" => :has_definition?, - "_dev" => :has_device?, - "_task" => :has_deployed_task?, - "_deployment_group" => :has_deployment_group? + self, m, HAS_THROUGH_METHOD_MISSING ) || super end + FIND_THROUGH_METHOD_MISSING = { + "_tag" => :find_tag, + "_def" => :find_definition_by_name, + "_dev" => :find_device_requirements_by_name, + "_task" => :find_deployed_task_by_name, + "_deployment_group" => :find_deployment_group_by_name + }.freeze + def find_through_method_missing(m, args) MetaRuby::DSLs.find_through_method_missing( - self, m, args, - "_tag" => :find_tag, - "_def" => :find_definition_by_name, - "_dev" => :find_device_requirements_by_name, - "_task" => :find_deployed_task_by_name, - "_deployment_group" => :find_deployment_group_by_name + self, m, args, FIND_THROUGH_METHOD_MISSING ) || super end diff --git a/lib/syskit/bound_data_service.rb b/lib/syskit/bound_data_service.rb index bb5bd55ba..d528f80b9 100644 --- a/lib/syskit/bound_data_service.rb +++ b/lib/syskit/bound_data_service.rb @@ -159,19 +159,9 @@ def to_instance_requirements req end - def has_through_method_missing?(m) - MetaRuby::DSLs.has_through_method_missing?( - self, m, - "_srv" => :has_data_service? - ) || super - end - - def find_through_method_missing(m, args) - MetaRuby::DSLs.find_through_method_missing( - self, m, args, - "_srv" => :find_data_service - ) || super - end + MetaRuby::DSLs::FindThroughMethodMissing.standard( + self, { "_srv" => "data_service" } + ) DRoby = Struct.new :component, :model do def proxy(peer) diff --git a/lib/syskit/component.rb b/lib/syskit/component.rb index f3a9ff401..ce04c0519 100644 --- a/lib/syskit/component.rb +++ b/lib/syskit/component.rb @@ -142,7 +142,7 @@ def each_data_service end def has_data_service?(service_name) - model.find_data_service(service_name) + model.has_data_service?(service_name) end # Finds a data service by its name @@ -385,7 +385,7 @@ def merge(merged_task) def duplicate_missing_services_from(task) missing_services = task.model.each_data_service.find_all do |_, srv| - !model.find_data_service(srv.full_name) + !model.has_data_service?(srv.full_name) end missing_services.each do |_, srv| @@ -700,21 +700,27 @@ def deregister_data_reader(name) @data_readers.each(&:disconnect) end + HAS_THROUGH_METHOD_MISSING = { + "_srv" => :has_data_service?, + "_writer" => :find_registered_data_writer, + "_reader" => :find_registered_data_reader + }.freeze + + FIND_THROUGH_METHOD_MISSING = { + "_srv" => :find_data_service, + "_writer" => :find_registered_data_writer, + "_reader" => :find_registered_data_reader + }.freeze + def has_through_method_missing?(m) MetaRuby::DSLs.has_through_method_missing?( - self, m, - "_srv" => :has_data_service?, - "_writer" => :find_registered_data_writer, - "_reader" => :find_registered_data_reader + self, m, HAS_THROUGH_METHOD_MISSING ) || super end def find_through_method_missing(m, args) MetaRuby::DSLs.find_through_method_missing( - self, m, args, - "_srv" => :find_data_service, - "_writer" => :find_registered_data_writer, - "_reader" => :find_registered_data_reader + self, m, args, FIND_THROUGH_METHOD_MISSING ) || super end diff --git a/lib/syskit/coordination/models/data_monitoring_table.rb b/lib/syskit/coordination/models/data_monitoring_table.rb index a18bf38ce..578d26e97 100644 --- a/lib/syskit/coordination/models/data_monitoring_table.rb +++ b/lib/syskit/coordination/models/data_monitoring_table.rb @@ -99,15 +99,18 @@ def attach_to(query) attachment_points << query end + HAS_THROUGH_METHOD_MISSING = { "_port" => :has_port? }.freeze + FIND_THROUGH_METHOD_MISSING = { "_port" => :find_port }.freeze + def has_through_method_missing?(m) MetaRuby::DSLs.has_through_method_missing?( - root, m, "_port" => :has_port? + root, m, HAS_THROUGH_METHOD_MISSING ) || super end def find_through_method_missing(m, args) MetaRuby::DSLs.find_through_method_missing( - root, m, args, "_port" => :find_port + root, m, args, FIND_THROUGH_METHOD_MISSING ) || super end diff --git a/lib/syskit/coordination/models/fault_response_table_extension.rb b/lib/syskit/coordination/models/fault_response_table_extension.rb index 93e8171b0..b1b810c45 100644 --- a/lib/syskit/coordination/models/fault_response_table_extension.rb +++ b/lib/syskit/coordination/models/fault_response_table_extension.rb @@ -77,26 +77,14 @@ def find_monitor(name) nil end - def has_through_method_missing?(m) - MetaRuby::DSLs.has_through_method_missing?( - self, m, "_monitor" => :find_monitor - ) || super - end - - def find_through_method_missing(m, args) - MetaRuby::DSLs.find_through_method_missing( - self, m, args, "_monitor" => :find_monitor - ) || super - end - - include MetaRuby::DSLs::FindThroughMethodMissing + MetaRuby::DSLs::FindThroughMethodMissing.standard(self, %w[monitor]) def respond_to_missing?(m, include_private) - arguments[m] || super + arguments.key?(m) || super end def method_missing(m, *args, &block) - if arg = arguments[m] + if (arg = arguments[m]) Roby::Coordination::Models::Variable.new(m) else super diff --git a/lib/syskit/coordination/models/port_handling.rb b/lib/syskit/coordination/models/port_handling.rb index b0298d5f4..6d6ce5cdf 100644 --- a/lib/syskit/coordination/models/port_handling.rb +++ b/lib/syskit/coordination/models/port_handling.rb @@ -25,13 +25,7 @@ def self_port_to_component_port(port) model.self_port_to_component_port(port) end - def has_through_method_missing?(m) - MetaRuby::DSLs.has_through_method_missing?(self, m, "_port" => :has_port?) || super - end - - def find_through_method_missing(m, args) - MetaRuby::DSLs.find_through_method_missing(self, m, args, "_port" => :find_port) || super - end + MetaRuby::DSLs::FindThroughMethodMissing.standard(self, %w[port]) end end end diff --git a/lib/syskit/coordination/port_handling.rb b/lib/syskit/coordination/port_handling.rb index 54030d44e..0d3e2ff65 100644 --- a/lib/syskit/coordination/port_handling.rb +++ b/lib/syskit/coordination/port_handling.rb @@ -31,13 +31,7 @@ def self_port_to_component_port(port) end end - def has_through_method_missing?(m) - MetaRuby::DSLs.has_through_method_missing?(self, m, "_port" => :has_port?) || super - end - - def find_through_method_missing(m, args) - MetaRuby::DSLs.find_through_method_missing(self, m, args, "_port" => :find_port) || super - end + MetaRuby::DSLs::FindThroughMethodMissing.standard(self, %w[port]) end class OutputPort < Syskit::OutputPort diff --git a/lib/syskit/deployment.rb b/lib/syskit/deployment.rb index a207e510e..39248aa4d 100644 --- a/lib/syskit/deployment.rb +++ b/lib/syskit/deployment.rb @@ -311,7 +311,7 @@ def logger_name # # @return [TaskContext,nil] either the logging task, or nil if this # deployment has none - def logger_task + def logger_task(create: true) return unless logging_enabled? if arguments[:logger_task] @@ -323,14 +323,16 @@ def logger_task @logger_task = if logger_task&.fullfills?(LoggerService) logger_task - else + elsif create instanciate_default_logger_task(logger_name) end @logger_task&.default_logger = true end - @logger_task ||= process_server_config.default_logger_task(plan) + return @logger_task if @logger_task + + @logger_task = process_server_config.default_logger_task(plan, create: create) end # Instanciates a new default logger diff --git a/lib/syskit/instance_requirements.rb b/lib/syskit/instance_requirements.rb index 809bce6f5..cf2429296 100644 --- a/lib/syskit/instance_requirements.rb +++ b/lib/syskit/instance_requirements.rb @@ -1349,25 +1349,12 @@ def each_child end end - def has_through_method_missing?(name) - MetaRuby::DSLs.has_through_method_missing?( - self, name, - "_srv" => :has_data_service?, - "_child" => :has_child?, - "_port" => :has_port? - ) || super - end - - def find_through_method_missing(name, args) - MetaRuby::DSLs.find_through_method_missing( - self, name, args, - "_srv" => :find_data_service, - "_child" => :find_child, - "_port" => :find_port - ) || super - end - - include MetaRuby::DSLs::FindThroughMethodMissing + MetaRuby::DSLs::FindThroughMethodMissing.standard( + self, + "_srv" => "data_service", + "_child" => "child", + "_port" => "port" + ) # Generates the InstanceRequirements object that represents +self+ # best diff --git a/lib/syskit/models/bound_data_service.rb b/lib/syskit/models/bound_data_service.rb index f0f2eeea5..d46fc8acb 100644 --- a/lib/syskit/models/bound_data_service.rb +++ b/lib/syskit/models/bound_data_service.rb @@ -385,31 +385,23 @@ def each_required_model extend InstanceRequirements::Auto def has_data_service?(name) - component_model.each_slave_data_service(self) do |slave_m| - return true if slave_m.name == name + unless (m = component_model.find_data_service("#{self.name}.#{name}")) + return false end - false + + m.master == self end def find_data_service(name) - component_model.each_slave_data_service(self) do |slave_m| - return slave_m if slave_m.name == name + unless (m = component_model.find_data_service("#{self.name}.#{name}")) + return end - nil - end - def has_through_method_missing?(m) - MetaRuby::DSLs.has_through_method_missing?( - self, m, "_srv" => :has_data_service? - ) || super + m if m.master == self end - def find_through_method_missing(m, args) - MetaRuby::DSLs.find_through_method_missing( - self, m, args, - "_srv" => :find_data_service - ) || super - end + MetaRuby::DSLs::FindThroughMethodMissing + .standard(self, { "_srv" => "data_service" }) # Whether two services are the same service bound to two different interfaces # diff --git a/lib/syskit/models/component.rb b/lib/syskit/models/component.rb index dd278e2af..7ad9797a9 100644 --- a/lib/syskit/models/component.rb +++ b/lib/syskit/models/component.rb @@ -42,7 +42,7 @@ def can_use_template? # # @key_name full_name # @return [Hash] - inherited_attribute(:data_service, :data_services, map: true) { {} } + inherited_attribute(:data_service, :data_services, map: true, cache: true) { {} } # List of modules that should be applied on the underlying # {Orocos::RubyTasks::StubTaskContext} when running tests in @@ -55,8 +55,8 @@ def can_use_template? def clear_model super - data_services.clear - dynamic_services.clear + data_services_clear + dynamic_services_clear # NOTE: the placeholder_models cache is cleared separately. The # reason is that we need to clear it on permanent and # non-permanent models alike, including component models that @@ -159,7 +159,7 @@ def each_slave_data_service(master_service) return enum_for(:each_slave_data_service, master_service) end - each_data_service(nil) do |_name, service| + each_data_service do |_name, service| next unless (m = service.master) yield(service) if m.full_name == master_service.full_name @@ -173,7 +173,7 @@ def each_slave_data_service(master_service) def each_root_data_service return enum_for(:each_root_data_service) unless block_given? - each_data_service(nil) do |_name, service| + each_data_service do |_name, service| yield(service) if service.master? end end @@ -186,8 +186,7 @@ def instanciate( plan, _context = DependencyInjectionContext.new, task_arguments: {}, ** ) - plan.add(task = new(**task_arguments)) - task + new(plan: plan, **task_arguments) end # The model next in the ancestry chain, or nil if +self+ is root @@ -638,11 +637,12 @@ def with_dynamic_service(dynamic_service_name, **options) # @param dyn_options options passed to the dynamic service block # through {DynamicDataService#instanciate} # @return [BoundDynamicDataService] the newly created service - def require_dynamic_service(dynamic_service_name, as:, **dyn_options) + def require_dynamic_service( + dynamic_service_name, force: false, as:, **dyn_options) service_name = as.to_str dyn = dynamic_service_by_name(dynamic_service_name) - if (srv = find_data_service(service_name)) + if !force && (srv = find_data_service(service_name)) return srv if srv.fullfills?(dyn.service_model) raise ArgumentError, @@ -796,7 +796,7 @@ def provides_resolve_name(as:, slave_of: nil) def provides_validate_possible_overload(model, full_name) # Get the source name and the source model - if data_services[full_name] + if self_data_services[full_name] raise ArgumentError, "there is already a data service named '#{full_name}' " \ "defined on '#{short_name}'" @@ -818,7 +818,7 @@ def provides_validate_possible_overload(model, full_name) def promote_service_if_needed(service) return service if service.component_model == self - data_services[service.full_name] = service.attach(self) + service.attach(self) end # @api private @@ -841,7 +841,7 @@ def provides_compute_port_mappings(service, given_srv_to_self = {}) def register_bound_data_service(full_name, service) include service.model - data_services[full_name] = service + data_service_set(full_name, service) Models.debug do Models.debug "#{short_name} provides #{service}" @@ -1209,30 +1209,28 @@ def can_merge_service?(self_srv, target_srv) def apply_missing_dynamic_services_from(from, specialize_if_needed = true) missing_services = from.each_data_service.find_all do |_, srv| - !find_data_service(srv.full_name) + !has_data_service?(srv.full_name) end - if missing_services.empty? - self - else - # We really really need to specialize self. The reason is - # that self.model, even though it has private - # specializations, might be a reusable model from the system - # designer's point of view. With the singleton class, we - # know that it is not - base_model = if specialize_if_needed then specialize - else - self - end - missing_services.each do |_, srv| - dynamic_service_options = - { as: srv.name }.merge(srv.dynamic_service_options) - base_model.require_dynamic_service( - srv.dynamic_service.name, **dynamic_service_options - ) - end - base_model + return self if missing_services.empty? + + # We really really need to specialize self. The reason is + # that self.model, even though it has private + # specializations, might be a reusable model from the system + # designer's point of view. With the singleton class, we + # know that it is not + base_model = if specialize_if_needed then specialize + else + self + end + missing_services.each do |_, srv| + dynamic_service_options = + { as: srv.name }.merge(srv.dynamic_service_options) + base_model.require_dynamic_service( + srv.dynamic_service.name, force: true, **dynamic_service_options + ) end + base_model end # Returns the component model that is the merge model of self and @@ -1399,25 +1397,14 @@ def data_writer(port, as:, **policy) data_writers[as] = port.to_bound_data_accessor(as, self, **policy) end - def has_through_method_missing?(name) - MetaRuby::DSLs.has_through_method_missing?( - self, name, - "_srv" => :find_data_service, - "_reader" => :find_data_reader, - "_writer" => :find_data_writer - ) || super - end - - def find_through_method_missing(name, args) - MetaRuby::DSLs.find_through_method_missing( - self, name, args, - "_srv" => :find_data_service, - "_reader" => :find_data_reader, - "_writer" => :find_data_writer - ) || super - end - - include MetaRuby::DSLs::FindThroughMethodMissing + MetaRuby::DSLs::FindThroughMethodMissing.standard( + self, + { + "_srv" => :data_service, + "_reader" => :data_reader, + "_writer" => :data_writer + } + ) ruby2_keywords def method_missing(name, *args, &block) # rubocop:disable Style/MissingRespondToMissing if name == :orogen_model diff --git a/lib/syskit/models/composition.rb b/lib/syskit/models/composition.rb index 9ae108b7d..1a2affd0d 100644 --- a/lib/syskit/models/composition.rb +++ b/lib/syskit/models/composition.rb @@ -1038,7 +1038,7 @@ def instanciate( # rubocop:disable Metrics/ParameterLists end # First of all, add the task for +self+ - plan.add(self_task = new(**task_arguments)) + self_task = new(plan: plan,**task_arguments) conf = if self_task.has_argument?(:conf) self_task.conf(self_task.arguments[:conf]) else @@ -1254,17 +1254,7 @@ def setup_submodel(submodel, register_specializations: true, submodel end - def has_through_method_missing?(m) - MetaRuby::DSLs.has_through_method_missing?( - self, m, "_child" => :find_child - ) || super - end - - def find_through_method_missing(m, args) - MetaRuby::DSLs.find_through_method_missing( - self, m, args, "_child" => :find_child - ) || super - end + MetaRuby::DSLs::FindThroughMethodMissing.standard(self, %w[child]) # Helper method for {#promote_exported_output} and # {#promote_exported_input} diff --git a/lib/syskit/models/deployment.rb b/lib/syskit/models/deployment.rb index 966647ef3..2a6dd356e 100644 --- a/lib/syskit/models/deployment.rb +++ b/lib/syskit/models/deployment.rb @@ -37,9 +37,8 @@ def deployment_name orogen_model.name end - def instanciate(plan, arguments = {}) - plan.add(task = new(arguments)) - task + def instanciate(plan, **arguments) + new(plan: plan, **arguments) end # @api private diff --git a/lib/syskit/models/deployment_group.rb b/lib/syskit/models/deployment_group.rb index 7ce1186fa..82d2690a5 100644 --- a/lib/syskit/models/deployment_group.rb +++ b/lib/syskit/models/deployment_group.rb @@ -34,14 +34,10 @@ class DeploymentGroup def instanciate(plan, permanent: true, deployment_tasks: {}) deployment_task = ( deployment_tasks[[configured_deployment]] ||= - configured_deployment.new + configured_deployment.new(plan: plan) ) - if permanent - plan.add_permanent_task(deployment_task) - else - plan.add(deployment_task) - end + plan.add_permanent_task(deployment_task) if permanent [deployment_task.task(mapped_task_name), deployment_task] end diff --git a/lib/syskit/models/faceted_access.rb b/lib/syskit/models/faceted_access.rb index 22eda3fb9..4f8521130 100644 --- a/lib/syskit/models/faceted_access.rb +++ b/lib/syskit/models/faceted_access.rb @@ -134,19 +134,7 @@ def to_s "#{object}.as(#{required.each_required_model.map(&:to_s).sort.join(',')})" end - def has_through_method_missing?(m) - MetaRuby::DSLs.has_through_method_missing?( - self, m, "_port" => :has_port? - ) || super - end - - def find_through_method_missing(m, args) - MetaRuby::DSLs.find_through_method_missing( - self, m, args, "_port" => :find_port - ) || super - end - - include MetaRuby::DSLs::FindThroughMethodMissing + MetaRuby::DSLs::FindThroughMethodMissing.standard(self, %w[port]) end end end diff --git a/lib/syskit/models/placeholder.rb b/lib/syskit/models/placeholder.rb index dffcc4dec..e49be80a6 100644 --- a/lib/syskit/models/placeholder.rb +++ b/lib/syskit/models/placeholder.rb @@ -146,21 +146,7 @@ def placeholder? true end - def has_through_method_missing?(m) - MetaRuby::DSLs.has_through_method_missing?( - self, m, - "_port" => :has_port? - ) || super - end - - def find_through_method_missing(m, args) - MetaRuby::DSLs.find_through_method_missing( - self, m, args, - "_port" => :find_port - ) || super - end - - include MetaRuby::DSLs::FindThroughMethodMissing + MetaRuby::DSLs::FindThroughMethodMissing.standard(self, %w[port]) # Encapsulation of the methods that allow to create placeholder # models diff --git a/lib/syskit/models/port_access.rb b/lib/syskit/models/port_access.rb index 3521b6514..cba2b9e85 100644 --- a/lib/syskit/models/port_access.rb +++ b/lib/syskit/models/port_access.rb @@ -9,17 +9,7 @@ module PortAccess # to the corresponding Models::Port instance attribute(:ports) { {} } - def has_through_method_missing?(m) - MetaRuby::DSLs.has_through_method_missing?( - self, m, "_port" => :has_port? - ) || super - end - - def find_through_method_missing(m, args) - MetaRuby::DSLs.find_through_method_missing( - self, m, args, "_port" => :find_port - ) || super - end + MetaRuby::DSLs::FindThroughMethodMissing.standard(self, %w[port]) # Returns the port object that maps to the given name, or nil if it # does not exist. diff --git a/lib/syskit/network_generation/async_fiber.rb b/lib/syskit/network_generation/async_fiber.rb index 78ff9edbc..9b9b4bb14 100644 --- a/lib/syskit/network_generation/async_fiber.rb +++ b/lib/syskit/network_generation/async_fiber.rb @@ -40,6 +40,8 @@ def initialize( resolution_control: Control.new(slice), event_logger: event_logger, resolver_options: resolver_options) + log_timepoint_group_start("syskit-netgen:async-fiber") + # Protect all Component instances against garbage collection # by adding them in a transaction. This is to make sure we don't # tear down, during network generation, subparts of the old network @@ -49,7 +51,7 @@ def initialize( @keepalive.wrap(component_task) unless component_task.finished? end - log_timepoint("syskit-netgen:async-fiber-start") + log_timepoint("syskit-netgen:created-keepalive-transaction") @fiber = Fiber.new do catch(:syskit_netgen_cancelled) do @@ -87,7 +89,13 @@ def async_phase def self.start( plan, requirement_tasks = default_requirement_tasks, resolver_options: {} ) - new(plan, requirement_tasks, resolver_options: resolver_options) + async = new(plan, requirement_tasks, resolver_options: resolver_options) + async.start unless Syskit.conf.resolution_time_slice == 0 + async + end + + def start + @fiber.resume(false) end # Cancel this resolution @@ -152,7 +160,7 @@ def result def finished! @finished = true @keepalive.discard_transaction unless @keepalive.finalized? - log_timepoint("syskit-netgen:async-fiber-finished") + log_timepoint_group_end("syskit-netgen:async-fiber") end # Wait for the resolution to finish and either apply the result or raise if diff --git a/lib/syskit/network_generation/engine.rb b/lib/syskit/network_generation/engine.rb index fec4415cd..1759364cd 100644 --- a/lib/syskit/network_generation/engine.rb +++ b/lib/syskit/network_generation/engine.rb @@ -184,11 +184,11 @@ def apply_deployed_network_to_plan if @dataflow_dynamics @dataflow_dynamics.apply_merges(merge_solver) - log_timepoint "apply_merged_to_dataflow_dynamics" + log_timepoint "syskit-netgen:apply_merged_to_dataflow_dynamics" end Engine.deployment_postprocessing.each do |block| block.call(self, work_plan) - log_timepoint "postprocessing:#{block}" + log_timepoint "syskit-netgen:postprocessing:#{block}" end end @@ -597,13 +597,12 @@ def apply_system_network_to_plan( required_instances = required_instances.transform_values do |task| merge_solver.replacement_for(task) end - log_timepoint "apply_merge_to_stored_instances" fix_toplevel_tasks(required_instances) - log_timepoint "fix_toplevel_tasks" + log_timepoint "syskit-netgen:fixup" Engine.final_network_postprocessing.each do |block| block.call(self, work_plan) - log_timepoint "final_network_postprocessing:#{block}" + log_timepoint "syskit-netgen:final_network_postprocessing:#{block}" end # Finally, we should now only have deployed tasks. Verify it @@ -611,10 +610,11 @@ def apply_system_network_to_plan( if garbage_collect && validate_final_network validate_final_network(required_instances, work_plan, compute_deployments: compute_deployments) - log_timepoint "validate_final_network" + log_timepoint "syskit-netgen:validate_final_network" end commit_work_plan + log_timepoint "syskit-netgen:commit" end def discard_work_plan diff --git a/lib/syskit/network_generation/logger.rb b/lib/syskit/network_generation/logger.rb index 9a36a14c8..affa8cc68 100644 --- a/lib/syskit/network_generation/logger.rb +++ b/lib/syskit/network_generation/logger.rb @@ -142,19 +142,25 @@ def self.add_logging_to_network(engine, work_plan) next unless deployment.log_port?(p) log_port_name = "#{t.orocos_name}.#{p.name}" - connections[[p.name, log_port_name]] = Hash[fallback_policy: fallback_policy] + connections[[p.name, log_port_name]] = + Hash[fallback_policy: fallback_policy] required_logging_ports << [log_port_name, t, p] end required_connections << [t, connections] end - unless (logger_task = deployment.logger_task) - warn "deployment #{deployment.process_name} has no usable " \ - "logger (default logger name would be " \ - "#{deployment.process_name}_Logger)" + logger_task = deployment.logger_task( + create: !required_logging_ports.empty? + ) + unless logger_task + unless required_logging_ports.empty? + warn "deployment #{deployment.process_name} has no usable " \ + "logger (default logger name would be " \ + "#{deployment.process_name}_Logger)" + end next end - logger_task = work_plan[deployment.logger_task] + logger_task = work_plan[logger_task] # Disconnect current log connections, we're going to # reestablish the ones we want later on. We leave other @@ -184,9 +190,12 @@ def self.add_logging_to_network(engine, work_plan) # # Otherwise, Logger#configure will take care of it for # us - required_logging_ports.each do |port_name, logged_task, logged_port| - logger_task.create_logging_port(port_name, logged_task, logged_port) - end + required_logging_ports + .each do |port_name, logged_task, logged_port| + logger_task.create_logging_port( + port_name, logged_task, logged_port + ) + end end required_connections.each do |task, connections| connections = diff --git a/lib/syskit/network_generation/runtime_network_adaptation.rb b/lib/syskit/network_generation/runtime_network_adaptation.rb index 3371873d9..f90c4aaa0 100644 --- a/lib/syskit/network_generation/runtime_network_adaptation.rb +++ b/lib/syskit/network_generation/runtime_network_adaptation.rb @@ -39,6 +39,7 @@ def initialize( def apply result = finalize_deployed_tasks sever_old_plan_from_new_plan + log_timepoint "syskit-netgen:sever-old-from-new-plan" result end diff --git a/lib/syskit/port_access.rb b/lib/syskit/port_access.rb index 509dddec2..443094bd3 100644 --- a/lib/syskit/port_access.rb +++ b/lib/syskit/port_access.rb @@ -89,16 +89,6 @@ def has_input_port?(name, including_dynamic = true) !!find_input_port(name) end - def has_through_method_missing?(m) - MetaRuby::DSLs.has_through_method_missing?( - self, m, "_port" => :has_port? - ) || super - end - - def find_through_method_missing(m, args) - MetaRuby::DSLs.find_through_method_missing( - self, m, args, "_port" => :find_port - ) || super - end + MetaRuby::DSLs::FindThroughMethodMissing.standard(self, %w[port]) end end diff --git a/lib/syskit/process_managers/in_process/manager.rb b/lib/syskit/process_managers/in_process/manager.rb index f18508a3c..25118a483 100644 --- a/lib/syskit/process_managers/in_process/manager.rb +++ b/lib/syskit/process_managers/in_process/manager.rb @@ -131,8 +131,8 @@ def stop(process_name) DEFAULT_LOGGER_NAME = "syskit_in_process_logger" - def default_logger_task(plan, app: Roby.app) - self.class.default_logger_task(plan, app: app) + def default_logger_task(plan, app: Roby.app, create: true) + self.class.default_logger_task(plan, app: app, create: create) end def self.find_default_logger_task(plan, app: Roby.app) @@ -152,11 +152,13 @@ def self.find_default_logger_deployment_task(plan, app: Roby.app) end # The logger task - def self.default_logger_task(plan, app: Roby.app) + def self.default_logger_task(plan, app: Roby.app, create: true) return unless (deployment = app.syskit_in_process_logger_deployment) if (t = find_default_logger_task(plan)) return t + elsif !create + return end deployment_t = find_default_logger_deployment_task(plan, app: app) diff --git a/lib/syskit/process_managers/ruby_tasks/manager.rb b/lib/syskit/process_managers/ruby_tasks/manager.rb index 80c7829d3..042ee5630 100644 --- a/lib/syskit/process_managers/ruby_tasks/manager.rb +++ b/lib/syskit/process_managers/ruby_tasks/manager.rb @@ -111,8 +111,8 @@ def dead_deployment(deployment_name, status = Status.new(true)) terminated_deployments[deployment] = status end - def default_logger_task(plan, app: Roby.app) - InProcess::Manager.default_logger_task(plan, app: app) + def default_logger_task(plan, app: Roby.app, create: true) + InProcess::Manager.default_logger_task(plan, app: app, create: create) end end end diff --git a/lib/syskit/queries/abstract_component_base.rb b/lib/syskit/queries/abstract_component_base.rb index 88c41785e..f82fa065e 100644 --- a/lib/syskit/queries/abstract_component_base.rb +++ b/lib/syskit/queries/abstract_component_base.rb @@ -80,19 +80,25 @@ def data_service_matcher_by_name(name) include MetaRuby::DSLs::FindThroughMethodMissing + HAS_THROUGH_METHOD_MISSING = { + "_srv" => :data_service_by_name?, + "_port" => :port_by_name? + }.freeze + def has_through_method_missing?(m) MetaRuby::DSLs.has_through_method_missing?( - self, m, - "_srv" => :data_service_by_name?, - "_port" => :port_by_name? + self, m, HAS_THROUGH_METHOD_MISSING ) || super end + FIND_THROUGH_METHOD_MISSING = { + "_srv" => :find_data_service_matcher_by_name, + "_port" => :find_port_matcher_by_name + }.freeze + def find_through_method_missing(m, args) MetaRuby::DSLs.find_through_method_missing( - self, m, args, - "_srv" => :find_data_service_matcher_by_name, - "_port" => :find_port_matcher_by_name + self, m, args, FIND_THROUGH_METHOD_MISSING ) || super end end diff --git a/lib/syskit/robot/master_device_instance.rb b/lib/syskit/robot/master_device_instance.rb index ea7189ea9..361bba6d8 100644 --- a/lib/syskit/robot/master_device_instance.rb +++ b/lib/syskit/robot/master_device_instance.rb @@ -355,15 +355,18 @@ def slave(slave_service, as: nil) robot.devices["#{name}.#{srv.name}"] = device_instance end + HAS_THROUGH_METHOD_MISSING = { "_dev" => :has_slave? }.freeze + FIND_THROUGH_METHOD_MISSING = { "_dev" => :slave }.freeze + def has_through_method_missing?(m) MetaRuby::DSLs.has_through_method_missing?( - self, m, "_dev" => :has_slave? + self, m, HAS_THROUGH_METHOD_MISSING ) || super end def find_through_method_missing(m, args) MetaRuby::DSLs.find_through_method_missing( - self, m, args, "_dev" => :slave + self, m, args, FIND_THROUGH_METHOD_MISSING ) || super end diff --git a/lib/syskit/robot/robot_definition.rb b/lib/syskit/robot/robot_definition.rb index 253eaada1..601175c78 100644 --- a/lib/syskit/robot/robot_definition.rb +++ b/lib/syskit/robot/robot_definition.rb @@ -255,19 +255,9 @@ def to_dependency_injection @di.dup end - def has_through_method_missing?(m) - MetaRuby::DSLs.has_through_method_missing?( - self, m, "_dev" => :has_device? - ) || super - end - - def find_through_method_missing(m, args) - MetaRuby::DSLs.find_through_method_missing( - self, m, args, "_dev" => :find_device - ) || super - end - - include MetaRuby::DSLs::FindThroughMethodMissing + MetaRuby::DSLs::FindThroughMethodMissing.standard( + self, { "_dev" => "device" } + ) end end end diff --git a/lib/syskit/roby_app/configuration.rb b/lib/syskit/roby_app/configuration.rb index 56d35547f..5a9465e8a 100644 --- a/lib/syskit/roby_app/configuration.rb +++ b/lib/syskit/roby_app/configuration.rb @@ -909,8 +909,10 @@ def register_on_name_server? register_on_name_server end - def default_logger_task(plan) - client.default_logger_task(plan) if client.respond_to?(:default_logger_task) + def default_logger_task(plan, create: true) + if client.respond_to?(:default_logger_task) + client.default_logger_task(plan, create: create) + end end end diff --git a/lib/syskit/task_context.rb b/lib/syskit/task_context.rb index fbdcd51c8..1f2360755 100644 --- a/lib/syskit/task_context.rb +++ b/lib/syskit/task_context.rb @@ -304,7 +304,7 @@ def can_be_deployed_by?(task) has_service_to_add_through_reconfiguration = each_required_dynamic_service.any? do |srv| srv.model.addition_requires_reconfiguration? && - !task.find_data_service(srv.name) + !task.has_data_service?(srv.name) end return false if has_service_to_add_through_reconfiguration @@ -1564,16 +1564,6 @@ def removed_sink(source) relation_graph_for(Flows::DataFlow).modified_tasks << self end - def has_through_method_missing?(name) - MetaRuby::DSLs.has_through_method_missing?( - self, name, "_property" => :has_property? - ) || super - end - - def find_through_method_missing(name, args) - MetaRuby::DSLs.find_through_method_missing( - self, name, args, "_property" => :find_property - ) || super - end + MetaRuby::DSLs::FindThroughMethodMissing.standard(self, %w[property]) end end diff --git a/lib/syskit/test/profile_test.rb b/lib/syskit/test/profile_test.rb index 4e79ba5fe..f138c27b5 100644 --- a/lib/syskit/test/profile_test.rb +++ b/lib/syskit/test/profile_test.rb @@ -54,23 +54,8 @@ def find_device(name) subject_syskit_model.robot.devices[name] end - def has_through_method_missing?(m) - MetaRuby::DSLs.has_through_method_missing?( - self, m, - "_def" => :find_definition, - "_dev" => :find_device - ) || super - end - - def find_through_method_missing(m, args) - MetaRuby::DSLs.find_through_method_missing( - self, m, args, - "_def" => :find_definition, - "_dev" => :find_device - ) || super - end - - include MetaRuby::DSLs::FindThroughMethodMissing + MetaRuby::DSLs::FindThroughMethodMissing + .standard(self, { "_def" => "definition", "_dev" => "device"}) end def has_through_method_missing?(m) diff --git a/test/runtime/test_apply_requirement_modifications.rb b/test/runtime/test_apply_requirement_modifications.rb index d2078e805..c979c2b21 100644 --- a/test/runtime/test_apply_requirement_modifications.rb +++ b/test/runtime/test_apply_requirement_modifications.rb @@ -55,6 +55,9 @@ module Runtime describe "with a cancelled resolution running" do before do + @__resolution_time_slice = Syskit.conf.resolution_time_slice + Syskit.conf.resolution_time_slice = 0 + @cmp_m = Composition.new_submodel plan.add_permanent_task( cmp = @cmp_m.to_instance_requirements.as_plan @@ -65,6 +68,10 @@ module Runtime execute { plan.syskit_cancel_async_resolution } end + after do + Syskit.conf.resolution_time_slice = @__resolution_time_slice + end + it "waits for the resolution end but does not apply the result" do execute { plan.syskit_join_current_resolution } @@ -94,12 +101,17 @@ module Runtime describe ".apply_requirement_modifications" do before do + @__fiber_slice = + Syskit.conf.resolution_time_slice @__capture_errors_feature_flag = Syskit.conf.capture_errors_during_network_resolution? + Syskit.conf.resolution_time_slice = 0 Syskit.conf.capture_errors_during_network_resolution = false end after do + Syskit.conf.resolution_time_slice = + @__fiber_slice Syskit.conf.capture_errors_during_network_resolution = @__capture_errors_feature_flag end @@ -278,16 +290,15 @@ module Runtime end execute { Runtime.apply_requirement_modifications(plan) } - loop do - break unless plan.syskit_has_async_resolution? - + deadline = Time.now + 1 + until Time.now > deadline execute { plan.syskit_join_current_resolution } execute { Runtime.apply_requirement_modifications(plan) } + success = reqs.all?(&:resolution_success?) + break if success end - reqs.each do |req| - assert req.resolution_success? - end + assert success end it "while using force, cancels pending resolutions and executes " \ diff --git a/test/test_component.rb b/test/test_component.rb index 3c30ed329..3875a7f95 100644 --- a/test/test_component.rb +++ b/test/test_component.rb @@ -285,7 +285,9 @@ merged_task.specialize merged_task.require_dynamic_service "dyn", as: "srv" task.specialize - flexmock(task.model).should_receive(:find_data_service).with("srv").and_return(true) + flexmock(task.model) + .should_receive(:has_data_service?) + .with("srv").and_return(true) flexmock(task.model).should_receive(:provides_dynamic).never task.merge(merged_task) end