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_abandon? ⇒ Boolean
-
#__weel_finalize ⇒ Object
{{{.
-
#alternative(eid, 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: {}, signal: false, 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(eid, mode = :inclusive, &block) ⇒ Object
Choose DSL-Construct Defines a choice in the Workflow path.
-
#critical(eid, id, &block) ⇒ Object
Defines a critical block (=Mutex).
-
#escape(eid) ⇒ Object
}}}.
-
#initialize ⇒ DSLRealization
constructor
{{{.
-
#loop(eid, 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(eid, args = {}, &block) ⇒ Object
}}}.
-
#parallel(eid, type = nil, &block) ⇒ Object
Parallel DSL-Construct Defines Workflow paths that can be executed parallel.
-
#parallel_branch(eid, 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(eid, abandon = false) ⇒ Object
}}}.
-
#test(code = nil, &blk) ⇒ Object
}}}.
-
#wait_for_signal(position, label) ⇒ Object
}}}.
-
#🠊(code) ⇒ Object
DSL-Construct for translating expressions into static parameters.
Constructor Details
#initialize ⇒ DSLRealization
{{{
485 486 487 488 489 490 491 492 493 494 495 496 497 |
# File 'lib/weel.rb', line 485 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_abandon = false @__weel_lock = Mutex.new end |
Instance Attribute Details
#__weel_connectionwrapper ⇒ Object
}}}
498 499 500 |
# File 'lib/weel.rb', line 498 def __weel_connectionwrapper @__weel_connectionwrapper end |
#__weel_connectionwrapper_args ⇒ Object
}}}
498 499 500 |
# File 'lib/weel.rb', line 498 def __weel_connectionwrapper_args @__weel_connectionwrapper_args end |
#__weel_data ⇒ Object
}}}
498 499 500 |
# File 'lib/weel.rb', line 498 def __weel_data @__weel_data end |
#__weel_endpoints ⇒ Object
}}}
498 499 500 |
# File 'lib/weel.rb', line 498 def __weel_endpoints @__weel_endpoints end |
#__weel_main ⇒ Object
}}}
498 499 500 |
# File 'lib/weel.rb', line 498 def __weel_main @__weel_main end |
#__weel_positions ⇒ Object
}}}
498 499 500 |
# File 'lib/weel.rb', line 498 def __weel_positions @__weel_positions end |
#__weel_search_positions ⇒ Object
}}}
498 499 500 |
# File 'lib/weel.rb', line 498 def __weel_search_positions @__weel_search_positions end |
#__weel_state ⇒ Object
Returns the value of attribute __weel_state.
499 500 501 |
# File 'lib/weel.rb', line 499 def __weel_state @__weel_state end |
#__weel_status ⇒ Object (readonly)
Returns the value of attribute __weel_status.
499 500 501 |
# File 'lib/weel.rb', line 499 def __weel_status @__weel_status end |
Instance Method Details
#__weel_abandon? ⇒ Boolean
500 |
# File 'lib/weel.rb', line 500 def __weel_abandon? = @__weel_abandon |
#__weel_finalize ⇒ Object
{{{
1123 1124 1125 1126 1127 |
# File 'lib/weel.rb', line 1123 def __weel_finalize #{{{ __weel_recursive_join(@__weel_main) @__weel_state = :stopped @__weel_connectionwrapper::inform_state_change @__weel_connectionwrapper_args, @__weel_state end |
#alternative(eid, 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)
663 664 665 666 667 668 669 670 671 672 673 674 675 676 |
# File 'lib/weel.rb', line 663 def alternative(eid,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(eid, 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: {}, signal: false, 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
510 511 512 |
# File 'lib/weel.rb', line 510 def call(position, endpoint, parameters: {}, signal: false, finalize: nil, update: nil, prepare: nil, salvage: nil, &finalizeblk) #{{{ __weel_activity(position,:call,endpoint,parameters,finalize||finalizeblk,update,prepare,salvage,signal) end |
#choose(eid, mode = :inclusive, &block) ⇒ Object
Choose DSL-Construct Defines a choice in the Workflow path. May contain multiple execution alternatives
642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 |
# File 'lib/weel.rb', line 642 def choose(eid,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 eid __weel_protect_yield(&block) cw.join_branches eid Thread.current[:alternative_executed].pop Thread.current[:alternative_mode].pop nil end |
#critical(eid, id, &block) ⇒ Object
Defines a critical block (=Mutex)
715 716 717 718 719 720 721 722 723 724 725 726 727 |
# File 'lib/weel.rb', line 715 def critical(eid,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(eid) ⇒ Object
}}}
777 778 779 780 781 |
# File 'lib/weel.rb', line 777 def escape(eid) #{{{ 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(eid, condition, args = {}, &block) ⇒ Object
Defines a Cycle (loop/iteration)
730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 |
# File 'lib/weel.rb', line 730 def loop(eid,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(eid, 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(eid, 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
515 516 517 518 519 520 |
# File 'lib/weel.rb', line 515 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(eid, args = {}, &block) ⇒ Object
}}}
677 678 679 680 |
# File 'lib/weel.rb', line 677 def otherwise(eid,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(eid, type = nil, &block) ⇒ Object
Parallel DSL-Construct Defines Workflow paths that can be executed parallel. May contain multiple branches (parallel_branch)
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 563 564 565 566 567 568 569 570 571 572 |
# File 'lib/weel.rb', line 525 def parallel(eid,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[:nudge] = Queue.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 eid, 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 eid, 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(eid, data = @__weel_data, &block) ⇒ Object
Defines a branch of a parallel-Construct
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 625 626 627 628 629 630 631 632 633 634 635 636 637 |
# File 'lib/weel.rb', line 575 def parallel_branch(eid,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.deep_dup 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(ReadHash.new(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 1.upto(branch_parent[:nudge].num_waiting) do branch_parent[:nudge].push(nil) end __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
}}}
773 774 775 |
# File 'lib/weel.rb', line 773 def post_test(code=nil,&blk)# {{{ [code || blk, :post_test] end |
#pre_test(code = nil, &blk) ⇒ Object
}}}
770 771 772 |
# File 'lib/weel.rb', line 770 def pre_test(code=nil,&blk)# {{{ [code || blk, :pre_test] end |
#stop(position) ⇒ Object
}}}
788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 |
# File 'lib/weel.rb', line 788 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(eid, abandon = false) ⇒ Object
}}}
782 783 784 785 786 787 |
# File 'lib/weel.rb', line 782 def terminate(eid,abandon=false) #{{{ return if __weel_is_in_search_mode return if self.__weel_state == :stopping || self.__weel_state == :finishing || self.__weel_state == :stopped || Thread.current[:nolongernecessary] @__weel_abandon = abandon self.__weel_state = :finishing end |
#test(code = nil, &blk) ⇒ Object
}}}
767 768 769 |
# File 'lib/weel.rb', line 767 def test(code=nil,&blk)# {{{ code || blk end |
#wait_for_signal(position, label) ⇒ Object
}}}
682 683 684 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 |
# File 'lib/weel.rb', line 682 def wait_for_signal(position,label) #{{{ position = __weel_position_test 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 uuid = SecureRandom.uuid wp = __weel_progress position, SecureRandom.uuid @__weel_connectionwrapper::inform_activity_minimal @__weel_connectionwrapper_args,'calling',uuid,label,position Thread.current[:branch_parent][:nudge].pop if self.__weel_state != :stopping if Thread.current[:nolongernecessary] @__weel_connectionwrapper::inform_activity_minimal @__weel_connectionwrapper_args, 'done', uuid, label, position Thread.current[:branch_position] = nil @__weel_positions.delete wp @__weel_connectionwrapper::inform_position_change @__weel_connectionwrapper_args, :unmark => [wp] else @__weel_connectionwrapper::inform_activity_minimal @__weel_connectionwrapper_args, 'done', uuid, label, position end end __weel_activity_ensure end |
#🠊(code) ⇒ Object
DSL-Construct for translating expressions into static parameters
503 |
# File 'lib/weel.rb', line 503 def 🠊(code); ProcString.new(code); end |