Uploaded image for project: 'JGroups'
  1. JGroups
  2. JGRP-2612

CENTRAL_LOCK2 is not initialized correctly using FORK channel

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Done
    • Icon: Major Major
    • 4.2.21, 5.2.3
    • 4.2.21
    • None
    • False
    • None
    • False
    • Hide

      Use CENTRAL_LOCK2 inside FORK

      Example of config:

      <config xmlns="urn:org:jgroups"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="urn:org:jgroups http://www.jgroups.org/schema/jgroups.xsd"
      >
          <UDP
                  mcast_port="${jgroups.udp.mcast_port:45588}"
                  ip_ttl="4"
                  tos="8"
                  ucast_recv_buf_size="5M"
                  ucast_send_buf_size="5M"
                  mcast_recv_buf_size="5M"
                  mcast_send_buf_size="5M"
                  max_bundle_size="64K"
                  enable_diagnostics="true"
                  thread_naming_pattern="cl"
      
                  thread_pool.min_threads="0"
                  thread_pool.max_threads="20"
                  thread_pool.keep_alive_time="30000"/>
      
          <PING />
          <MERGE3 max_interval="30000"
                  min_interval="10000"/>
          <FD_SOCK/>
          <FD_ALL/>
          <VERIFY_SUSPECT timeout="1500"  />
          <BARRIER />
          <pbcast.NAKACK2 xmit_interval="500"
                          xmit_table_num_rows="100"
                          xmit_table_msgs_per_row="2000"
                          xmit_table_max_compaction_time="30000"
                          use_mcast_xmit="false"
                          discard_delivered_msgs="true"/>
          <UNICAST3 xmit_interval="500"
                    xmit_table_num_rows="100"
                    xmit_table_msgs_per_row="2000"
                    xmit_table_max_compaction_time="60000"
                    conn_expiry_timeout="0"/>
          <pbcast.STABLE desired_avg_gossip="50000"
                         max_bytes="4M"/>
          <pbcast.GMS print_local_addr="true" join_timeout="2000"/>
          <UFC max_credits="10M"
               min_threshold="0.4"/>
          <MFC max_credits="10M"
               min_threshold="0.4"/>
          <FRAG2 frag_size="60K"  />
          <RSVP resend_interval="2000" timeout="10000"/>
          <pbcast.STATE_TRANSFER />
          <FORK>
              <fork-stacks xmlns="fork" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                           xsi:schemaLocation="fork fork-stacks-4.2.xsd">
                  <fork-stack id="lock">
                      <config>
                          <CENTRAL_LOCK2/>
                      </config>
                  </fork-stack>
              </fork-stacks>
          </FORK>
      </config>
      

      Example of code:

       JChannel c = new JChannel(configFileWithFork).connect("cluster");
       ForkChannel fc = new ForkChannel(c, "lock", "lock-channel");
       fc.connect("bla");
      
       LockService lockService = new LockService(fc);
      
       //without running RequestHandler we never get a lock
       boolean isLocked = lockService.getLock("myLock").tryLock(5, TimeUnit.SECONDS);
      
      Show
      Use CENTRAL_LOCK2 inside FORK Example of config: <config xmlns= "urn:org:jgroups"         xmlns:xsi= "http: //www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation= "urn:org:jgroups http: //www.jgroups.org/schema/jgroups.xsd" >     <UDP             mcast_port= "${jgroups.udp.mcast_port:45588}"             ip_ttl= "4"             tos= "8"             ucast_recv_buf_size= "5M"             ucast_send_buf_size= "5M"             mcast_recv_buf_size= "5M"             mcast_send_buf_size= "5M"             max_bundle_size= "64K"             enable_diagnostics= " true "             thread_naming_pattern= "cl"             thread_pool.min_threads= "0"             thread_pool.max_threads= "20"             thread_pool.keep_alive_time= "30000" />     <PING />     <MERGE3 max_interval= "30000"             min_interval= "10000" />     <FD_SOCK/>     <FD_ALL/>     <VERIFY_SUSPECT timeout= "1500"  />     <BARRIER />     <pbcast.NAKACK2 xmit_interval= "500"                     xmit_table_num_rows= "100"                     xmit_table_msgs_per_row= "2000"                     xmit_table_max_compaction_time= "30000"                     use_mcast_xmit= " false "                     discard_delivered_msgs= " true " />     <UNICAST3 xmit_interval= "500"               xmit_table_num_rows= "100"               xmit_table_msgs_per_row= "2000"               xmit_table_max_compaction_time= "60000"               conn_expiry_timeout= "0" />     <pbcast.STABLE desired_avg_gossip= "50000"                    max_bytes= "4M" />     <pbcast.GMS print_local_addr= " true " join_timeout= "2000" />     <UFC max_credits= "10M"          min_threshold= "0.4" />     <MFC max_credits= "10M"          min_threshold= "0.4" />     <FRAG2 frag_size= "60K"  />     <RSVP resend_interval= "2000" timeout= "10000" />     <pbcast.STATE_TRANSFER />     <FORK>         <fork-stacks xmlns= "fork" xmlns:xsi= "http: //www.w3.org/2001/XMLSchema-instance"                      xsi:schemaLocation= "fork fork-stacks-4.2.xsd" >             <fork-stack id= "lock" >                 <config>                     <CENTRAL_LOCK2/>                 </config>             </fork-stack>         </fork-stacks>     </FORK> </config> Example of code:  JChannel c = new JChannel(configFileWithFork).connect( "cluster" );  ForkChannel fc = new ForkChannel(c, "lock" , "lock-channel" );  fc.connect( "bla" );  LockService lockService = new LockService(fc);   //without running RequestHandler we never get a lock   boolean isLocked = lockService.getLock( "myLock" ).tryLock(5, TimeUnit.SECONDS);

      CENTRAL_LOCK2 is not properly initialized if used together with FORK channel. RequestHandler is never started, and doesn't process locking requests.

      Basically this happens because CENTRAL_LOCK2  first receives VIEW_CHANGE event (when connecting main channel) and then SET_LOCAL_ADDRESS (when connecting fork channel). If fork is not used, the order is correct: first SET_LOCAL_ADDRESS and then VIEW_CHANGE.

       

      Sequence of actions when creating fork channel:

      • first main channel is created and connected
        • JChannel sends "down" SET_LOCAL_ADDRESS event to protocols starting from top: FORK -> STATE -> etc (CENTRAL_LOCK2 doesn't receive this event because it is child of FORK)
        • when connection is established GMS protocol builds the view and distributes the VIEW_CHANGE event up and down. So going up request reach FORK and FORK sends it to its child (CENTRAL_LOCK2)
        • at this stage CENTRAL_LOCK2 doesn't have local_addr initialized yet - so condition for coordinator fails and RequestHandler is not started
      • create and connect fork channel
        • JChannel sends "down" SET_LOCAL_ADDRESS event to protocols starting from CENTRAL_LOCK2 - now local_addr is initialized
        • when connection is established again GMS sends VIEW_CHANGE event
        • now CENTRAL_LOCK2 see the coordinator hasn't changed (it compares local_addr with remembered coordinator - they are same), so it is not starting RequestHandler

      In my view CENTRAL_LOCK2/Locking should reject all events from "up" method until local_addr is initialized.

       

              rhn-engineering-bban Bela Ban
              michalbogdal Michal Bogdal (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: