Class: OpenC3::ReactionMicroservice

Inherits:
Microservice show all
Defined in:
lib/openc3/microservices/reaction_microservice.rb

Overview

The reaction microservice starts a manager then gets the reactions and triggers from redis. It then monitors the AutonomicTopic for changes.

Constant Summary collapse

TOPIC_LOOKUP =
{
  'group' => {
    'created' => :no_op,
    'updated' => :no_op,
    'deleted' => :no_op,
  },
  'trigger' => {
    'error' => :no_op,
    'created' => :no_op,
    'updated' => :no_op,
    'deleted' => :no_op,
    'enabled' => :no_op,
    'disabled' => :no_op,
    'true' => :trigger_true_event,
    'false' => :no_op,
  },
  'reaction' => {
    'run' => :no_op,
    'deployed' => :no_op,
    'undeployed' => :no_op,
    'created' => :reaction_created_event,
    'updated' => :reaction_updated_event,
    'deleted' => :reaction_deleted_event,
    'enabled' => :reaction_enabled_event,
    'disabled' => :reaction_disabled_event,
    'snoozed' => :no_op,
    'awakened' => :no_op,
    'executed' => :reaction_execute_event,
  }
}

Instance Attribute Summary collapse

Attributes inherited from Microservice

#count, #custom, #error, #logger, #microservice_status_thread, #secrets, #state

Instance Method Summary collapse

Methods inherited from Microservice

#as_json, #microservice_cmd, run, #setup_microservice_topic

Constructor Details

#initialize(*args) ⇒ ReactionMicroservice

Returns a new instance of ReactionMicroservice.



477
478
479
480
481
482
483
484
# File 'lib/openc3/microservices/reaction_microservice.rb', line 477

def initialize(*args)
  # The name is passed in via the reaction_model as "#{scope}__OPENC3__REACTION"
  super(*args)
  @share = ReactionShare.new(scope: @scope)
  @manager = ReactionSnoozeManager.new(name: @name, logger: @logger, scope: @scope, share: @share)
  @manager_thread = nil
  @read_topic = true
end

Instance Attribute Details

#managerObject (readonly)

Returns the value of attribute manager.



445
446
447
# File 'lib/openc3/microservices/reaction_microservice.rb', line 445

def manager
  @manager
end

#manager_threadObject (readonly)

Returns the value of attribute manager_thread.



445
446
447
# File 'lib/openc3/microservices/reaction_microservice.rb', line 445

def manager_thread
  @manager_thread
end

#nameObject (readonly)

Returns the value of attribute name.



445
446
447
# File 'lib/openc3/microservices/reaction_microservice.rb', line 445

def name
  @name
end

#scopeObject (readonly)

Returns the value of attribute scope.



445
446
447
# File 'lib/openc3/microservices/reaction_microservice.rb', line 445

def scope
  @scope
end

#shareObject (readonly)

Returns the value of attribute share.



445
446
447
# File 'lib/openc3/microservices/reaction_microservice.rb', line 445

def share
  @share
end

Instance Method Details

#block_for_updatesObject



511
512
513
514
515
516
517
518
519
520
521
522
523
# File 'lib/openc3/microservices/reaction_microservice.rb', line 511

def block_for_updates
  @read_topic = true
  while @read_topic && !@cancel_thread
    begin
      AutonomicTopic.read_topics(@topics) do |_topic, _msg_id, msg_hash, _redis|
        @logger.debug "ReactionMicroservice block_for_updates: #{msg_hash.to_s}"
        public_send(TOPIC_LOOKUP[msg_hash['type']][msg_hash['kind']], msg_hash)
      end
    rescue StandardError => e
      @logger.error "ReactionMicroservice failed to read topics #{@topics}\n#{e.formatted}"
    end
  end
end

#no_op(data) ⇒ Object



525
526
527
# File 'lib/openc3/microservices/reaction_microservice.rb', line 525

def no_op(data)
  @logger.debug "ReactionMicroservice web socket event: #{data}"
end

#reaction_created_event(msg_hash) ⇒ Object

Add the reaction to the shared data.



542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
# File 'lib/openc3/microservices/reaction_microservice.rb', line 542

def reaction_created_event(msg_hash)
  @logger.debug "ReactionMicroservice reaction created msg_hash: #{msg_hash}"
  reaction = JSON.parse(msg_hash['data'], :allow_nan => true, :create_additions => true)
  @share.reaction_base.add(reaction: reaction)

  # If the reaction triggerLevel is LEVEL we have to check its triggers
  # on add because if the trigger is active it should run
  if reaction['triggerLevel'] == 'LEVEL'
    reaction['triggers'].each do |trigger_hash|
      trigger = TriggerModel.get(name: trigger_hash['name'], group: trigger_hash['group'], scope: reaction['scope'])
      if trigger && trigger.state
        @logger.info "ReactionMicroservice reaction #{reaction['name']} created. Since triggerLevel is 'LEVEL' it was run due to #{trigger.name}."
        @share.queue_base.enqueue(kind: 'reaction', data: reaction)
      end
    end
  end
end

#reaction_deleted_event(msg_hash) ⇒ Object

Remove the reaction from the shared data



594
595
596
597
# File 'lib/openc3/microservices/reaction_microservice.rb', line 594

def reaction_deleted_event(msg_hash)
  @logger.debug "ReactionMicroservice reaction deleted msg_hash: #{msg_hash}"
  @share.reaction_base.remove(reaction: JSON.parse(msg_hash['data'], :allow_nan => true, :create_additions => true))
end

#reaction_disabled_event(msg_hash) ⇒ Object

Update the reaction to the shared data.



580
581
582
583
# File 'lib/openc3/microservices/reaction_microservice.rb', line 580

def reaction_disabled_event(msg_hash)
  @logger.debug "ReactionMicroservice reaction disabled msg_hash: #{msg_hash}"
  @share.reaction_base.update(reaction: JSON.parse(msg_hash['data'], :allow_nan => true, :create_additions => true))
end

#reaction_enabled_event(msg_hash) ⇒ Object

Update the reaction to the shared data.



561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
# File 'lib/openc3/microservices/reaction_microservice.rb', line 561

def reaction_enabled_event(msg_hash)
  @logger.debug "ReactionMicroservice reaction enabled msg_hash: #{msg_hash}"
  reaction = JSON.parse(msg_hash['data'], :allow_nan => true, :create_additions => true)
  @share.reaction_base.update(reaction: reaction)

  # If the reaction triggerLevel is LEVEL we have to check its triggers
  # on add because if the trigger is active it should run
  if reaction['triggerLevel'] == 'LEVEL'
    reaction['triggers'].each do |trigger_hash|
      trigger = TriggerModel.get(name: trigger_hash['name'], group: trigger_hash['group'], scope: reaction['scope'])
      if trigger && trigger.state
        @logger.info "ReactionMicroservice reaction #{reaction['name']} enabled. Since triggerLevel is 'LEVEL' it was run due to #{trigger.name}."
        @share.queue_base.enqueue(kind: 'reaction', data: reaction)
      end
    end
  end
end

#reaction_execute_event(msg_hash) ⇒ Object

Add the reaction to the shared data.



586
587
588
589
590
591
# File 'lib/openc3/microservices/reaction_microservice.rb', line 586

def reaction_execute_event(msg_hash)
  @logger.debug "ReactionMicroservice reaction execute msg_hash: #{msg_hash}"
  reaction = JSON.parse(msg_hash['data'], :allow_nan => true, :create_additions => true)
  @share.reaction_base.update(reaction: reaction)
  @share.queue_base.enqueue(kind: 'reaction', data: reaction)
end

#reaction_updated_event(msg_hash) ⇒ Object



529
530
531
532
533
534
# File 'lib/openc3/microservices/reaction_microservice.rb', line 529

def reaction_updated_event(msg_hash)
  @logger.debug "ReactionMicroservice reaction updated msg_hash: #{msg_hash}"
  reaction = JSON.parse(msg_hash['data'], :allow_nan => true, :create_additions => true)
  @share.reaction_base.update(reaction: reaction)
  @read_topic = false
end

#runObject



486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
# File 'lib/openc3/microservices/reaction_microservice.rb', line 486

def run
  @logger.info "ReactionMicroservice running"
  # Let the frontend know that the microservice has been deployed and is running
  notification = {
    'kind' => 'deployed',
    'type' => 'reaction',
    # name and updated_at fields are required for Event formatting
    'data' => JSON.generate({
      'name' => @name,
      'updated_at' => Time.now.to_nsec_from_epoch,
    }),
  }
  AutonomicTopic.write_notification(notification, scope: @scope)

  @manager_thread = Thread.new { @manager.run }
  loop do
    reactions = ReactionModel.all(scope: @scope)
    @share.reaction_base.setup(reactions: reactions)
    break if @cancel_thread
    block_for_updates()
    break if @cancel_thread
  end
  @logger.info "ReactionMicroservice exiting"
end

#shutdownObject



599
600
601
602
603
# File 'lib/openc3/microservices/reaction_microservice.rb', line 599

def shutdown
  @read_topic = false
  @manager.shutdown()
  super
end

#trigger_true_event(msg_hash) ⇒ Object



536
537
538
539
# File 'lib/openc3/microservices/reaction_microservice.rb', line 536

def trigger_true_event(msg_hash)
  @logger.debug "ReactionMicroservice trigger true msg_hash: #{msg_hash}"
  @share.queue_base.enqueue(kind: 'trigger', data: JSON.parse(msg_hash['data'], :allow_nan => true, :create_additions => true))
end