Class: Syskit::Deployment

Inherits:
Roby::Task
  • Object
show all
Extended by:
Logger::Hierarchy, Models::Deployment
Includes:
Logger::Hierarchy
Defined in:
lib/syskit/deployment.rb

Overview

In oroGen, a deployment is a Unix process that holds a certain number of task contexts. This Roby task represents the unix process itself. Once it gets instanciated, the associated task contexts can be accessed with #task(name)

Defined Under Namespace

Classes: CurrentTaskConfiguration, Ready, RemoteTaskHandles, Signaled, Start, Stop

Constant Summary collapse

STATE_READER_BUFFER_SIZE =

The size of the buffered connection created between this object and the remote task's state port

200
@@all_deployments =
Hash.new

Instance Attribute Summary collapse

Attributes included from Models::Deployment

#orogen_model

Task Arguments collapse

Task Events collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Models::Deployment

all_default_name_mapping, all_default_run_option, default_name_mapping, default_name_mappings, default_run_option, default_run_options, define_from_orogen, deployment_name, each_default_name_mapping, each_default_run_option, each_deployed_task_model, each_deployed_task_name, instanciate, new_submodel, supermodel, tasks

Methods included from Models::OrogenBase

#find_model_by_orogen, #find_model_from_orogen_name, #has_model_for?, #model_for

Methods included from Models::Base

#dependency_injection_names, #pretty_print, #short_name, #to_instance_requirements, #to_s

Constructor Details

#initialize(options = Hash.new) ⇒ Deployment

Returns a new instance of Deployment



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/syskit/deployment.rb', line 44

def initialize(options = Hash.new)
    super

    @quit_ready_event_monitor = Concurrent::Event.new
    @remote_task_handles = Hash.new
    if !self.spawn_options
        self.spawn_options = Hash.new
    end
    if !self.name_mappings
        self.name_mappings = Hash.new
    end
    model.each_default_name_mapping do |k, v|
        self.name_mappings[k] ||= v
    end
end

Instance Attribute Details

#orocos_processObject (readonly)

The underlying Orocos::Process instance



35
36
37
# File 'lib/syskit/deployment.rb', line 35

def orocos_process
  @orocos_process
end

#quit_ready_event_monitorConcurrent::Event (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Event used to quit the ready monitor started by #schedule_ready_event_monitor

Returns:

  • (Concurrent::Event)


438
439
440
# File 'lib/syskit/deployment.rb', line 438

def quit_ready_event_monitor
  @quit_ready_event_monitor
end

#remote_task_handlesHash<String,RemoteTaskHandles> (readonly)

Handles to all remote tasks from this deployment

Returns:



75
76
77
# File 'lib/syskit/deployment.rb', line 75

def remote_task_handles
  @remote_task_handles
end

Class Method Details

.all_deploymentsObject



62
# File 'lib/syskit/deployment.rb', line 62

def all_deployments; @@all_deployments end

.command_line(name, name_mappings, working_directory: Roby.app.log_dir, log_level: nil, cmdline_args: Hash.new, tracing: false, gdb: nil, valgrind: nil, name_service_ip: 'localhost', loader: Roby.app.default_pkgconfig_loader) ⇒ Orocos::Process::CommandLine

Create the spawn options needed to start this deployment for the given configuration

Returns:

  • (Orocos::Process::CommandLine)


297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/syskit/deployment.rb', line 297

def self.command_line(name, name_mappings,
        working_directory: Roby.app.log_dir,
        log_level: nil,
        cmdline_args: Hash.new,
        tracing: false,
        gdb: nil,
        valgrind: nil,
        name_service_ip: 'localhost',
        loader: Roby.app.default_pkgconfig_loader)

    cmdline_args = cmdline_args.dup
    each_default_run_option do |option_name, option_value|
        if !cmdline_args.has_key?(option_name)
            cmdline_args[option_name] = option_value
        end
    end

    process = Orocos::Process.new(name, orogen_model,
        loader: loader,
        name_mappings: name_mappings)
    process.command_line(
        working_directory: working_directory,
        log_level: log_level,
        cmdline_args: cmdline_args,
        tracing: tracing,
        gdb: gdb,
        valgrind: valgrind,
        name_service_ip: name_service_ip)
end

.deployment_by_process(process) ⇒ Object

Returns the deployment object that matches the given process object

Parameters:

  • process

    the deployment's process object. Note that it is usually not a Ruby Process object, but a process representation from orocosrb's process server infrastructure



713
714
715
# File 'lib/syskit/deployment.rb', line 713

def self.deployment_by_process(process)
    all_deployments.fetch(process)
end

.needs_reconfiguration!(plan, orocos_name) ⇒ Object

Force reconfiguration for all tasks in a plan that match the given orocos name



537
538
539
540
541
542
543
544
# File 'lib/syskit/deployment.rb', line 537

def self.needs_reconfiguration!(plan, orocos_name)
    plan.find_local_tasks(Syskit::Deployment).
        each do |deployment_task|
            if deployment_task.has_orocos_name?(orocos_name)
                deployment_task.needs_reconfiguration!(orocos_name)
            end
        end
end

Instance Method Details

#configuration_changed?(orocos_name, conf, dynamic_services) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The currently applied configuration for the given task

Returns:

  • (Boolean)


519
520
521
522
523
# File 'lib/syskit/deployment.rb', line 519

def configuration_changed?(orocos_name, conf, dynamic_services)
    current = remote_task_handles[orocos_name].current_configuration
    current.conf != conf ||
        current.dynamic_services != dynamic_services.to_set
end

#configuring?(orocos_name) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Whether one of this deployment's task is being configured

Returns:

  • (Boolean)


498
499
500
# File 'lib/syskit/deployment.rb', line 498

def configuring?(orocos_name)
    remote_task_handles[orocos_name].configuring
end

#create_deployed_task(orogen_task_deployment_model, syskit_task_model, scheduler_task, auto_conf: false) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Create and add a task model supported by this deployment

Parameters:

  • orogen_task_deployment_model (OroGen::Spec::TaskDeployment)

    the orogen model that describes this deployment

  • syskit_task_model (Models::TaskContext, nil)

    the expected syskit task model, or nil if it is meant to use the basic model. This is useful in specialized models (e.g. dynamic services)

  • syskit_execution_agent (Deployment, TaskContext)

    the task that will be used as an execution agent. this is usually self, but may be a task in master/slave relationships.

  • auto_conf (Boolean)

    if true, the method will attempt to select a configuration that matches the task's orocos name (if it exists). This is mostly used for scheduling tasks, which are automatically instanciated by Syskit.

See Also:



179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
# File 'lib/syskit/deployment.rb', line 179

def create_deployed_task(orogen_task_deployment_model,
    syskit_task_model, scheduler_task, auto_conf: false)

    mapped_name = name_mappings[orogen_task_deployment_model.name]
    base_syskit_task_model = deployed_model_by_orogen_model(
        orogen_task_deployment_model)
    if syskit_task_model
        if !(syskit_task_model <= base_syskit_task_model)
            raise ArgumentError, "incompatible explicit selection of task "\
                "model #{syskit_task_model} for the model of #{mapped_name} "\
                " in #{self}"
        end
    else
        syskit_task_model = base_syskit_task_model
    end

    plan.add(task = syskit_task_model.new(orocos_name: mapped_name))
    task.executed_by self
    if scheduler_task
        task.depends_on scheduler_task, role: 'scheduler'
        task.should_configure_after scheduler_task.start_event
    end

    task.orogen_model = orogen_task_deployment_model
    if ready?
        if remote_task = remote_task_handles[mapped_name]
            task.initialize_remote_handles(remote_task)
        else
            raise InternalError, "no remote handle describing #{mapped_name} in #{self} for #{task} (got #{remote_task_handles.keys.sort.join(", ")})"
        end
    end
    auto_select_conf(task) if auto_conf
    task
end

#create_state_access(remote_task, distance: TaskContext::D_UNKNOWN) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Called asynchronously to initialize the RemoteTaskHandles object once and for all



621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
# File 'lib/syskit/deployment.rb', line 621

def create_state_access(remote_task, distance: TaskContext::D_UNKNOWN)
    state_getter = RemoteStateGetter.new(
        remote_task,
        initial_state: remote_task.rtt_state)

    if remote_task.model.extended_state_support?
        state_port = remote_task.raw_port('state')
        state_reader = state_port.reader(
            type: :buffer, size: STATE_READER_BUFFER_SIZE, init: true,
            distance: distance)
        state_reader.extend Orocos::TaskContext::StateReader
        state_reader.state_symbols = remote_task.state_symbols
    else
        state_reader = state_getter
    end
    return state_reader, state_getter
end

#dead!(result) ⇒ Object

Called when the process is finished.

result is the Process::Status object describing how this process finished.



683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
# File 'lib/syskit/deployment.rb', line 683

def dead!(result)
    if history.find(&:terminal?)
        # Do nothing. A terminal event already happened, so we don't
        # need to tell what kind of end this is for the system
        stop_event.emit
    elsif !result
        failed_event.emit
    elsif result.success?
        success_event.emit
    elsif result.signaled?
        signaled_event.emit result
    else
        failed_event.emit result
    end

    Deployment.all_deployments.delete(orocos_process)

    # do NOT call cleanup_dead_connections here.
    # Runtime.update_deployment_states will first announce all the
    # dead processes and only then call #cleanup_dead_connections,
    # thus avoiding to disconnect connections between already-dead
    # processes
end

#deployed_model_by_orogen_model(orogen_model) ⇒ Object



157
158
159
# File 'lib/syskit/deployment.rb', line 157

def deployed_model_by_orogen_model(orogen_model)
    TaskContext.model_for(orogen_model.task_model)
end

#deployed_orogen_model_by_name(name) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/syskit/deployment.rb', line 142

def deployed_orogen_model_by_name(name)
    orogen_task_deployment = each_orogen_deployed_task_context_model.
        find { |act| name == name_mappings[act.name] }
    unless orogen_task_deployment
        available = each_orogen_deployed_task_context_model.
            map { |act| name_mappings[act.name] }.sort.join(", ")
        mappings  = name_mappings.
            map { |k,v| "#{k} => #{v}" }.join(", ")
        raise ArgumentError, "no task called #{name} in "\
            "#{self.class.deployment_name}, available tasks are "\
            "#{available} using name mappings #{mappings}"
    end
    orogen_task_deployment
end

#distance_to(other_deployment) ⇒ Object

“How far” this deployment is from another

It returns one of the TaskContext::D_ constants



394
395
396
397
398
399
400
401
402
403
404
405
406
# File 'lib/syskit/deployment.rb', line 394

def distance_to(other_deployment)
    if other_deployment == self
        TaskContext::D_SAME_PROCESS
    elsif other_deployment.host_id == host_id
        if host_id == 'syskit'
            TaskContext::D_SAME_PROCESS
        else
            TaskContext::D_SAME_HOST
        end
    else
        TaskContext::D_DIFFERENT_HOSTS
    end
end

#distance_to_syskitObject

How “far” this process is from the Syskit process

Returns:



360
361
362
363
364
365
366
367
368
# File 'lib/syskit/deployment.rb', line 360

def distance_to_syskit
    if in_process?
        TaskContext::D_SAME_PROCESS
    elsif on_localhost?
        TaskContext::D_SAME_HOST
    else
        TaskContext::D_DIFFERENT_HOSTS
    end
end

#each_orogen_deployed_task_context_model(&block) ⇒ Object

The list of deployed task contexts for this particular deployment

It takes into account deployment prefix



104
105
106
# File 'lib/syskit/deployment.rb', line 104

def each_orogen_deployed_task_context_model(&block)
    model.each_orogen_deployed_task_context_model(&block)
end

#find_or_create_task(name, syskit_task_model = nil, auto_conf: false) ⇒ Object

Either find the existing task that matches the given deployment specification, or creates and adds it.

Parameters:

  • name (String)

    the unmapped name of the task

  • syskit_task_model (Models::TaskContext, nil) (defaults to: nil)

    the Syskit model that should be used to create the task, if it is not the same as the base model. This is used for specialized models (e.g. dynamic services)



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/syskit/deployment.rb', line 112

def find_or_create_task(name, syskit_task_model = nil, auto_conf: false)
    orogen_task_deployment_model = deployed_orogen_model_by_name(name)
    if orogen_master = orogen_task_deployment_model.master
        mapped_master = name_mappings[orogen_master.name]
        scheduler_task = find_or_create_task(
            mapped_master, auto_conf: true)
        candidates = scheduler_task.each_parent_task
    else
        candidates = each_executed_task
    end

    # I don't know why name_mappings[orogen.name] would not be
    # equal to 'name' and I couldn't find a reason for this in the
    # git history when I refactored this.
    #
    # I keep it here for now, just in case, but that would need to
    # be investigated
    #
    # TODO
    mapped_name = name_mappings[orogen_task_deployment_model.name]
    candidates.each do |task|
        return task if task.orocos_name == mapped_name
    end

    create_deployed_task(
        orogen_task_deployment_model,
        syskit_task_model,
        scheduler_task, auto_conf: auto_conf)
end

#finished_configuration(orocos_name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Declare that the given task is being configured



512
513
514
# File 'lib/syskit/deployment.rb', line 512

def finished_configuration(orocos_name)
    remote_task_handles[orocos_name].configuring = false
end

#has_orocos_name?(orocos_name) ⇒ Boolean

Returns:

  • (Boolean)


91
92
93
# File 'lib/syskit/deployment.rb', line 91

def has_orocos_name?(orocos_name)
    name_mappings.each_value.any? { |n| n == orocos_name }
end

#host_idObject

The name of the host this deployment is running on, i.e. the name given to the :on argument.



377
378
379
# File 'lib/syskit/deployment.rb', line 377

def host_id
    process_server_config.host_id
end

#in_process?Boolean

Whether this task runs within the Syskit process itself

Returns:

  • (Boolean)


382
383
384
# File 'lib/syskit/deployment.rb', line 382

def in_process?
    process_server_config.in_process?
end

#instanciate_all_tasksObject



95
96
97
98
99
# File 'lib/syskit/deployment.rb', line 95

def instanciate_all_tasks
    model.each_orogen_deployed_task_context_model.map do |act|
        task(name_mappings[act.name])
    end
end

#logObject



27
# File 'lib/syskit/deployment.rb', line 27

argument :log, :default => true

#log=Object



27
# File 'lib/syskit/deployment.rb', line 27

argument :log, :default => true

#log_dirObject



327
328
329
# File 'lib/syskit/deployment.rb', line 327

def log_dir
    process_server_config.log_dir
end

#log_port?(port) ⇒ Boolean

Returns true if the syskit plugin configuration requires port to be logged

Parameters:

Returns:

  • (Boolean)


413
414
415
416
417
418
419
420
# File 'lib/syskit/deployment.rb', line 413

def log_port?(port)
    if Syskit.conf.logs.port_excluded_from_log?(port)
        false
    else
        Syskit.info "not logging #{port.component}.#{port.name}"
        true
    end
end

#logger_taskTaskContext?

Returns this deployment's logger

Returns:

  • (TaskContext, nil)

    either the logging task, or nil if this deployment has none



335
# File 'lib/syskit/deployment.rb', line 335

argument :logger_task, default: nil

#logger_task=Object



32
# File 'lib/syskit/deployment.rb', line 32

argument :logger_task, default: nil

#mark_changed_configuration_as_not_reusable(changed) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Mark tasks affected by a change in configuration section as non-reusable



577
578
579
580
581
582
583
584
585
586
587
588
589
590
# File 'lib/syskit/deployment.rb', line 577

def mark_changed_configuration_as_not_reusable(changed)
    needed = Set.new
    remote_task_handles.each do |orocos_name, remote_handle|
        current_conf = remote_handle.current_configuration
        next if current_conf.conf.empty?
        if modified_sections = changed[current_conf.model.concrete_model]
            if modified_sections.any? { |section_name| current_conf.conf.include?(section_name) }
                needed << orocos_name
                remote_handle.needs_reconfiguration = true
            end
        end
    end
    needed
end

#name_mappingsObject



29
# File 'lib/syskit/deployment.rb', line 29

argument :name_mappings, :default => nil

#name_mappings=Object



29
# File 'lib/syskit/deployment.rb', line 29

argument :name_mappings, :default => nil

#needs_reconfiguration!(orocos_name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Force a task to be reconfigured during the next network adaptation



559
560
561
562
563
# File 'lib/syskit/deployment.rb', line 559

def needs_reconfiguration!(orocos_name)
    if handle = remote_task_handles[orocos_name]
        handle.needs_reconfiguration = true
    end
end

#needs_reconfiguration?(orocos_name) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Whether a task should be forcefully reconfigured during the next network adaptation

Returns:

  • (Boolean)


550
551
552
553
554
# File 'lib/syskit/deployment.rb', line 550

def needs_reconfiguration?(orocos_name)
    if handle = remote_task_handles[orocos_name]
        handle.needs_reconfiguration
    end
end

#onObject



28
# File 'lib/syskit/deployment.rb', line 28

argument :on, :default => 'localhost'

#on=Object



28
# File 'lib/syskit/deployment.rb', line 28

argument :on, :default => 'localhost'

#on_localhost?Boolean

Whether this deployment runs on the same host than the Syskit process

Returns:

  • (Boolean)


387
388
389
# File 'lib/syskit/deployment.rb', line 387

def on_localhost?
    process_server_config.on_localhost?
end

#pending_reconfigurationsObject

List of task (orocos names) that are marked as needing reconfiguration



567
568
569
570
571
# File 'lib/syskit/deployment.rb', line 567

def pending_reconfigurations
    remote_task_handles.keys.find_all do |orocos_name|
        remote_task_handles[orocos_name].needs_reconfiguration
    end
end

#pidObject

The PID of this process



66
67
68
69
70
# File 'lib/syskit/deployment.rb', line 66

def pid
    if running?
        @pid ||= orocos_process.pid
    end
end

#process_nameObject



26
# File 'lib/syskit/deployment.rb', line 26

argument :process_name, :default => from(:model).deployment_name

#process_name=Object



26
# File 'lib/syskit/deployment.rb', line 26

argument :process_name, :default => from(:model).deployment_name

#process_server_configRobyApp::Configuration::ProcessServerConfig

An object describing the underlying pocess server



40
41
42
# File 'lib/syskit/deployment.rb', line 40

def process_server_config
    @process_server_config ||= Syskit.conf.process_server_config_for(process_server_name)
end

#process_server_nameObject

The name of the process server



371
372
373
# File 'lib/syskit/deployment.rb', line 371

def process_server_name
    arguments[:on]
end

#ready?Boolean

Event emitted when the deployment is up and running

Returns:

  • (Boolean)


81
# File 'lib/syskit/deployment.rb', line 81

event :ready

#ready_eventEventGenerator

Event emitted when the deployment is up and running

Returns:

  • (EventGenerator)


81
# File 'lib/syskit/deployment.rb', line 81

event :ready

#ready_polling_periodObject

Default: 0.1



31
# File 'lib/syskit/deployment.rb', line 31

argument :ready_polling_period, default: 0.1

#ready_polling_period=Object



31
# File 'lib/syskit/deployment.rb', line 31

argument :ready_polling_period, default: 0.1

#ready_to_die!Object



641
642
643
# File 'lib/syskit/deployment.rb', line 641

def ready_to_die!
	@ready_to_die = true
end

#ready_to_die?Boolean

Returns:

  • (Boolean)


639
# File 'lib/syskit/deployment.rb', line 639

attr_predicate :ready_to_die?

#schedule_ready_event_monitor(handles_from_plan, ready_polling_period: self.ready_polling_period) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Schedule a promise to resolve the task handles

It will reschedule itself until the process is ready, and will emit the ready event when it happens



446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
# File 'lib/syskit/deployment.rb', line 446

def schedule_ready_event_monitor(handles_from_plan, ready_polling_period: self.ready_polling_period)
    distance_to_syskit = self.distance_to_syskit
    promise = execution_engine.promise(description: "#{self}:ready_event_monitor") do
        while !quit_ready_event_monitor.set? && !(handles = orocos_process.resolve_all_tasks(handles_from_plan))
            sleep ready_polling_period
        end

        (handles || Hash.new).map_value do |_, remote_task|
            state_reader, state_getter = create_state_access(remote_task, distance: distance_to_syskit)
            properties = remote_task.property_names.map do |p_name|
                p = remote_task.raw_property(p_name)
                [p, p.raw_read]
            end
            current_configuration = CurrentTaskConfiguration.new(nil, [], Set.new)
            RemoteTaskHandles.new(remote_task, state_reader, state_getter, properties, false, current_configuration)
        end
    end.on_success(description: "#{self}#schedule_ready_event_monitor#emit") do |remote_tasks|
        if running? && !finishing? && remote_tasks
            @remote_task_handles = remote_tasks
            ready_event.emit
        end
    end
    promise.on_error(description: "#{self}#emit_failed") do |reason|
        if !finishing? || !finished?
            emit_failed(reason)
        end
    end
    ready_event.achieve_asynchronously(promise, emit_on_success: false, on_failure: :nothing)
end

#setup_task_handles(remote_tasks) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
# File 'lib/syskit/deployment.rb', line 593

def setup_task_handles(remote_tasks)
    model.each_orogen_deployed_task_context_model do |act|
        name = orocos_process.get_mapped_name(act.name)
        if !remote_tasks.has_key?(name)
            raise InternalError, "expected #{orocos_process}'s reported tasks to include mapped_task_name, but got handles only for invalid_name"
        end
    end

    remote_tasks.each_value do |task|
        task.handle.process = nil
    end

    each_parent_object(Roby::TaskStructure::ExecutionAgent) do |task|
        if remote_handles = remote_tasks[task.orocos_name]
            task.initialize_remote_handles(remote_handles)
        else
            task.failed_to_start!(
                Roby::CommandFailed.new(
                    InternalError.exception("#{task} is supported by #{self} but there does not seem to be any task called #{task.orocos_name} on this deployment"),
                    task.start_event))
        end
    end
end

#signaled?Boolean

Event emitted whenever the deployment finishes because of a UNIX signal. The event context is the Process::Status instance that describes the termination

It is forwarded to failed_event

Returns:

  • (Boolean)


88
# File 'lib/syskit/deployment.rb', line 88

event :signaled

#signaled_eventEventGenerator

Event emitted whenever the deployment finishes because of a UNIX signal. The event context is the Process::Status instance that describes the termination

It is forwarded to failed_event

Returns:

  • (EventGenerator)


88
# File 'lib/syskit/deployment.rb', line 88

event :signaled

#spawn_optionsObject



30
# File 'lib/syskit/deployment.rb', line 30

argument :spawn_options, :default=> nil

#spawn_options=Object



30
# File 'lib/syskit/deployment.rb', line 30

argument :spawn_options, :default=> nil

#startObject

method: start!

Starts the process and emits the start event immediately. The :ready event will be emitted when the deployment is up and running.



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/syskit/deployment.rb', line 260

event :start do |context|
    if !process_name
        raise ArgumentError, "must set process_name"
    end

    spawn_options = self.spawn_options
    options = (spawn_options[:cmdline_args] || Hash.new).dup
    model.each_default_run_option do |name, value|
        options[name] = value
    end

    spawn_options = spawn_options.merge(
        output: "%m-%p.txt",
        wait: false,
        cmdline_args: options)

    if log_dir
        spawn_options = spawn_options.merge(working_directory: log_dir)
    else
        spawn_options.delete(:working_directory)
    end

    Deployment.info do
        "starting deployment #{process_name} using #{model.deployment_name} on #{arguments[:on]} with #{spawn_options} and mappings #{name_mappings}"
    end

    @orocos_process = process_server_config.client.start(
        process_name, model.orogen_model, name_mappings, spawn_options)

    Deployment.all_deployments[orocos_process] = self
    start_event.emit
end

#start?Boolean

method: start!

Starts the process and emits the start event immediately. The :ready event will be emitted when the deployment is up and running.

Returns:

  • (Boolean)


260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/syskit/deployment.rb', line 260

event :start do |context|
    if !process_name
        raise ArgumentError, "must set process_name"
    end

    spawn_options = self.spawn_options
    options = (spawn_options[:cmdline_args] || Hash.new).dup
    model.each_default_run_option do |name, value|
        options[name] = value
    end

    spawn_options = spawn_options.merge(
        output: "%m-%p.txt",
        wait: false,
        cmdline_args: options)

    if log_dir
        spawn_options = spawn_options.merge(working_directory: log_dir)
    else
        spawn_options.delete(:working_directory)
    end

    Deployment.info do
        "starting deployment #{process_name} using #{model.deployment_name} on #{arguments[:on]} with #{spawn_options} and mappings #{name_mappings}"
    end

    @orocos_process = process_server_config.client.start(
        process_name, model.orogen_model, name_mappings, spawn_options)

    Deployment.all_deployments[orocos_process] = self
    start_event.emit
end

#start_configuration(orocos_name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Declare that the given task is being configured



505
506
507
# File 'lib/syskit/deployment.rb', line 505

def start_configuration(orocos_name)
    remote_task_handles[orocos_name].configuring = true
end

#start_eventEventGenerator

method: start!

Starts the process and emits the start event immediately. The :ready event will be emitted when the deployment is up and running.

Returns:

  • (EventGenerator)


260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/syskit/deployment.rb', line 260

event :start do |context|
    if !process_name
        raise ArgumentError, "must set process_name"
    end

    spawn_options = self.spawn_options
    options = (spawn_options[:cmdline_args] || Hash.new).dup
    model.each_default_run_option do |name, value|
        options[name] = value
    end

    spawn_options = spawn_options.merge(
        output: "%m-%p.txt",
        wait: false,
        cmdline_args: options)

    if log_dir
        spawn_options = spawn_options.merge(working_directory: log_dir)
    else
        spawn_options.delete(:working_directory)
    end

    Deployment.info do
        "starting deployment #{process_name} using #{model.deployment_name} on #{arguments[:on]} with #{spawn_options} and mappings #{name_mappings}"
    end

    @orocos_process = process_server_config.client.start(
        process_name, model.orogen_model, name_mappings, spawn_options)

    Deployment.all_deployments[orocos_process] = self
    start_event.emit
end

#stopObject

method: stop!

Stops all tasks that are running on top of this deployment, and kill the deployment



650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
# File 'lib/syskit/deployment.rb', line 650

event :stop do |context|
    quit_ready_event_monitor.set
    promise = execution_engine.promise(description: "#{self}.stop_event.on") do
        begin
            remote_task_handles.each_value do |remote_task|
                remote_task.state_getter.disconnect
                if remote_task.handle.rtt_state == :STOPPED
                    remote_task.handle.cleanup(false)
                end
            end
            remote_task_handles.each_value do |remote_task|
                remote_task.state_getter.join
            end
        rescue Orocos::ComError
            # Assume that the process is killed as it is not reachable
        end
    end.on_success(description: "#{self}#stop_event#command#dead!") do
        ready_to_die!
        begin
            orocos_process.kill(false)
        rescue Orocos::ComError
            # The underlying process server cannot be reached. Just emit
            # failed ourselves
            dead!(nil)
        end
    end
    stop_event.achieve_asynchronously(promise, emit_on_success: false)
end

#stop?Boolean

method: stop!

Stops all tasks that are running on top of this deployment, and kill the deployment

Returns:

  • (Boolean)


650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
# File 'lib/syskit/deployment.rb', line 650

event :stop do |context|
    quit_ready_event_monitor.set
    promise = execution_engine.promise(description: "#{self}.stop_event.on") do
        begin
            remote_task_handles.each_value do |remote_task|
                remote_task.state_getter.disconnect
                if remote_task.handle.rtt_state == :STOPPED
                    remote_task.handle.cleanup(false)
                end
            end
            remote_task_handles.each_value do |remote_task|
                remote_task.state_getter.join
            end
        rescue Orocos::ComError
            # Assume that the process is killed as it is not reachable
        end
    end.on_success(description: "#{self}#stop_event#command#dead!") do
        ready_to_die!
        begin
            orocos_process.kill(false)
        rescue Orocos::ComError
            # The underlying process server cannot be reached. Just emit
            # failed ourselves
            dead!(nil)
        end
    end
    stop_event.achieve_asynchronously(promise, emit_on_success: false)
end

#stop_eventEventGenerator

method: stop!

Stops all tasks that are running on top of this deployment, and kill the deployment

Returns:

  • (EventGenerator)


650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
# File 'lib/syskit/deployment.rb', line 650

event :stop do |context|
    quit_ready_event_monitor.set
    promise = execution_engine.promise(description: "#{self}.stop_event.on") do
        begin
            remote_task_handles.each_value do |remote_task|
                remote_task.state_getter.disconnect
                if remote_task.handle.rtt_state == :STOPPED
                    remote_task.handle.cleanup(false)
                end
            end
            remote_task_handles.each_value do |remote_task|
                remote_task.state_getter.join
            end
        rescue Orocos::ComError
            # Assume that the process is killed as it is not reachable
        end
    end.on_success(description: "#{self}#stop_event#command#dead!") do
        ready_to_die!
        begin
            orocos_process.kill(false)
        rescue Orocos::ComError
            # The underlying process server cannot be reached. Just emit
            # failed ourselves
            dead!(nil)
        end
    end
    stop_event.achieve_asynchronously(promise, emit_on_success: false)
end

#task(name, syskit_task_model = nil) ⇒ Object

Returns an task instance that represents the given task in this deployment.

Parameters:

  • name (String)

    the unmapped name of the task

  • syskit_task_model (Models::TaskContext, nil) (defaults to: nil)

    the Syskit model that should be used to create the task, if it is not the same as the base model. This is used for specialized models (e.g. dynamic services)



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/syskit/deployment.rb', line 222

def task(name, syskit_task_model = nil)
    if finishing? || finished?
        raise InvalidState, "#{self} is either finishing or already "\
            "finished, you cannot call #task"
    end

    orogen_task_deployment_model = deployed_orogen_model_by_name(name)

    if orogen_master = orogen_task_deployment_model.master
        scheduler_task = find_or_create_task(
            orogen_master.name, auto_conf: true)
    end
    create_deployed_task(orogen_task_deployment_model,
        syskit_task_model, scheduler_task)
end

#update_current_configuration(orocos_name, model, conf, current_dynamic_services) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Update the last known configuration of a task



528
529
530
531
532
533
# File 'lib/syskit/deployment.rb', line 528

def update_current_configuration(orocos_name, model, conf, current_dynamic_services)
    task_info = remote_task_handles[orocos_name]
    task_info.needs_reconfiguration = false
    task_info.current_configuration =
        CurrentTaskConfiguration.new(model, conf, current_dynamic_services)
end