flor 1.0.1 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/LICENSE.txt +1 -1
- data/README.md +1 -1
- data/lib/flor.rb +2 -1
- data/lib/flor/core/texecutor.rb +26 -1
- data/lib/flor/flor.rb +24 -6
- data/lib/flor/log.rb +12 -7
- data/lib/flor/punit/c_iterator.rb +1 -1
- data/lib/flor/punit/concurrence.rb +6 -5
- data/lib/flor/punit/{m_ram.rb → m_receive_and_merge.rb} +0 -0
- data/lib/flor/tools/firb.rb +33 -0
- data/lib/flor/tools/shell.rb +12 -3
- data/lib/flor/unit.rb +1 -0
- data/lib/flor/unit/caller.rb +6 -4
- data/lib/flor/unit/caller_jruby.rb +8 -7
- data/lib/flor/unit/executor.rb +18 -13
- data/lib/flor/unit/ganger.rb +3 -0
- data/lib/flor/unit/gangers.rb +125 -0
- data/lib/flor/unit/loader.rb +42 -10
- data/lib/flor/unit/logger.rb +11 -2
- data/lib/flor/unit/models/message.rb +5 -0
- data/lib/flor/unit/models/pointer.rb +20 -1
- data/lib/flor/unit/scheduler.rb +13 -8
- data/lib/flor/unit/storage.rb +53 -44
- data/lib/flor/unit/taskers.rb +68 -0
- data/lib/flor/unit/waiter.rb +2 -2
- metadata +5 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: f1dae0857de545986e18ad31a41f37a6ead6687b34d3c06de22aafa606369283
         | 
| 4 | 
            +
              data.tar.gz: 9843d0124a2c3948ffc6846e7854854f5eda37d95bd02bfc02cecfefab0e5ea1
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 185490e0054ffdfe7c078b71955834679a398266e613be5d8bb6b63bc626bf4727bd4fd45249e7dea14cdd91a85c5ad92a1f6b3b120117c7c274b41d5478ba31
         | 
| 7 | 
            +
              data.tar.gz: e6dde7ae40f3ef6d2c7a620d6a07840c6591b745798962d039ac39fa426e4bcef51f3c67e97d9a367bb981918ec5fe98934393eec2cd7e87046b8d491b9a6511
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -2,6 +2,36 @@ | |
| 2 2 | 
             
            # CHANGELOG.md
         | 
| 3 3 |  | 
| 4 4 |  | 
| 5 | 
            +
            ## flor 1.2.2  released 2021-03-29
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            * Include data in flor_pointers
         | 
| 8 | 
            +
            * Ensure flor_pointers name is a string
         | 
| 9 | 
            +
             | 
| 10 | 
            +
             | 
| 11 | 
            +
            ## flor 1.2.1  released 2021-03-22
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            * If conf sto_db_logger is false, do not attach a logger to the db connection
         | 
| 14 | 
            +
             | 
| 15 | 
            +
             | 
| 16 | 
            +
            ## flor 1.2.0  released 2021-03-15
         | 
| 17 | 
            +
             | 
| 18 | 
            +
            * Add #attd, #attl, #att_texts to Flor::Pointer
         | 
| 19 | 
            +
             | 
| 20 | 
            +
             | 
| 21 | 
            +
            ## flor 1.1.1  released 2021-03-03
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            * Use YAML to have more compact msg_to_detail_s
         | 
| 24 | 
            +
             | 
| 25 | 
            +
             | 
| 26 | 
            +
            ## flor 1.1.0  released 2021-01-06
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            * Introduce Tasker #set_payload and #set_vars
         | 
| 29 | 
            +
            * Introduce the ModuleGanger
         | 
| 30 | 
            +
            * Allow for domain/dot.json taskers
         | 
| 31 | 
            +
            * Introduce Flor::StagedBasicTasker
         | 
| 32 | 
            +
            * Fix service/executor issue in Caller
         | 
| 33 | 
            +
             | 
| 34 | 
            +
             | 
| 5 35 | 
             
            ## flor 1.0.1  released 2020-11-23
         | 
| 6 36 |  | 
| 7 37 | 
             
            * Accept sto_uri strings pointing to constant like 'DB'
         | 
    
        data/LICENSE.txt
    CHANGED
    
    | @@ -1,5 +1,5 @@ | |
| 1 1 |  | 
| 2 | 
            -
            Copyright (c) 2015- | 
| 2 | 
            +
            Copyright (c) 2015-2021, John Mettraux, jmettraux+flor@gmail.com
         | 
| 3 3 |  | 
| 4 4 | 
             
            Permission is hereby granted, free of charge, to any person obtaining a copy
         | 
| 5 5 | 
             
            of this software and associated documentation files (the "Software"), to deal
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 |  | 
| 2 2 | 
             
            # flor
         | 
| 3 3 |  | 
| 4 | 
            -
            [](https://github.com/floraison/flor/actions)
         | 
| 5 5 | 
             
            [](http://badge.fury.io/rb/flor)
         | 
| 6 6 |  | 
| 7 7 | 
             
            Flor is a "Ruby workflow engine", if that makes any sense.
         | 
    
        data/lib/flor.rb
    CHANGED
    
    
    
        data/lib/flor/core/texecutor.rb
    CHANGED
    
    | @@ -254,7 +254,7 @@ module Flor | |
| 254 254 | 
             
                      o.each { |ee| ee['_path'] = path if ee.is_a?(Hash) }
         | 
| 255 255 | 
             
                    end
         | 
| 256 256 |  | 
| 257 | 
            -
                    o
         | 
| 257 | 
            +
                    rework_conf(o)
         | 
| 258 258 | 
             
                  end
         | 
| 259 259 |  | 
| 260 260 | 
             
                  def interpret_path(path, context=nil)
         | 
| @@ -299,6 +299,31 @@ module Flor | |
| 299 299 |  | 
| 300 300 | 
             
                    ps.last == 'etc' ? File.absolute_path(File.join(dir, '..')) : dir
         | 
| 301 301 | 
             
                  end
         | 
| 302 | 
            +
             | 
| 303 | 
            +
                  protected
         | 
| 304 | 
            +
             | 
| 305 | 
            +
                  # For now, only the return procedure has to be marshalled back
         | 
| 306 | 
            +
                  # to the "return" string, gh-36
         | 
| 307 | 
            +
                  #
         | 
| 308 | 
            +
                  def rework_conf(o)
         | 
| 309 | 
            +
             | 
| 310 | 
            +
                    case o
         | 
| 311 | 
            +
                    when Array
         | 
| 312 | 
            +
                      o.collect { |e|
         | 
| 313 | 
            +
                        rework_conf(e) }
         | 
| 314 | 
            +
                    when Hash
         | 
| 315 | 
            +
                      o.inject({}) { |h, (k, v)|
         | 
| 316 | 
            +
                        h[k] =
         | 
| 317 | 
            +
                          if Flor.is_proc_tree?(v) && v[1]['proc'] == 'return'
         | 
| 318 | 
            +
                            'return'
         | 
| 319 | 
            +
                          else
         | 
| 320 | 
            +
                            rework_conf(v)
         | 
| 321 | 
            +
                          end
         | 
| 322 | 
            +
                        h }
         | 
| 323 | 
            +
                    else
         | 
| 324 | 
            +
                      o
         | 
| 325 | 
            +
                    end
         | 
| 326 | 
            +
                  end
         | 
| 302 327 | 
             
                end
         | 
| 303 328 | 
             
              end
         | 
| 304 329 | 
             
            end
         | 
    
        data/lib/flor/flor.rb
    CHANGED
    
    | @@ -20,7 +20,7 @@ module Flor | |
| 20 20 | 
             
                signal cancel
         | 
| 21 21 | 
             
                terminated failed ceased
         | 
| 22 22 | 
             
                idle
         | 
| 23 | 
            -
             | 
| 23 | 
            +
                  ].freeze
         | 
| 24 24 |  | 
| 25 25 | 
             
              class << self
         | 
| 26 26 |  | 
| @@ -279,13 +279,19 @@ module Flor | |
| 279 279 | 
             
                #
         | 
| 280 280 | 
             
                # functions about time
         | 
| 281 281 |  | 
| 282 | 
            +
                # Used by the storage in its next_time endeavours
         | 
| 283 | 
            +
                #
         | 
| 284 | 
            +
                def tstam
         | 
| 285 | 
            +
                  Time.now.utc.strftime('%FT%T')
         | 
| 286 | 
            +
                end
         | 
| 287 | 
            +
             | 
| 282 288 | 
             
                def isostamp(show_date, show_time, show_usec, time)
         | 
| 283 289 |  | 
| 284 290 | 
             
                  t = (time || Time.now).utc
         | 
| 285 291 | 
             
                  s = StringIO.new
         | 
| 286 292 |  | 
| 287 | 
            -
                  s << t.strftime('% | 
| 288 | 
            -
                  s << t.strftime('T% | 
| 293 | 
            +
                  s << t.strftime('%F') if show_date   # YYYY-mm-dd
         | 
| 294 | 
            +
                  s << t.strftime('T%T') if show_time  # THH:MM:SS
         | 
| 289 295 | 
             
                  s << sprintf('.%06d', t.usec) if show_time && show_usec
         | 
| 290 296 | 
             
                  s << 'Z' if show_time
         | 
| 291 297 |  | 
| @@ -323,6 +329,11 @@ module Flor | |
| 323 329 | 
             
                  isostamp(false, true, true, t)
         | 
| 324 330 | 
             
                end
         | 
| 325 331 |  | 
| 332 | 
            +
                def monow
         | 
| 333 | 
            +
             | 
| 334 | 
            +
                  Process.clock_gettime(Process::CLOCK_MONOTONIC)
         | 
| 335 | 
            +
                end
         | 
| 336 | 
            +
             | 
| 326 337 | 
             
            #  def to_time(ts)
         | 
| 327 338 | 
             
            #
         | 
| 328 339 | 
             
            #    m = ts.match(/\A(\d{4})(\d{2})(\d{2})\.(\d{2})(\d{2})(\d{2})(\d+)([uU]?)\z/)
         | 
| @@ -367,11 +378,18 @@ module Flor | |
| 367 378 | 
             
                  sub_domain?(dom, sub)
         | 
| 368 379 | 
             
                end
         | 
| 369 380 |  | 
| 381 | 
            +
                def dot_join(*elts)
         | 
| 382 | 
            +
             | 
| 383 | 
            +
                  elts.collect(&:to_s).select { |e| e.length > 0 }.join('.')
         | 
| 384 | 
            +
                end
         | 
| 385 | 
            +
             | 
| 370 386 | 
             
                def sub_domain?(dom, sub)
         | 
| 371 387 |  | 
| 372 | 
            -
                  dom  | 
| 373 | 
            -
             | 
| 374 | 
            -
                   | 
| 388 | 
            +
                  d = dom.is_a?(Array) ? dot_join(*dom) : dom.to_s
         | 
| 389 | 
            +
             | 
| 390 | 
            +
                  d == '' ||
         | 
| 391 | 
            +
                  sub == d ||
         | 
| 392 | 
            +
                  sub[0, d.length + 1] == d + '.'
         | 
| 375 393 | 
             
                end
         | 
| 376 394 | 
             
                alias subdomain? sub_domain?
         | 
| 377 395 |  | 
    
        data/lib/flor/log.rb
    CHANGED
    
    | @@ -324,6 +324,7 @@ module Flor | |
| 324 324 | 
             
                def msg_to_detail_s(executor, m, opts={})
         | 
| 325 325 |  | 
| 326 326 | 
             
                  return if m['_detail_msg_flag']
         | 
| 327 | 
            +
                    #
         | 
| 327 328 | 
             
                  m['_detail_msg_flag'] = true if opts[:flag]
         | 
| 328 329 |  | 
| 329 330 | 
             
                  o = StringIO.new
         | 
| @@ -333,18 +334,22 @@ module Flor | |
| 333 334 | 
             
                  n = executor.execution['nodes'][nid]
         | 
| 334 335 | 
             
                  node = n ? Flor::Node.new(executor, n, m) : nil
         | 
| 335 336 |  | 
| 336 | 
            -
                  o.puts "#{_c. | 
| 337 | 
            -
             | 
| 338 | 
            -
                  o.puts "#{_c.dg} | 
| 339 | 
            -
                  o.puts  | 
| 340 | 
            -
             | 
| 337 | 
            +
                  o.puts "#{_c.rs}#{_c.dg}<Flor.msg_to_detail_s>"
         | 
| 338 | 
            +
             | 
| 339 | 
            +
                  o.puts "#{_c.dg}message:#{_c.yl}"
         | 
| 340 | 
            +
                  o.puts YAML.dump(m)
         | 
| 341 | 
            +
             | 
| 342 | 
            +
                  o.puts "#{_c.dg}tree:#{_c.yl}"
         | 
| 341 343 | 
             
                  o.puts(tree_to_s(node.lookup_tree(nid), nid, out: o)) if node
         | 
| 344 | 
            +
             | 
| 342 345 | 
             
                  o.puts "#{_c.dg}node:#{_c.yl}"
         | 
| 343 | 
            -
                  o.puts( | 
| 344 | 
            -
             | 
| 346 | 
            +
                  o.puts YAML.dump(n.merge('tree' => '(above)'))
         | 
| 347 | 
            +
             | 
| 348 | 
            +
                  o.puts "#{_c.dg}nodes:#{_c.yl}"
         | 
| 345 349 | 
             
                  o.puts nods_to_s(executor, m, opts)
         | 
| 346 350 | 
             
                  z = executor.execution['nodes'].size
         | 
| 347 351 | 
             
                  o.puts "#{_c.yl}#{z} node#{z == 1 ? '' : 's'}."
         | 
| 352 | 
            +
             | 
| 348 353 | 
             
                  o.puts "#{_c.dg}</Flor.msg_to_detail_s>#{_c.rs}"
         | 
| 349 354 |  | 
| 350 355 | 
             
                  o.string
         | 
| @@ -1,6 +1,6 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require 'flor/punit/ | 
| 3 | 
            +
            require 'flor/punit/m_receive_and_merge'
         | 
| 4 4 |  | 
| 5 5 |  | 
| 6 6 | 
             
            class Flor::Pro::Concurrence < Flor::Procedure
         | 
| @@ -387,10 +387,11 @@ class Flor::Pro::Concurrence < Flor::Procedure | |
| 387 387 |  | 
| 388 388 | 
             
              REWRITE_AS_ATTS = %w[
         | 
| 389 389 | 
             
                on_receive on_merge
         | 
| 390 | 
            -
                child_on_error children_on_error | 
| 391 | 
            -
                   | 
| 392 | 
            -
             | 
| 393 | 
            -
             | 
| 390 | 
            +
                child_on_error children_on_error
         | 
| 391 | 
            +
                  ].freeze
         | 
| 392 | 
            +
                    #
         | 
| 393 | 
            +
                    # heads of the child nodes that should get rewritten as attributes
         | 
| 394 | 
            +
                    # of the concurrence ...
         | 
| 394 395 |  | 
| 395 396 | 
             
              def pre_execute_rewrite
         | 
| 396 397 |  | 
| 
            File without changes
         | 
| @@ -0,0 +1,33 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'irb'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            #require 'sequel'
         | 
| 6 | 
            +
            require 'flor'
         | 
| 7 | 
            +
            require 'flor/unit'
         | 
| 8 | 
            +
             | 
| 9 | 
            +
             | 
| 10 | 
            +
            p [ RUBY_VERSION, RUBY_PLATFORM ]
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            puts
         | 
| 13 | 
            +
             | 
| 14 | 
            +
            ENV.each do |k, v|
         | 
| 15 | 
            +
              next unless k.match?(/RUBY|GEM/)
         | 
| 16 | 
            +
              puts "* #{k}: #{v}"
         | 
| 17 | 
            +
            end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            ARGV.each do |arg|
         | 
| 20 | 
            +
              if arg.match(/:/)
         | 
| 21 | 
            +
                DB = Sequel.connect(arg)
         | 
| 22 | 
            +
                p DB
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            #MODELS = [ :executions, :timers, :traces, :traps, :pointers, :messages ]
         | 
| 27 | 
            +
            if defined?(DB)
         | 
| 28 | 
            +
              Flor::Message.dataset = DB[:flor_messages]
         | 
| 29 | 
            +
            end
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            ARGV.clear
         | 
| 32 | 
            +
            IRB.start
         | 
| 33 | 
            +
             | 
    
        data/lib/flor/tools/shell.rb
    CHANGED
    
    | @@ -15,11 +15,16 @@ module Flor::Tools | |
| 15 15 | 
             
                def initialize(argv=nil)
         | 
| 16 16 |  | 
| 17 17 | 
             
                  env = ENV['FLOR_ENV'] || 'shell'
         | 
| 18 | 
            -
             | 
| 18 | 
            +
             | 
| 19 | 
            +
                  @root = File.directory?(env) ? env : "envs/#{env}"
         | 
| 19 20 |  | 
| 20 21 | 
             
                  prepare_home
         | 
| 21 22 |  | 
| 22 | 
            -
                   | 
| 23 | 
            +
                  over_conf = {}
         | 
| 24 | 
            +
                    #
         | 
| 25 | 
            +
                  c = ENV['FLOR_STO_URI']; over_conf['sto_uri'] = c if c
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  @unit = Flor::Unit.new("#{@root}/etc/conf.json", over_conf)
         | 
| 23 28 |  | 
| 24 29 | 
             
                  @unit.conf['unit'] = 'cli'
         | 
| 25 30 | 
             
                  #unit.hooker.add('journal', Flor::Journal)
         | 
| @@ -31,7 +36,11 @@ module Flor::Tools | |
| 31 36 | 
             
                  @mute = false
         | 
| 32 37 | 
             
                  @paging = true
         | 
| 33 38 |  | 
| 34 | 
            -
                   | 
| 39 | 
            +
                  if ENV['FLOR_NO_START']
         | 
| 40 | 
            +
                    @unit.check_migration_version
         | 
| 41 | 
            +
                  else
         | 
| 42 | 
            +
                    @unit.start
         | 
| 43 | 
            +
                  end
         | 
| 35 44 |  | 
| 36 45 | 
             
                  @flow_path = File.join(@root, 'home/scratch.flo')
         | 
| 37 46 | 
             
                  @ra_flow_path = File.join(@root, 'home/ra_scratch.flo')
         | 
    
        data/lib/flor/unit.rb
    CHANGED
    
    
    
        data/lib/flor/unit/caller.rb
    CHANGED
    
    | @@ -107,9 +107,11 @@ module Flor | |
| 107 107 | 
             
                  #
         | 
| 108 108 | 
             
                  # call
         | 
| 109 109 |  | 
| 110 | 
            -
                   | 
| 111 | 
            -
             | 
| 112 | 
            -
                  ms =  | 
| 110 | 
            +
                  pt = message['point']
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                  ms = [ "call_#{pt}", "on_#{pt}", :on_message, :on, pt ]
         | 
| 113 | 
            +
                  ms = ms + [ :on_cancel, :cancel ] if pt == 'detask'
         | 
| 114 | 
            +
             | 
| 113 115 | 
             
                  m = ms.find { |mm| o.respond_to?(mm) }
         | 
| 114 116 |  | 
| 115 117 | 
             
                  fail(
         | 
| @@ -121,7 +123,7 @@ module Flor | |
| 121 123 | 
             
                    case o.method(m).arity
         | 
| 122 124 | 
             
                    when 1 then o.send(m, message)
         | 
| 123 125 | 
             
                    when 2 then o.send(m, conf, message)
         | 
| 124 | 
            -
                    when 3 then o.send(m,  | 
| 126 | 
            +
                    when 3 then o.send(m, service, conf, message)
         | 
| 125 127 | 
             
                    when -1 then o.send(m, {
         | 
| 126 128 | 
             
                      service: service, configuration: conf, message: message })
         | 
| 127 129 | 
             
                    else o.send(m)
         | 
| @@ -23,7 +23,7 @@ module Flor | |
| 23 23 | 
             
                    @exitstatus = exitstatus
         | 
| 24 24 | 
             
                  end
         | 
| 25 25 |  | 
| 26 | 
            -
                  def pid; @process.pid; end
         | 
| 26 | 
            +
                  def pid; @process.pid; rescue; nil; end
         | 
| 27 27 | 
             
                end
         | 
| 28 28 |  | 
| 29 29 | 
             
                def spawn(conf, data)
         | 
| @@ -41,7 +41,7 @@ module Flor | |
| 41 41 | 
             
                  henv.each { |k, v| builder.environment.put(k, v) }
         | 
| 42 42 |  | 
| 43 43 | 
             
                  process = builder.start
         | 
| 44 | 
            -
                  pid = process.pid
         | 
| 44 | 
            +
                  pid = process.respond_to?(:pid) ?  process.pid : nil
         | 
| 45 45 |  | 
| 46 46 | 
             
                  o = process.outputStream.to_io
         | 
| 47 47 | 
             
                  i = process.inputStream.to_io
         | 
| @@ -61,10 +61,12 @@ module Flor | |
| 61 61 |  | 
| 62 62 | 
             
                rescue => err
         | 
| 63 63 |  | 
| 64 | 
            -
                   | 
| 65 | 
            -
                     | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 64 | 
            +
                  if pid
         | 
| 65 | 
            +
                    Process.detach(pid)
         | 
| 66 | 
            +
                    (Process.kill(9, pid) rescue nil) unless Flor.no?(conf['on_error_kill'])
         | 
| 67 | 
            +
                  else
         | 
| 68 | 
            +
                    process.destroy rescue nil
         | 
| 69 | 
            +
                  end
         | 
| 68 70 |  | 
| 69 71 | 
             
                  raise err if err.is_a?(SpawnError)
         | 
| 70 72 | 
             
                  raise WrappedSpawnError.new(conf, { to: to, t0: t0, pid: pid }, err)
         | 
| @@ -72,7 +74,6 @@ module Flor | |
| 72 74 | 
             
                ensure
         | 
| 73 75 |  | 
| 74 76 | 
             
                  [ i, o, f ].each { |x| x.close rescue nil }
         | 
| 75 | 
            -
             | 
| 76 77 | 
             
                end
         | 
| 77 78 |  | 
| 78 79 | 
             
                module CmdParser include Raabro
         | 
    
        data/lib/flor/unit/executor.rb
    CHANGED
    
    | @@ -109,15 +109,13 @@ module Flor | |
| 109 109 | 
             
                rescue Exception => exc
         | 
| 110 110 |  | 
| 111 111 | 
             
            # TODO eventually, have a dump dir
         | 
| 112 | 
            +
             | 
| 112 113 | 
             
                  fn =
         | 
| 113 | 
            -
                    [
         | 
| 114 | 
            -
                      ' | 
| 115 | 
            -
                      @unit.conf['env'], @unit.identifier, @exid,
         | 
| 116 | 
            -
                      'r' + counter('runs').to_s
         | 
| 117 | 
            -
                    ].collect(&:to_s).join('_') + '.dump'
         | 
| 114 | 
            +
                    [ 'flor', @unit.conf['env'], @unit.identifier, @exid,
         | 
| 115 | 
            +
                      'r' + counter('runs').to_s ].collect(&:to_s).join('_') + '.dump'
         | 
| 118 116 |  | 
| 119 117 | 
             
                  @unit.logger.error(
         | 
| 120 | 
            -
                    "#{self.class}#do_run()", exc, "(dumping to #{fn})")
         | 
| 118 | 
            +
                    "#{self.class}#do_run()", exc, "(dumping to #{fn} ...)")
         | 
| 121 119 |  | 
| 122 120 | 
             
                  File.open(fn, 'wb') do |f|
         | 
| 123 121 | 
             
                    f.puts(Flor.to_pretty_s({
         | 
| @@ -134,19 +132,26 @@ module Flor | |
| 134 132 | 
             
                    f.puts(on_do_run_exc(exc))
         | 
| 135 133 | 
             
                  end
         | 
| 136 134 |  | 
| 135 | 
            +
                  @unit.logger.error(
         | 
| 136 | 
            +
                    "#{self.class}#do_run()", exc, "(dumped to #{fn})")
         | 
| 137 | 
            +
             | 
| 137 138 | 
             
                  #puts on_do_run_exc(exc)
         | 
| 138 139 | 
             
                    # dump notification above
         | 
| 139 140 | 
             
                end
         | 
| 140 141 |  | 
| 141 142 | 
             
                def task(message)
         | 
| 142 143 |  | 
| 143 | 
            -
                   | 
| 144 | 
            -
             | 
| 145 | 
            -
                    message | 
| 146 | 
            -
                     | 
| 147 | 
            -
             | 
| 148 | 
            -
                     | 
| 149 | 
            -
             | 
| 144 | 
            +
                  if message['routed'] == false
         | 
| 145 | 
            +
             | 
| 146 | 
            +
                    t = message['tasker']
         | 
| 147 | 
            +
                    n = node(message['nid'])
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                    msg = n['heat0'] != t ?
         | 
| 150 | 
            +
                      "tasker #{t.inspect} not found" :
         | 
| 151 | 
            +
                      "don't know how to apply #{t.inspect}"
         | 
| 152 | 
            +
             | 
| 153 | 
            +
                    return error_reply(n, message, msg)
         | 
| 154 | 
            +
                  end
         | 
| 150 155 |  | 
| 151 156 | 
             
                  @unit.ganger.task(self, message)
         | 
| 152 157 | 
             
                end
         | 
    
        data/lib/flor/unit/ganger.rb
    CHANGED
    
    | @@ -54,6 +54,9 @@ module Flor | |
| 54 54 | 
             
                     (@unit.loader.tasker(domain, 'ganger', message) ||
         | 
| 55 55 | 
             
                      @unit.loader.tasker(domain, 'tasker', message))) ||
         | 
| 56 56 | 
             
                    @unit.loader.tasker(domain, tname, message)
         | 
| 57 | 
            +
            #puts "=" * 80
         | 
| 58 | 
            +
            #pp tconf
         | 
| 59 | 
            +
            #puts "=" * 80
         | 
| 57 60 |  | 
| 58 61 | 
             
                  fail ArgumentError.new(
         | 
| 59 62 | 
             
                    "tasker #{tname.inspect} not found"
         | 
| @@ -0,0 +1,125 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            module Flor
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              # A ModuleGanger accepts a `module:` conf entry that points to a Ruby
         | 
| 6 | 
            +
              # module. The tasker implementations are searched for among the classes
         | 
| 7 | 
            +
              # in the given module.
         | 
| 8 | 
            +
              #
         | 
| 9 | 
            +
              # Among the tasker classes (classes that respond to on_task, on_detask, ...)
         | 
| 10 | 
            +
              # it selects the first tasker that matches the tasker name.
         | 
| 11 | 
            +
              #
         | 
| 12 | 
            +
              class ModuleGanger
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                def initialize(service, conf, message)
         | 
| 15 | 
            +
             | 
| 16 | 
            +
                  @service = service
         | 
| 17 | 
            +
                  @conf = conf
         | 
| 18 | 
            +
                  @message = message
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                def task
         | 
| 22 | 
            +
             | 
| 23 | 
            +
                  tas = @message['tasker']
         | 
| 24 | 
            +
                  clas = list_tasker_classes
         | 
| 25 | 
            +
                  cla = clas.find { |c| tasker_name(c) == tas }
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                  return [ Flor.dup_and_merge(@message, 'routed' => false) ] \
         | 
| 28 | 
            +
                    unless cla
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                  call_tasker(cla)
         | 
| 31 | 
            +
                end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                alias detask task
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                protected
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                def list_tasker_classes
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                  mod_name = @conf['module']
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  fail ArgumentError.new('ganger module: configuration entry missing') \
         | 
| 42 | 
            +
                    unless mod_name
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  mod = Flor.const_lookup(mod_name) rescue nil
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  fail ArgumentError.new("ganger cannot find module #{mod_name.inspect}") \
         | 
| 47 | 
            +
                    unless mod
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                  list_classes(mod, [])
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def list_classes(start, r)
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                  # place leave classes on top if possible
         | 
| 55 | 
            +
                  # within a level, sort alphabetically
         | 
| 56 | 
            +
             | 
| 57 | 
            +
                  clas = start.constants.collect { |co| start.const_get(co) }
         | 
| 58 | 
            +
                  clas, mods = clas.partition { |c| c.is_a?(Class) }
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                  mods.each { |m| list_classes(m, r) }
         | 
| 61 | 
            +
                  r.concat(clas.select { |c| tasker?(c) }.sort_by { |c| c.name })
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  r
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 66 | 
            +
                TASKER_METHODS = [
         | 
| 67 | 
            +
                  :on, :on_message,
         | 
| 68 | 
            +
                  :task, :on_task,
         | 
| 69 | 
            +
                  :detask, :on_detask, :cancel, :on_cancel
         | 
| 70 | 
            +
                    ].freeze
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                def tasker?(cla)
         | 
| 73 | 
            +
             | 
| 74 | 
            +
                  return true if (TASKER_METHODS & cla.public_instance_methods).any?
         | 
| 75 | 
            +
                  return true if (TASKER_METHODS & cla.public_methods).any?
         | 
| 76 | 
            +
                  false
         | 
| 77 | 
            +
                end
         | 
| 78 | 
            +
             | 
| 79 | 
            +
                def tasker_name(cla)
         | 
| 80 | 
            +
             | 
| 81 | 
            +
                  if cla.public_instance_methods.include?(:tasker_name)
         | 
| 82 | 
            +
             | 
| 83 | 
            +
                    unless cla.respond_to?(:_ganged)
         | 
| 84 | 
            +
                      class << cla
         | 
| 85 | 
            +
                        attr_accessor :_ganged
         | 
| 86 | 
            +
                      end
         | 
| 87 | 
            +
                      cla._ganged = cla.allocate
         | 
| 88 | 
            +
                    end
         | 
| 89 | 
            +
             | 
| 90 | 
            +
                    call_tasker_name(cla._ganged)
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                  elsif cla.public_methods.include?(:tasker_name)
         | 
| 93 | 
            +
             | 
| 94 | 
            +
                    call_tasker_name(cla)
         | 
| 95 | 
            +
             | 
| 96 | 
            +
                  else
         | 
| 97 | 
            +
             | 
| 98 | 
            +
                    cla.name.split('::').last.gsub(/Tasker\z/, '')
         | 
| 99 | 
            +
                      .gsub(/([a-z])([A-Z])/) { |_| $1 + '_' + $2.downcase }
         | 
| 100 | 
            +
                      .gsub(/([A-Z])/) { |c| c.downcase }
         | 
| 101 | 
            +
                  end
         | 
| 102 | 
            +
                end
         | 
| 103 | 
            +
             | 
| 104 | 
            +
                def call_tasker_name(o)
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                  case i = o.method(:tasker_name).arity
         | 
| 107 | 
            +
                  when 1 then o.tasker_name(@message)
         | 
| 108 | 
            +
                  when 2 then o.tasker_name(@conf, @message)
         | 
| 109 | 
            +
                  when 3 then o.tasker_name(@service, @conf, @message)
         | 
| 110 | 
            +
                  when -1 then o.tasker_name(
         | 
| 111 | 
            +
                    service: @service, conf: @conf, message: @message)
         | 
| 112 | 
            +
                  else o.tasker_name
         | 
| 113 | 
            +
                  end
         | 
| 114 | 
            +
                end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                def call_tasker(c)
         | 
| 117 | 
            +
             | 
| 118 | 
            +
                  cnf = @conf.merge('class' => c)
         | 
| 119 | 
            +
             | 
| 120 | 
            +
                  @service.unit.caller
         | 
| 121 | 
            +
                    .call(@service, cnf, @message)
         | 
| 122 | 
            +
                end
         | 
| 123 | 
            +
              end
         | 
| 124 | 
            +
            end
         | 
| 125 | 
            +
             | 
    
        data/lib/flor/unit/loader.rb
    CHANGED
    
    | @@ -46,7 +46,7 @@ module Flor | |
| 46 46 | 
             
                    .collect { |pa| [ pa, expose_d(pa, {}) ] }
         | 
| 47 47 | 
             
                    .select { |pa, d| Flor.sub_domain?(d, domain) }
         | 
| 48 48 | 
             
                    .sort_by { |pa, d| d.count('.') }
         | 
| 49 | 
            -
                    .inject({}) { |vars, (pa, _)| vars.merge!( | 
| 49 | 
            +
                    .inject({}) { |vars, (pa, _)| vars.merge!(eval_variables(pa, {})) }
         | 
| 50 50 | 
             
                end
         | 
| 51 51 |  | 
| 52 52 | 
             
                #def procedures(path)
         | 
| @@ -87,25 +87,28 @@ module Flor | |
| 87 87 | 
             
                    .select { |pa| pa.index('/lib/taskers/') }
         | 
| 88 88 | 
             
                    .collect { |pa| [ pa, *expose_dn(pa, {}) ] }
         | 
| 89 89 | 
             
                    .select { |pa, d, n|
         | 
| 90 | 
            -
                      Flor.sub_domain?([ d, n ] | 
| 90 | 
            +
                      Flor.sub_domain?([ d, n ], domain) ||
         | 
| 91 91 | 
             
                      (n == name && Flor.sub_domain?(d, domain)) }
         | 
| 92 92 | 
             
                    .sort_by { |pa, d, n| d.count('.') }
         | 
| 93 93 | 
             
                    .last
         | 
| 94 94 |  | 
| 95 95 | 
             
                  return nil unless pat
         | 
| 96 96 |  | 
| 97 | 
            -
                  conf =  | 
| 97 | 
            +
                  conf = eval_tasker_conf(pat, message)
         | 
| 98 98 |  | 
| 99 99 | 
             
                  return conf if nam == name
         | 
| 100 100 |  | 
| 101 | 
            -
                   | 
| 101 | 
            +
                  cnf = conf[name]
         | 
| 102 102 |  | 
| 103 | 
            -
                  return nil unless  | 
| 103 | 
            +
                  return nil unless cnf
         | 
| 104 104 |  | 
| 105 | 
            -
                   | 
| 106 | 
            -
             | 
| 105 | 
            +
                  extras = conf.select { |_, v| ! v.is_a?(Hash) }
         | 
| 106 | 
            +
                  extras['_path'] = pat
         | 
| 107 107 |  | 
| 108 | 
            -
                   | 
| 108 | 
            +
                  (cnf.is_a?(Array) ? cnf : [ cnf ])
         | 
| 109 | 
            +
                    .each { |h| h.merge!(extras) }
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                  cnf
         | 
| 109 112 | 
             
                end
         | 
| 110 113 |  | 
| 111 114 | 
             
                def hooks(domain)
         | 
| @@ -119,8 +122,8 @@ module Flor | |
| 119 122 | 
             
                    .select { |pa, d| Flor.sub_domain?(d, domain) }
         | 
| 120 123 | 
             
                    .sort_by { |pa, d| d.count('.') }
         | 
| 121 124 | 
             
                    .collect { |pa, d|
         | 
| 122 | 
            -
                       | 
| 123 | 
            -
                        .each_with_index { |h, i| h['_path'] = pa | 
| 125 | 
            +
                      eval_hook_conf(pa, {})
         | 
| 126 | 
            +
                        .each_with_index { |h, i| h['_path'] = "#{pa}:#{i}" } }
         | 
| 124 127 | 
             
                    .flatten(1)
         | 
| 125 128 | 
             
                end
         | 
| 126 129 |  | 
| @@ -247,6 +250,35 @@ module Flor | |
| 247 250 | 
             
                  end
         | 
| 248 251 | 
             
                end
         | 
| 249 252 |  | 
| 253 | 
            +
                def eval_variables(path, context)
         | 
| 254 | 
            +
                  eval(path, context)
         | 
| 255 | 
            +
                end
         | 
| 256 | 
            +
                def eval_tasker_conf(path, context)
         | 
| 257 | 
            +
                  eval(path, context)
         | 
| 258 | 
            +
                end
         | 
| 259 | 
            +
            # TODO like in eval_hook_conf, reject fautly tasker confs...
         | 
| 260 | 
            +
            # TODO like in eval_hook_conf, reject fautly variables...
         | 
| 261 | 
            +
             | 
| 262 | 
            +
                def eval_hook_conf(path, context)
         | 
| 263 | 
            +
             | 
| 264 | 
            +
                  a = eval(path, context)
         | 
| 265 | 
            +
             | 
| 266 | 
            +
                  fail ArgumentError.new(
         | 
| 267 | 
            +
                    "hook conf at #{path} must be an array of hashes"
         | 
| 268 | 
            +
                  ) unless a.is_a?(Array)
         | 
| 269 | 
            +
             | 
| 270 | 
            +
                  a.each do |e|
         | 
| 271 | 
            +
                    fail ArgumentError.new(
         | 
| 272 | 
            +
                      "hook conf at #{path} has non-hash entry #{e.inspect}"
         | 
| 273 | 
            +
                    ) unless e.is_a?(Hash)
         | 
| 274 | 
            +
                    fail ArgumentError.new(
         | 
| 275 | 
            +
                      "hook conf at #{path} has incorrect point #{e['point'].inspect}"
         | 
| 276 | 
            +
                    ) unless e['point'].is_a?(String)
         | 
| 277 | 
            +
                  end
         | 
| 278 | 
            +
             | 
| 279 | 
            +
                  a
         | 
| 280 | 
            +
                end
         | 
| 281 | 
            +
             | 
| 250 282 | 
             
                def eval(path, context)
         | 
| 251 283 |  | 
| 252 284 | 
             
                  ext =
         | 
    
        data/lib/flor/unit/logger.rb
    CHANGED
    
    | @@ -71,7 +71,8 @@ module Flor | |
| 71 71 | 
             
                  dbi = ' ' + dbi if dbi.length > 0
         | 
| 72 72 |  | 
| 73 73 | 
             
                  txt = elts.collect(&:to_s).join(' ')
         | 
| 74 | 
            -
             | 
| 74 | 
            +
             | 
| 75 | 
            +
                  err = find_err(elts)
         | 
| 75 76 |  | 
| 76 77 | 
             
                  head = "#{stp} #{@uni}#{dbi} #{lvl} "
         | 
| 77 78 |  | 
| @@ -198,7 +199,8 @@ module Flor | |
| 198 199 |  | 
| 199 200 | 
             
                  return unless @unit.conf['log_err']
         | 
| 200 201 |  | 
| 201 | 
            -
                   | 
| 202 | 
            +
                  s = Flor.msg_to_detail_s(executor, message, opts.merge(flag: true))
         | 
| 203 | 
            +
                  @out.puts(s) if s
         | 
| 202 204 | 
             
                end
         | 
| 203 205 |  | 
| 204 206 | 
             
                def log_src(source, opts, log_opts={})
         | 
| @@ -245,6 +247,13 @@ module Flor | |
| 245 247 | 
             
                  message[0..k + 2 + 4] + "(...len#{i - (k + 2 + 1)})" + message[i..-1]
         | 
| 246 248 | 
             
                end
         | 
| 247 249 |  | 
| 250 | 
            +
                def find_err(elts)
         | 
| 251 | 
            +
             | 
| 252 | 
            +
                  elts.find { |e| e.is_a?(Exception) } ||
         | 
| 253 | 
            +
                  (defined?(Java) &&
         | 
| 254 | 
            +
                   elts.find { |e| e.class.ancestors.include?(Java::JavaLang::Error) })
         | 
| 255 | 
            +
                end
         | 
| 256 | 
            +
             | 
| 248 257 | 
             
                class Out
         | 
| 249 258 |  | 
| 250 259 | 
             
                  attr_reader :unit
         | 
| @@ -1,5 +1,6 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            +
             | 
| 3 4 | 
             
            module Flor
         | 
| 4 5 |  | 
| 5 6 | 
             
              class Message < FlorModel
         | 
| @@ -19,6 +20,10 @@ module Flor | |
| 19 20 | 
             
                #
         | 
| 20 21 | 
             
                #  index :exid
         | 
| 21 22 | 
             
                #end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                def nid; data['nid']; end
         | 
| 25 | 
            +
                def tasker; data['tasker']; end
         | 
| 26 | 
            +
                alias payload data
         | 
| 22 27 | 
             
              end
         | 
| 23 28 | 
             
            end
         | 
| 24 29 |  | 
| @@ -30,7 +30,7 @@ module Flor | |
| 30 30 | 
             
                #end
         | 
| 31 31 |  | 
| 32 32 | 
             
                # If the pointer is a "var" pointer, returns the full value
         | 
| 33 | 
            -
                # for the variable, as  | 
| 33 | 
            +
                # for the variable, as found in the execution's node "0".
         | 
| 34 34 | 
             
                #
         | 
| 35 35 | 
             
                def full_value
         | 
| 36 36 |  | 
| @@ -38,6 +38,25 @@ module Flor | |
| 38 38 |  | 
| 39 39 | 
             
                  node['vars'][name]
         | 
| 40 40 | 
             
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                def attd
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                  data['atts'].inject({}) { |h, (k, v)| h[k] = v if k; h }
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                rescue; []
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                def attl
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                  data['atts'].inject([]) { |a, (k, v)| a << v if k == nil; a }
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                rescue; []
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                def att_texts
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                  attl.select { |e| e.is_a?(String) }
         | 
| 59 | 
            +
                end
         | 
| 41 60 | 
             
              end
         | 
| 42 61 | 
             
            end
         | 
| 43 62 |  | 
    
        data/lib/flor/unit/scheduler.rb
    CHANGED
    
    | @@ -138,11 +138,7 @@ module Flor | |
| 138 138 |  | 
| 139 139 | 
             
                  # TODO heartbeat, every x minutes, when idle, log something
         | 
| 140 140 |  | 
| 141 | 
            -
                   | 
| 142 | 
            -
                    "database not ready, " +
         | 
| 143 | 
            -
                    "db ver: #{@storage.db_version.inspect}, " +
         | 
| 144 | 
            -
                    "mig ver: #{@storage.migration_version}"
         | 
| 145 | 
            -
                  ) if !! @conf['sto_migration_check'] && @storage.ready?
         | 
| 141 | 
            +
                  check_migration_version
         | 
| 146 142 |  | 
| 147 143 | 
             
                  @thread_status = :running
         | 
| 148 144 |  | 
| @@ -162,6 +158,15 @@ module Flor | |
| 162 158 | 
             
                  self
         | 
| 163 159 | 
             
                end
         | 
| 164 160 |  | 
| 161 | 
            +
                def check_migration_version
         | 
| 162 | 
            +
             | 
| 163 | 
            +
                  fail(
         | 
| 164 | 
            +
                    "database not ready, " +
         | 
| 165 | 
            +
                    "db ver: #{@storage.db_version.inspect}, " +
         | 
| 166 | 
            +
                    "mig ver: #{@storage.migration_version}"
         | 
| 167 | 
            +
                  ) if !! @conf['sto_migration_check'] && @storage.ready?
         | 
| 168 | 
            +
                end
         | 
| 169 | 
            +
             | 
| 165 170 | 
             
                def stop
         | 
| 166 171 |  | 
| 167 172 | 
             
                  @thread_status = :stop
         | 
| @@ -590,7 +595,7 @@ module Flor | |
| 590 595 |  | 
| 591 596 | 
             
                rescue Exception => ex
         | 
| 592 597 |  | 
| 593 | 
            -
                  puts | 
| 598 | 
            +
                  puts(on_start_exc(ex))
         | 
| 594 599 | 
             
                end
         | 
| 595 600 |  | 
| 596 601 | 
             
                def prepare_message(point, args)
         | 
| @@ -678,9 +683,9 @@ module Flor | |
| 678 683 | 
             
                def should_wake_up?
         | 
| 679 684 |  | 
| 680 685 | 
             
                  return true if @wake_up
         | 
| 681 | 
            -
                  return true if Time.now - @reloaded_at >= reload_after
         | 
| 686 | 
            +
                  return true if (Time.now - @reloaded_at) >= reload_after
         | 
| 682 687 |  | 
| 683 | 
            -
                  @next_time && @next_time <= Flor. | 
| 688 | 
            +
                  @next_time && (@next_time <= Flor.tstam)
         | 
| 684 689 | 
             
                end
         | 
| 685 690 |  | 
| 686 691 | 
             
                def unreserve_messages
         | 
    
        data/lib/flor/unit/storage.rb
    CHANGED
    
    | @@ -7,6 +7,15 @@ module Flor | |
| 7 7 |  | 
| 8 8 | 
             
              class Storage
         | 
| 9 9 |  | 
| 10 | 
            +
                MESSAGE_COLUMNS = [
         | 
| 11 | 
            +
                  :domain, :exid, :point, :content,
         | 
| 12 | 
            +
                  :status, :ctime, :mtime, :cunit, :munit
         | 
| 13 | 
            +
                    ].freeze
         | 
| 14 | 
            +
                POINTER_COLUMNS = [
         | 
| 15 | 
            +
                  :domain, :exid, :nid, :type, :name, :value, :ctime, :cunit,
         | 
| 16 | 
            +
                    :content
         | 
| 17 | 
            +
                      ].freeze
         | 
| 18 | 
            +
             | 
| 10 19 | 
             
                attr_reader :unit, :db, :models
         | 
| 11 20 |  | 
| 12 21 | 
             
                attr_reader :mutex
         | 
| @@ -352,8 +361,7 @@ module Flor | |
| 352 361 |  | 
| 353 362 | 
             
                      @db[:flor_messages]
         | 
| 354 363 | 
             
                        .import(
         | 
| 355 | 
            -
                           | 
| 356 | 
            -
                            :status, :ctime, :mtime, :cunit, :munit ],
         | 
| 364 | 
            +
                          MESSAGE_COLUMNS,
         | 
| 357 365 | 
             
                          unstored.map { |m|
         | 
| 358 366 | 
             
                            [ Flor.domain(m['exid']), m['exid'], m['point'], to_blob(m),
         | 
| 359 367 | 
             
                              'created', n, n, u, u ] }) \
         | 
| @@ -517,25 +525,6 @@ module Flor | |
| 517 525 | 
             
                  end
         | 
| 518 526 | 
             
                end
         | 
| 519 527 |  | 
| 520 | 
            -
                def put_task_pointer(msg, tname, tconf)
         | 
| 521 | 
            -
             | 
| 522 | 
            -
                  exid = msg['exid']
         | 
| 523 | 
            -
                  dom = Flor.domain(exid)
         | 
| 524 | 
            -
             | 
| 525 | 
            -
                  synchronize do
         | 
| 526 | 
            -
             | 
| 527 | 
            -
                    @db[:flor_pointers]
         | 
| 528 | 
            -
                      .insert(
         | 
| 529 | 
            -
                        domain: dom,
         | 
| 530 | 
            -
                        exid: exid,
         | 
| 531 | 
            -
                        nid: msg['nid'],
         | 
| 532 | 
            -
                        type: 'tasker',
         | 
| 533 | 
            -
                        name: tname,
         | 
| 534 | 
            -
                        ctime: Flor.tstamp,
         | 
| 535 | 
            -
                        cunit: @unit.identifier)
         | 
| 536 | 
            -
                  end
         | 
| 537 | 
            -
                end
         | 
| 538 | 
            -
             | 
| 539 528 | 
             
                def fetch_next_time
         | 
| 540 529 |  | 
| 541 530 | 
             
                  t =
         | 
| @@ -598,14 +587,13 @@ module Flor | |
| 598 587 |  | 
| 599 588 | 
             
                    @db[:flor_messages]
         | 
| 600 589 | 
             
                      .where(
         | 
| 601 | 
            -
                        id: messages.collect { |m| m['mid'] }.compact)
         | 
| 590 | 
            +
                        id: messages.collect { |m| m['mid'] }.uniq.compact)
         | 
| 602 591 | 
             
                      .update(
         | 
| 603 592 | 
             
                        status: 'consumed', mtime: n, munit: u)
         | 
| 604 593 |  | 
| 605 594 | 
             
                    @db[:flor_messages]
         | 
| 606 595 | 
             
                      .import(
         | 
| 607 | 
            -
                         | 
| 608 | 
            -
                          :status, :ctime, :mtime, :cunit, :munit ],
         | 
| 596 | 
            +
                        MESSAGE_COLUMNS,
         | 
| 609 597 | 
             
                        messages
         | 
| 610 598 | 
             
                          .select { |m|
         | 
| 611 599 | 
             
                            ! m['mid'] && POINTS_TO_ARCHIVE.include?(m['point']) }
         | 
| @@ -621,19 +609,16 @@ module Flor | |
| 621 609 |  | 
| 622 610 | 
             
                    @db[:flor_messages]
         | 
| 623 611 | 
             
                      .where(
         | 
| 624 | 
            -
                        id: messages.collect { |m| m['mid'] }.compact)
         | 
| 612 | 
            +
                        id: messages.collect { |m| m['mid'] }.uniq.compact)
         | 
| 625 613 | 
             
                      .delete
         | 
| 626 614 | 
             
                  end
         | 
| 627 615 | 
             
                end
         | 
| 628 616 |  | 
| 629 617 | 
             
                def load_timers
         | 
| 630 618 |  | 
| 631 | 
            -
                  now = Flor.tstamp
         | 
| 632 | 
            -
                  no = now[0, now.rindex('.')]
         | 
| 633 | 
            -
             | 
| 634 619 | 
             
                  timers
         | 
| 635 620 | 
             
                    .where(status: 'active')
         | 
| 636 | 
            -
                    .where { ntime <=  | 
| 621 | 
            +
                    .where { ntime <= Flor.tstam }
         | 
| 637 622 | 
             
                    .order(:ntime)
         | 
| 638 623 | 
             
                    .all
         | 
| 639 624 |  | 
| @@ -703,9 +688,9 @@ module Flor | |
| 703 688 |  | 
| 704 689 | 
             
                def update_pointers(exe, status, now)
         | 
| 705 690 |  | 
| 706 | 
            -
            # Q | 
| 707 | 
            -
            # | 
| 708 | 
            -
            # | 
| 691 | 
            +
            # Q  Should we archive old pointers?
         | 
| 692 | 
            +
            # A  Well, it might be better to only archive the execution and leave
         | 
| 693 | 
            +
            #    in there enough information...
         | 
| 709 694 |  | 
| 710 695 | 
             
                  exid = exe['exid']
         | 
| 711 696 |  | 
| @@ -731,23 +716,25 @@ module Flor | |
| 731 716 |  | 
| 732 717 | 
             
                      ts = node['tags']
         | 
| 733 718 | 
             
                      ts.each { |t|
         | 
| 734 | 
            -
                        a << [ dom, exid, nid, 'tag', t, nil, now, u ] } if ts
         | 
| 719 | 
            +
                        a << [ dom, exid, nid, 'tag', t, nil, now, u, nil ] } if ts
         | 
| 735 720 |  | 
| 736 721 | 
             
                      vs = nid == '0' ? node['vars'] : nil
         | 
| 737 722 | 
             
                      vs.each { |k, v|
         | 
| 738 723 | 
             
                        case v; when Numeric, String, TrueClass, FalseClass, NilClass
         | 
| 739 | 
            -
                          a << [ dom, exid, '0', 'var', k, v.to_s, now, u ]
         | 
| 724 | 
            +
                          a << [ dom, exid, '0', 'var', k, v.to_s, now, u, v ]
         | 
| 740 725 | 
             
                        when Array, Hash
         | 
| 741 726 | 
             
                          s = '(array)'; s = '(object)' if v.is_a?(Hash)
         | 
| 742 | 
            -
                          a << [ dom, exid, '0', 'var', k, s, now, u ]
         | 
| 727 | 
            +
                          a << [ dom, exid, '0', 'var', k, s, now, u, v ]
         | 
| 743 728 | 
             
                        else
         | 
| 744 | 
            -
                          a << [ dom, exid, '0', 'var', k, nil, now, u ]
         | 
| 729 | 
            +
                          a << [ dom, exid, '0', 'var', k, nil, now, u, v ]
         | 
| 745 730 | 
             
                        end } if vs
         | 
| 746 731 |  | 
| 747 | 
            -
                       | 
| 748 | 
            -
             | 
| 749 | 
            -
             | 
| 750 | 
            -
                         | 
| 732 | 
            +
                      if ta = node['task']
         | 
| 733 | 
            +
                        tasker = ta['tasker']
         | 
| 734 | 
            +
                        n = ta['name']; name = n.is_a?(String) ? n : JSON.dump(n)
         | 
| 735 | 
            +
                        content = { message: node['message'], atts: node['atts'] }
         | 
| 736 | 
            +
                        a << [ dom, exid, nid, 'tasker', tasker, name, now, u, content ]
         | 
| 737 | 
            +
                      end
         | 
| 751 738 |  | 
| 752 739 | 
             
                      a }
         | 
| 753 740 |  | 
| @@ -755,17 +742,36 @@ module Flor | |
| 755 742 | 
             
                    .where(exid: exid)
         | 
| 756 743 | 
             
                    .select(:nid, :type, :name)
         | 
| 757 744 | 
             
                    .all
         | 
| 758 | 
            -
                  pointers.reject! { |_, _, ni, ty, na, _, _, _|
         | 
| 745 | 
            +
                  pointers.reject! { |_, _, ni, ty, na, _, _, _, _|
         | 
| 759 746 | 
             
                    cps.find { |cp| cp[:nid] == ni && cp[:type] == ty && cp[:name] == na } }
         | 
| 760 747 | 
             
                      #
         | 
| 761 748 | 
             
                      # don't insert when already inserted
         | 
| 762 749 |  | 
| 750 | 
            +
                  #if pointer_columns.include?(:content)
         | 
| 751 | 
            +
                  pointers.each { |ptr| c = ptr[8]; ptr[8] = to_blob(c) if c }
         | 
| 752 | 
            +
                  #else
         | 
| 753 | 
            +
                  #  pointers.each { |ptr| ptr.pop }
         | 
| 754 | 
            +
                  #end
         | 
| 755 | 
            +
             | 
| 756 | 
            +
                  #@db[:flor_pointers]
         | 
| 757 | 
            +
                  #  .import(
         | 
| 758 | 
            +
                  #    pointer_columns,
         | 
| 759 | 
            +
                  #    pointers)
         | 
| 763 760 | 
             
                  @db[:flor_pointers]
         | 
| 764 761 | 
             
                    .import(
         | 
| 765 | 
            -
                       | 
| 762 | 
            +
                      POINTER_COLUMNS,
         | 
| 766 763 | 
             
                      pointers)
         | 
| 767 764 | 
             
                end
         | 
| 768 765 |  | 
| 766 | 
            +
                #def pointer_columns
         | 
| 767 | 
            +
                #  @pointer_columns ||=
         | 
| 768 | 
            +
                #    if @db[:flor_pointers].columns.include?(:content)
         | 
| 769 | 
            +
                #      POINTER_COLUMNS + [ :content ]
         | 
| 770 | 
            +
                #    else
         | 
| 771 | 
            +
                #      POINTER_COLUMNS
         | 
| 772 | 
            +
                #    end
         | 
| 773 | 
            +
                #end
         | 
| 774 | 
            +
             | 
| 769 775 | 
             
                def determine_type_and_schedule(message)
         | 
| 770 776 |  | 
| 771 777 | 
             
                  t, s = message['type'], message['string']
         | 
| @@ -845,8 +851,11 @@ module Flor | |
| 845 851 | 
             
                      # NB: -1 means "check at every use"
         | 
| 846 852 | 
             
                  end
         | 
| 847 853 |  | 
| 848 | 
            -
                  @ | 
| 849 | 
            -
             | 
| 854 | 
            +
                  if @unit.conf['sto_db_logger'] != false
         | 
| 855 | 
            +
             | 
| 856 | 
            +
                    @db_logger = DbLogger.new(@unit)
         | 
| 857 | 
            +
                    @db.loggers << @db_logger
         | 
| 858 | 
            +
                  end
         | 
| 850 859 | 
             
                end
         | 
| 851 860 |  | 
| 852 861 | 
             
                class << self
         | 
    
        data/lib/flor/unit/taskers.rb
    CHANGED
    
    | @@ -29,6 +29,29 @@ module Flor | |
| 29 29 | 
             
                alias task_name taskname
         | 
| 30 30 |  | 
| 31 31 | 
             
                def vars; @message['vars']; end
         | 
| 32 | 
            +
                alias variables vars
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                def set_payload(h)
         | 
| 35 | 
            +
                  fail TypeError.new("not a hash but a #{fs.class}") unless h.is_a?(Hash)
         | 
| 36 | 
            +
                  @message['payload'] = h
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
                alias set_fields set_payload
         | 
| 39 | 
            +
             | 
| 40 | 
            +
                def set_vars(h)
         | 
| 41 | 
            +
                  fail TypeError.new("not a hash but a #{fs.class}") unless h.is_a?(Hash)
         | 
| 42 | 
            +
                  @message['vars'] = h
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
                alias set_variables set_vars
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                #def merge_into_payload(h)
         | 
| 47 | 
            +
                #  @message['payload'].merge(h)
         | 
| 48 | 
            +
                #end
         | 
| 49 | 
            +
                #alias merge_into_fields merge_into_payload
         | 
| 50 | 
            +
                #def merge_into_vars(h)
         | 
| 51 | 
            +
                #  @message['vars'].merge(h)
         | 
| 52 | 
            +
                #end
         | 
| 53 | 
            +
                  #
         | 
| 54 | 
            +
                  # no for now, payload.merge(h) and vars.merge(h) do suffice
         | 
| 32 55 |  | 
| 33 56 | 
             
                def execution
         | 
| 34 57 |  | 
| @@ -112,5 +135,50 @@ module Flor | |
| 112 135 | 
             
                  h
         | 
| 113 136 | 
             
                end
         | 
| 114 137 | 
             
              end
         | 
| 138 | 
            +
             | 
| 139 | 
            +
              # A BasicTasker with stages (pre / on / post)
         | 
| 140 | 
            +
              #
         | 
| 141 | 
            +
              class StagedBasicTasker < BasicTasker
         | 
| 142 | 
            +
             | 
| 143 | 
            +
                def call_task
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                  call_one_of(:pre_task)
         | 
| 146 | 
            +
                  call_one_of(:on_task, :task)
         | 
| 147 | 
            +
                end
         | 
| 148 | 
            +
             | 
| 149 | 
            +
                def call_detask
         | 
| 150 | 
            +
             | 
| 151 | 
            +
                  call_one_of(:pre_detask, :pre_cancel)
         | 
| 152 | 
            +
                  call_one_of(:on_detask, :on_cancel, :detask, :cancel)
         | 
| 153 | 
            +
                end
         | 
| 154 | 
            +
             | 
| 155 | 
            +
                protected
         | 
| 156 | 
            +
             | 
| 157 | 
            +
                def call_one_of(*ms)
         | 
| 158 | 
            +
             | 
| 159 | 
            +
                  m = ms.flatten.find { |mm| respond_to?(mm) }
         | 
| 160 | 
            +
             | 
| 161 | 
            +
                  send(m) if m
         | 
| 162 | 
            +
                end
         | 
| 163 | 
            +
             | 
| 164 | 
            +
                def reply(message=@message, force=false)
         | 
| 165 | 
            +
             | 
| 166 | 
            +
                  fail ArgumentError.new(
         | 
| 167 | 
            +
                    "argument to reply must be a Hash but is #{message.class}"
         | 
| 168 | 
            +
                  ) unless message.is_a?(Hash)
         | 
| 169 | 
            +
             | 
| 170 | 
            +
                  pt = @message['point']
         | 
| 171 | 
            +
             | 
| 172 | 
            +
                  ms = [ "post_#{pt}" ]; ms << :post_cancel if pt == 'detask'
         | 
| 173 | 
            +
                    #
         | 
| 174 | 
            +
                  call_one_of(ms)
         | 
| 175 | 
            +
             | 
| 176 | 
            +
                  msg = derive_message(message)
         | 
| 177 | 
            +
             | 
| 178 | 
            +
                  @ganger.return(msg) if force || @ganger
         | 
| 179 | 
            +
             | 
| 180 | 
            +
                  [] # very important, return no further messages
         | 
| 181 | 
            +
                end
         | 
| 182 | 
            +
              end
         | 
| 115 183 | 
             
            end
         | 
| 116 184 |  | 
    
        data/lib/flor/unit/waiter.rb
    CHANGED
    
    | @@ -53,7 +53,7 @@ module Flor | |
| 53 53 |  | 
| 54 54 | 
             
                  @mutex.synchronize do
         | 
| 55 55 |  | 
| 56 | 
            -
                    return false unless  | 
| 56 | 
            +
                    return false unless msg_match?(message)
         | 
| 57 57 |  | 
| 58 58 | 
             
                    @serie.shift
         | 
| 59 59 | 
             
                    return false if @serie.any?
         | 
| @@ -151,7 +151,7 @@ module Flor | |
| 151 151 |  | 
| 152 152 | 
             
                protected
         | 
| 153 153 |  | 
| 154 | 
            -
                def  | 
| 154 | 
            +
                def msg_match?(message)
         | 
| 155 155 |  | 
| 156 156 | 
             
                  mpoint = message['point']
         | 
| 157 157 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: flor
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1. | 
| 4 | 
            +
              version: 1.2.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - John Mettraux
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date:  | 
| 11 | 
            +
            date: 2021-03-29 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: munemo
         | 
| @@ -237,7 +237,7 @@ files: | |
| 237 237 | 
             
            - lib/flor/punit/do_trap.rb
         | 
| 238 238 | 
             
            - lib/flor/punit/every.rb
         | 
| 239 239 | 
             
            - lib/flor/punit/graft.rb
         | 
| 240 | 
            -
            - lib/flor/punit/ | 
| 240 | 
            +
            - lib/flor/punit/m_receive_and_merge.rb
         | 
| 241 241 | 
             
            - lib/flor/punit/on_timeout.rb
         | 
| 242 242 | 
             
            - lib/flor/punit/part.rb
         | 
| 243 243 | 
             
            - lib/flor/punit/schedule.rb
         | 
| @@ -248,6 +248,7 @@ files: | |
| 248 248 | 
             
            - lib/flor/punit/trap.rb
         | 
| 249 249 | 
             
            - lib/flor/to_string.rb
         | 
| 250 250 | 
             
            - lib/flor/tools/env.rb
         | 
| 251 | 
            +
            - lib/flor/tools/firb.rb
         | 
| 251 252 | 
             
            - lib/flor/tools/shell.rb
         | 
| 252 253 | 
             
            - lib/flor/tools/shell_out.rb
         | 
| 253 254 | 
             
            - lib/flor/tt.rb
         | 
| @@ -257,6 +258,7 @@ files: | |
| 257 258 | 
             
            - lib/flor/unit/dump.rb
         | 
| 258 259 | 
             
            - lib/flor/unit/executor.rb
         | 
| 259 260 | 
             
            - lib/flor/unit/ganger.rb
         | 
| 261 | 
            +
            - lib/flor/unit/gangers.rb
         | 
| 260 262 | 
             
            - lib/flor/unit/hloader.rb
         | 
| 261 263 | 
             
            - lib/flor/unit/hook.rb
         | 
| 262 264 | 
             
            - lib/flor/unit/hooker.rb
         |