Class: WEEL::DSLRealization
- Inherits:
-
Object
- Object
- WEEL::DSLRealization
- Defined in:
- lib/weel.rb
Overview
}}}
Instance Attribute Summary collapse
-
#__weel_connectionwrapper ⇒ Object
}}}.
-
#__weel_connectionwrapper_args ⇒ Object
}}}.
-
#__weel_data ⇒ Object
}}}.
-
#__weel_endpoints ⇒ Object
}}}.
-
#__weel_main ⇒ Object
}}}.
-
#__weel_positions ⇒ Object
}}}.
-
#__weel_search_positions ⇒ Object
}}}.
-
#__weel_state ⇒ Object
Returns the value of attribute __weel_state.
-
#__weel_status ⇒ Object
readonly
Returns the value of attribute __weel_status.
Instance Method Summary collapse
-
#__weel_finalize ⇒ Object
{{{.
-
#alternative(condition, args = {}, &block) ⇒ Object
Defines a possible choice of a choose-Construct Block is executed if condition == true or searchmode is active (to find the starting position).
-
#call(position, endpoint, parameters: {}, finalize: nil, update: nil, prepare: nil, salvage: nil, &finalizeblk) ⇒ Object
DSL-Constructs for atomic calls to external services (calls) and pure context manipulations (manipulate).
-
#choose(mode = :inclusive, &block) ⇒ Object
Choose DSL-Construct Defines a choice in the Workflow path.
-
#critical(id, &block) ⇒ Object
Defines a critical block (=Mutex).
-
#escape ⇒ Object
}}}.
-
#initialize ⇒ DSLRealization
constructor
{{{.
-
#loop(condition, args = {}, &block) ⇒ Object
Defines a Cycle (loop/iteration).
-
#manipulate(position, parameters = nil, script = nil, &scriptblk) ⇒ Object
when two params, second param always script when block and two params, parameters stays.
-
#otherwise(args = {}, &block) ⇒ Object
}}}.
-
#parallel(type = nil, &block) ⇒ Object
Parallel DSL-Construct Defines Workflow paths that can be executed parallel.
-
#parallel_branch(data = @__weel_data, &block) ⇒ Object
Defines a branch of a parallel-Construct.
-
#post_test(code = nil, &blk) ⇒ Object
}}}.
-
#pre_test(code = nil, &blk) ⇒ Object
}}}.
-
#stop(position) ⇒ Object
}}}.
-
#terminate ⇒ Object
}}}.
-
#test(code = nil, &blk) ⇒ Object
}}}.
-
#🠊(code) ⇒ Object
DSL-Construct for translating expressions into static parameters.
Constructor Details
#initialize ⇒ DSLRealization
{{{
477 478 479 480 481 482 483 484 485 486 487 488 489 |
# File 'lib/weel.rb', line 477 def initialize #{{{ @__weel_search_positions = {} @__weel_positions = Array.new @__weel_main = nil @__weel_data ||= Hash.new @__weel_endpoints ||= Hash.new @__weel_connectionwrapper = ConnectionWrapperBase @__weel_connectionwrapper_args = [] @__weel_state = :ready @__weel_status = Status.new(0,"undefined") @__weel_sim = false @__weel_lock = Mutex.new end |
Instance Attribute Details
#__weel_connectionwrapper ⇒ Object
}}}
490 491 492 |
# File 'lib/weel.rb', line 490 def __weel_connectionwrapper @__weel_connectionwrapper end |
#__weel_connectionwrapper_args ⇒ Object
}}}
490 491 492 |
# File 'lib/weel.rb', line 490 def __weel_connectionwrapper_args @__weel_connectionwrapper_args end |
#__weel_data ⇒ Object
}}}
490 491 492 |
# File 'lib/weel.rb', line 490 def __weel_data @__weel_data end |
#__weel_endpoints ⇒ Object
}}}
490 491 492 |
# File 'lib/weel.rb', line 490 def __weel_endpoints @__weel_endpoints end |
#__weel_main ⇒ Object
}}}
490 491 492 |
# File 'lib/weel.rb', line 490 def __weel_main @__weel_main end |
#__weel_positions ⇒ Object
}}}
490 491 492 |
# File 'lib/weel.rb', line 490 def __weel_positions @__weel_positions end |
#__weel_search_positions ⇒ Object
}}}
490 491 492 |
# File 'lib/weel.rb', line 490 def __weel_search_positions @__weel_search_positions end |
#__weel_state ⇒ Object
Returns the value of attribute __weel_state.
491 492 493 |
# File 'lib/weel.rb', line 491 def __weel_state @__weel_state end |
#__weel_status ⇒ Object (readonly)
Returns the value of attribute __weel_status.
491 492 493 |
# File 'lib/weel.rb', line 491 def __weel_status @__weel_status end |
Instance Method Details
#__weel_finalize ⇒ Object
{{{
1055 1056 1057 1058 1059 |
# File 'lib/weel.rb', line 1055 def __weel_finalize #{{{ __weel_recursive_join(@__weel_main) @__weel_state = :stopped @__weel_connectionwrapper::inform_state_change @__weel_connectionwrapper_args, @__weel_state end |
#alternative(condition, args = {}, &block) ⇒ Object
Defines a possible choice of a choose-Construct Block is executed if condition == true or searchmode is active (to find the starting position)
650 651 652 653 654 655 656 657 658 659 660 661 662 663 |
# File 'lib/weel.rb', line 650 def alternative(condition,args={},&block)# {{{ return if self.__weel_state == :stopping || self.__weel_state == :finishing || self.__weel_state == :stopped || Thread.current[:nolongernecessary] Thread.current[:mutex] ||= Mutex.new Thread.current[:mutex].synchronize do return if Thread.current[:alternative_mode][-1] == :exclusive && Thread.current[:alternative_executed][-1] == true if condition.is_a?(String) condition = __weel_eval_condition(condition, args) end Thread.current[:alternative_executed][-1] = true if condition end searchmode = __weel_is_in_search_mode __weel_protect_yield(&block) if searchmode || condition Thread.current[:alternative_executed][-1] = true if __weel_is_in_search_mode != searchmode # we swiched from searchmode true to false, thus branch has been executed which is as good as evaling the condition to true end |
#call(position, endpoint, parameters: {}, finalize: nil, update: nil, prepare: nil, salvage: nil, &finalizeblk) ⇒ Object
DSL-Constructs for atomic calls to external services (calls) and pure context manipulations (manipulate). Calls can also manipulate context (after the invoking the external services) position: a unique identifier within the wf-description (may be used by the search to identify a starting point) endpoint: (only with :call) ep of the service parameters: (only with :call) service parameters
501 502 503 |
# File 'lib/weel.rb', line 501 def call(position, endpoint, parameters: {}, finalize: nil, update: nil, prepare: nil, salvage: nil, &finalizeblk) #{{{ __weel_activity(position,:call,endpoint,parameters,finalize||finalizeblk,update,prepare,salvage) end |
#choose(mode = :inclusive, &block) ⇒ Object
Choose DSL-Construct Defines a choice in the Workflow path. May contain multiple execution alternatives
629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 |
# File 'lib/weel.rb', line 629 def choose(mode=:inclusive,&block) # {{{ return if self.__weel_state == :stopping || self.__weel_state == :finishing || self.__weel_state == :stopped || Thread.current[:nolongernecessary] Thread.current[:alternative_executed] ||= [] Thread.current[:alternative_mode] ||= [] Thread.current[:alternative_executed] << false Thread.current[:alternative_mode] << mode cw = @__weel_connectionwrapper.new @__weel_connectionwrapper_args cw.split_branches Thread.current.__id__ __weel_protect_yield(&block) cw.join_branches Thread.current.__id__ Thread.current[:alternative_executed].pop Thread.current[:alternative_mode].pop nil end |
#critical(id, &block) ⇒ Object
Defines a critical block (=Mutex)
670 671 672 673 674 675 676 677 678 679 680 681 682 |
# File 'lib/weel.rb', line 670 def critical(id,&block)# {{{ return if self.__weel_state == :stopping || self.__weel_state == :finishing || self.__weel_state == :stopped || Thread.current[:nolongernecessary] @__weel_critical ||= Mutex.new semaphore = nil @__weel_critical.synchronize do @__weel_critical_sections ||= {} semaphore = @__weel_critical_sections[id] ? @__weel_critical_sections[id] : Mutex.new @__weel_critical_sections[id] = semaphore if id end semaphore.synchronize do __weel_protect_yield(&block) end end |
#escape ⇒ Object
}}}
732 733 734 735 736 |
# File 'lib/weel.rb', line 732 def escape #{{{ return if __weel_is_in_search_mode return if self.__weel_state == :stopping || self.__weel_state == :finishing || self.__weel_state == :stopped || Thread.current[:nolongernecessary] throw :escape end |
#loop(condition, args = {}, &block) ⇒ Object
Defines a Cycle (loop/iteration)
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 |
# File 'lib/weel.rb', line 685 def loop(condition,args={},&block)# {{{ unless condition[0].is_a?(String) && [:pre_test,:post_test].include?(condition[1]) && args.is_a?(Hash) raise "condition must be called pre_test{} or post_test{}" end return if self.__weel_state == :stopping || self.__weel_state == :finishing || self.__weel_state == :stopped || Thread.current[:nolongernecessary] if __weel_is_in_search_mode catch :escape do __weel_protect_yield(&block) end if __weel_is_in_search_mode return else ### in case it was a :post_test we wake inside the loop so we can check ### condition first thing condition[1] = :pre_test end end loop_guard = 0 loop_id = SecureRandom.uuid catch :escape do case condition[1] when :pre_test while __weel_eval_condition(condition[0],args) && self.__weel_state != :stopping && self.__weel_state != :stopped && self.__weel_state != :finishing && !Thread.current[:nolongernecessary] loop_guard += 1 __weel_protect_yield(&block) sleep 1 if @__weel_connectionwrapper::loop_guard(@__weel_connectionwrapper_args,loop_id,loop_guard) end when :post_test begin loop_guard += 1 __weel_protect_yield(&block) sleep 1 if @__weel_connectionwrapper::loop_guard(@__weel_connectionwrapper_args,loop_id,loop_guard) end while __weel_eval_condition(condition[0],args) && self.__weel_state != :stopping && self.__weel_state != :stopped && self.__weel_state != :finishing && !Thread.current[:nolongernecessary] end end end |
#manipulate(position, parameters = nil, script = nil, &scriptblk) ⇒ Object
when two params, second param always script when block and two params, parameters stays
506 507 508 509 510 511 |
# File 'lib/weel.rb', line 506 def manipulate(position, parameters=nil, script=nil, &scriptblk) #{{{ if scriptblk.nil? && script.nil? && !parameters.nil? script, parameters = parameters, nil end __weel_activity(position,:manipulate,nil,parameters||{},script||scriptblk) end |
#otherwise(args = {}, &block) ⇒ Object
}}}
664 665 666 667 |
# File 'lib/weel.rb', line 664 def otherwise(args={},&block) # {{{ return if self.__weel_state == :stopping || self.__weel_state == :finishing || self.__weel_state == :stopped || Thread.current[:nolongernecessary] __weel_protect_yield(&block) if __weel_is_in_search_mode || !Thread.current[:alternative_executed].last end |
#parallel(type = nil, &block) ⇒ Object
Parallel DSL-Construct Defines Workflow paths that can be executed parallel. May contain multiple branches (parallel_branch)
516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 |
# File 'lib/weel.rb', line 516 def parallel(type=nil,&block)# {{{ return if self.__weel_state == :stopping || self.__weel_state == :finishing || self.__weel_state == :stopped || Thread.current[:nolongernecessary] Thread.current[:branches] = [] Thread.current[:branch_traces] = {} Thread.current[:branch_traces_ids] = 0 Thread.current[:branch_finished_count] = 0 Thread.current[:branch_event] = Continue.new Thread.current[:mutex] = Mutex.new __weel_protect_yield(&block) Thread.current[:branch_wait_count] = (type.is_a?(Hash) && type[:wait] != nil && (type[:wait].is_a?(Integer) && type[:wait] > 0) ? type[:wait] : Thread.current[:branches].size) Thread.current[:branch_wait_count_cancel] = 0 Thread.current[:branch_wait_count_cancel_condition] = (type.is_a?(Hash) && type[:cancel] != nil && type[:cancel] == :first ) ? :first : :last 1.upto Thread.current[:branches].size do Thread.current[:branch_event].wait end cw = @__weel_connectionwrapper.new @__weel_connectionwrapper_args cw.split_branches Thread.current.__id__, Thread.current[:branch_traces] Thread.current[:branches].each do |thread| # decide after executing block in parallel cause for coopis # it goes out of search mode while dynamically counting branches if Thread.current[:branch_search] == false thread[:branch_search] = false end thread[:start_event]&.continue # sometimes start event might not even exist yet (i.e. race condition) end Thread.current[:branch_event].wait unless self.__weel_state == :stopping || self.__weel_state == :finishing || self.__weel_state == :stopped || Thread.current[:branches].length == 0 cw.join_branches Thread.current.__id__, Thread.current[:branch_traces] unless self.__weel_state == :stopping || self.__weel_state == :finishing || self.__weel_state == :stopped # first set all to no_longer_neccessary, just in case, but this should not be necessary Thread.current[:branches].each do |thread| thread[:nolongernecessary] = true __weel_recursive_continue(thread) end # wait for all, they should not even exist at this point Thread.current[:branches].each do |thread| __weel_recursive_join(thread) end end end |
#parallel_branch(data = @__weel_data, &block) ⇒ Object
Defines a branch of a parallel-Construct
565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 |
# File 'lib/weel.rb', line 565 def parallel_branch(data=@__weel_data,&block)# {{{ return if self.__weel_state == :stopping || self.__weel_state == :finishing || self.__weel_state == :stopped || Thread.current[:nolongernecessary] branch_parent = Thread.current branch_parent[:branches] << Thread.new(data) do |*local| Thread.current.abort_on_exception = true Thread.current[:branch_search] = @__weel_search_positions.any? Thread.current[:branch_parent] = branch_parent Thread.current[:start_event] = Continue.new Thread.current[:local] = local Thread.current[:branch_wait_count_cancel_active] = false branch_parent[:mutex].synchronize do Thread.current[:branch_traces_id] = branch_parent[:branch_traces_ids] branch_parent[:branch_traces_ids] += 1 end # parallel_branch could be possibly around an alternative. Thus thread has to inherit the alternative_executed # after branching, update it in the parent (TODO) if branch_parent[:alternative_executed] && branch_parent[:alternative_executed].length > 0 Thread.current[:alternative_executed] = [branch_parent[:alternative_executed].last] Thread.current[:alternative_mode] = [branch_parent[:alternative_mode].last] end branch_parent[:branch_event].continue Thread.current[:start_event].wait unless self.__weel_state == :stopping || self.__weel_state == :stopped || self.__weel_state == :finishing unless self.__weel_state == :stopping || self.__weel_state == :finishing || self.__weel_state == :stopped || Thread.current[:nolongernecessary] __weel_protect_yield(*local, &block) end branch_parent[:mutex].synchronize do branch_parent[:branch_finished_count] += 1 if branch_parent[:branch_wait_count_cancel_condition] == :last if branch_parent[:branch_finished_count] == branch_parent[:branch_wait_count] && self.__weel_state != :stopping && self.__weel_state != :finishing branch_parent[:branches].each do |thread| if thread.alive? && thread[:branch_wait_count_cancel_active] == false thread[:nolongernecessary] = true __weel_recursive_continue(thread) end end end end if branch_parent[:branch_finished_count] == branch_parent[:branches].length && self.__weel_state != :stopping && self.__weel_state != :finishing branch_parent[:branch_event].continue end end unless self.__weel_state == :stopping || self.__weel_state == :stopped || self.__weel_state == :finishing if Thread.current[:branch_position] @__weel_positions.delete Thread.current[:branch_position] begin ipc = {} ipc[:unmark] = [Thread.current[:branch_position]] @__weel_connectionwrapper::inform_position_change(@__weel_connectionwrapper_args,ipc) end rescue nil Thread.current[:branch_position] = nil end end end end |
#post_test(code = nil, &blk) ⇒ Object
}}}
728 729 730 |
# File 'lib/weel.rb', line 728 def post_test(code=nil,&blk)# {{{ [code || blk, :post_test] end |
#pre_test(code = nil, &blk) ⇒ Object
}}}
725 726 727 |
# File 'lib/weel.rb', line 725 def pre_test(code=nil,&blk)# {{{ [code || blk, :pre_test] end |
#stop(position) ⇒ Object
}}}
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 |
# File 'lib/weel.rb', line 742 def stop(position) #{{{ searchmode = __weel_is_in_search_mode(position) return if searchmode return if self.__weel_state == :stopping || self.__weel_state == :finishing || self.__weel_state == :stopped || Thread.current[:nolongernecessary] # gather traces in threads to point to join if Thread.current[:branch_parent] && Thread.current[:branch_traces_id] Thread.current[:branch_parent][:branch_traces][Thread.current[:branch_traces_id]] ||= [] Thread.current[:branch_parent][:branch_traces][Thread.current[:branch_traces_id]] << position end __weel_progress position, 0, true self.__weel_state = :stopping end |
#terminate ⇒ Object
}}}
737 738 739 740 741 |
# File 'lib/weel.rb', line 737 def terminate #{{{ return if __weel_is_in_search_mode return if self.__weel_state == :stopping || self.__weel_state == :finishing || self.__weel_state == :stopped || Thread.current[:nolongernecessary] self.__weel_state = :finishing end |
#test(code = nil, &blk) ⇒ Object
}}}
722 723 724 |
# File 'lib/weel.rb', line 722 def test(code=nil,&blk)# {{{ code || blk end |
#🠊(code) ⇒ Object
DSL-Construct for translating expressions into static parameters
494 |
# File 'lib/weel.rb', line 494 def 🠊(code); ProcString.new(code); end |