<commit_before><?xml version="1.0" encoding="UTF-8"?>
<chapter id="user-channel">
  <title>API</title>

  <para>This chapter explains the classes available in JGroups that will be
  used by applications to build reliable group communication applications. The
  focus is on creating and using channels.</para>

  <para>Information in this document may not be up-to-date, but the nature of
  the classes in the JGroups toolkit described here is the same. For the most
  up-to-date information refer to the Javadoc-generated documentation in the
  <filename>doc/javadoc</filename> directory.</para>

  <para>All of the classes discussed below reside in the
  <classname>org.jgroups</classname> package unless otherwise
  mentioned.</para>

  <section>
    <title>Utility classes</title>

    <para>The <classname>org.jgroups.util.Util</classname> class contains a
    collection of useful functionality which cannot be assigned to any
    particular package.</para>

    <section>
      <title>objectToByteBuffer(), objectFromByteBuffer()</title>

      <para>The first method takes an object as argument and serializes it
      into a byte buffer (the object has to be serializable or
      externalizable). The byte array is then returned. This method is often
      used to serialize objects into the byte buffer of a message. The second
      method returns a reconstructed object from a buffer. Both methods throw
      an exception if the object cannot be serialized or unserialized.</para>
    </section>
  </section>

  <section>
    <title>Interfaces</title>

    <para>These interfaces are used with some of the APIs presented below,
    therefore they are listed first.</para>

    <section>
      <title>MessageListener</title>

      <para>Contrary to the pull-style of channels, some building blocks (e.g.
      <classname>PullPushAdapter</classname> ) provide an event-like
      <emphasis>push-style</emphasis> message delivery model. In this case,
      the entity to be notified of message reception needs to provide a
      callback to be invoked whenever a message has been received. The
      <classname>MessageListener</classname> interface below provides a method
      to do so:</para>

      <screen>
                public interface MessageListener {
                    public void receive(Message msg);
                    byte[] getState();
                    void setState(byte[] state);
                }
            </screen>

      <para>Method <methodname>receive()</methodname> will be called when a
      message is received. The <methodname>getState()</methodname> and
      <methodname>setState()</methodname> methods are used to fetch and set
      the group state (e.g. when joining). Refer to <xref
      linkend="GetState" /> for a discussion of state transfer.</para>
    </section>

    <section>
      <title>ExtendedMessageListener</title>

      <para>JGroups release 2.3 introduced ExtendedMessageListener enabling
      partial state transfer (refer to <xref linkend="PartialStateTransfer" />
      ) while release 2.4 further expands ExtendedMessageListener with
      streaming state transfer callbacks:</para>

      <screen>
                public interface ExtendedMessageListener extends MessageListener {
                    byte[] getState(String state_id);
                    void setState(String state_id, byte[] state);
                      
                    /*** since JGroups 2.4 *****/
                    void getState(OutputStream ostream);
                    void getState(String state_id, OutputStream ostream);
                    void setState(InputStream istream);
                    void setState(String state_id, InputStream istream);
                }
            </screen>

    </section>

    <section id="MembershipListener">
      <title>MembershipListener</title>

      <para>The <classname>MembershipListener</classname> interface is similar
      to the <classname>MessageListener</classname> interface above: every
      time a new view, a suspicion message, or a block event is received, the
      corresponding method of the class implementing
      <classname>MembershipListener</classname> will be called.</para>

      <screen>
                public interface MembershipListener {
                    public void viewAccepted(View new_view);
                    public void suspect(Object suspected_mbr);
                    public void block();
                }
            </screen>

        <para>Oftentimes the only method containing any functionality will be
            <methodname>viewAccepted()</methodname> which notifies the receiver that
            a new member has joined the group or that an existing member has left or
            crashed. The <methodname>suspect()</methodname> callback is invoked by
            JGroups whenever a member if suspected of having crashed, but not yet
            excluded <footnote>
            <para>It could be that the member is suspected falsely, in which
                case the next view would still contain the suspected member (there
                is currently no <methodname>unsuspect()</methodname> method</para>
        </footnote>.</para>
        <para>
            The <methodname>block()</methodname> method is called
            to notify the member that it will soon be blocked sending messages. This
            is done by the FLUSH protocol, for example to ensure that nobody is sending
            messages while a state transfer is in progress. When block() returns, any thread
            sending messages will be blocked, until FLUSH unblocks the thread again, e.g.
            after the state has been transferred successfully.
         </para>

        <para>
            Therefore, block() can be used to send pending messages or complete some other work.
         </para>

        <para>
            Note that block() should be brief, or else the entire FLUSH protocol is blocked.
        </para>
    </section><commit_msg>added note on sending of messages in callback<commit_after><?xml version="1.0" encoding="UTF-8"?>
<chapter id="user-channel">
  <title>API</title>

  <para>This chapter explains the classes available in JGroups that will be
  used by applications to build reliable group communication applications. The
  focus is on creating and using channels.</para>

  <para>Information in this document may not be up-to-date, but the nature of
  the classes in the JGroups toolkit described here is the same. For the most
  up-to-date information refer to the Javadoc-generated documentation in the
  <filename>doc/javadoc</filename> directory.</para>

  <para>All of the classes discussed below reside in the
  <classname>org.jgroups</classname> package unless otherwise
  mentioned.</para>

  <section>
    <title>Utility classes</title>

    <para>The <classname>org.jgroups.util.Util</classname> class contains a
    collection of useful functionality which cannot be assigned to any
    particular package.</para>

    <section>
      <title>objectToByteBuffer(), objectFromByteBuffer()</title>

      <para>The first method takes an object as argument and serializes it
      into a byte buffer (the object has to be serializable or
      externalizable). The byte array is then returned. This method is often
      used to serialize objects into the byte buffer of a message. The second
      method returns a reconstructed object from a buffer. Both methods throw
      an exception if the object cannot be serialized or unserialized.</para>
    </section>
  </section>

  <section>
    <title>Interfaces</title>

    <para>These interfaces are used with some of the APIs presented below,
    therefore they are listed first.</para>

    <section>
      <title>MessageListener</title>

      <para>Contrary to the pull-style of channels, some building blocks (e.g.
      <classname>PullPushAdapter</classname> ) provide an event-like
      <emphasis>push-style</emphasis> message delivery model. In this case,
      the entity to be notified of message reception needs to provide a
      callback to be invoked whenever a message has been received. The
      <classname>MessageListener</classname> interface below provides a method
      to do so:</para>

      <screen>
                public interface MessageListener {
                    public void receive(Message msg);
                    byte[] getState();
                    void setState(byte[] state);
                }
            </screen>

      <para>Method <methodname>receive()</methodname> will be called when a
      message is received. The <methodname>getState()</methodname> and
      <methodname>setState()</methodname> methods are used to fetch and set
      the group state (e.g. when joining). Refer to <xref
      linkend="GetState" /> for a discussion of state transfer.</para>
    </section>

    <section>
      <title>ExtendedMessageListener</title>

      <para>JGroups release 2.3 introduced ExtendedMessageListener enabling
      partial state transfer (refer to <xref linkend="PartialStateTransfer" />
      ) while release 2.4 further expands ExtendedMessageListener with
      streaming state transfer callbacks:</para>

      <screen>
                public interface ExtendedMessageListener extends MessageListener {
                    byte[] getState(String state_id);
                    void setState(String state_id, byte[] state);
                      
                    /*** since JGroups 2.4 *****/
                    void getState(OutputStream ostream);
                    void getState(String state_id, OutputStream ostream);
                    void setState(InputStream istream);
                    void setState(String state_id, InputStream istream);
                }
            </screen>

    </section>

    <section id="MembershipListener">
      <title>MembershipListener</title>

      <para>The <classname>MembershipListener</classname> interface is similar
      to the <classname>MessageListener</classname> interface above: every
      time a new view, a suspicion message, or a block event is received, the
      corresponding method of the class implementing
      <classname>MembershipListener</classname> will be called.</para>

      <screen>
                public interface MembershipListener {
                    public void viewAccepted(View new_view);
                    public void suspect(Object suspected_mbr);
                    public void block();
                }
            </screen>

        <para>Oftentimes the only method containing any functionality will be
            <methodname>viewAccepted()</methodname> which notifies the receiver that
            a new member has joined the group or that an existing member has left or
            crashed. The <methodname>suspect()</methodname> callback is invoked by
            JGroups whenever a member if suspected of having crashed, but not yet
            excluded <footnote>
            <para>It could be that the member is suspected falsely, in which
                case the next view would still contain the suspected member (there
                is currently no <methodname>unsuspect()</methodname> method</para>
        </footnote>.</para>
        <para>
            The <methodname>block()</methodname> method is called
            to notify the member that it will soon be blocked sending messages. This
            is done by the FLUSH protocol, for example to ensure that nobody is sending
            messages while a state transfer is in progress. When block() returns, any thread
            sending messages will be blocked, until FLUSH unblocks the thread again, e.g.
            after the state has been transferred successfully.
         </para>

        <para>
            Therefore, block() can be used to send pending messages or complete some other work.
         </para>

        <para>
            Note that block() should be brief, or else the entire FLUSH protocol is blocked.
        </para>
        <note>
            <title>Sending messages in callbacks</title>
            <para>
                Note that anything that could block should <emphasis>not</emphasis> be done in a callback.
                This includes sending of messages;
                if we have FLUSH on the stack, and send a message in a viewAccepted() callback, then the following
                happens: the FLUSH protocol blocks all (multicast) messages before installing a view, then installs
                the view, then unblocks. However, because installation of the view triggers the viewAccepted() callback,
                sending of messages inside of viewAccepted() will block. This in turn blocks the viewAccepted() thread,
                so the flush will never return !
            </para>
            <para>
                If we need to send a message in a callback, the sending should be done on a separate thread, or a timer
                task should be submitted to the timer.
            </para>
        </note>
    </section>
{'fraction_non_alphanumeric': 0.07062883435582822, 'fraction_numerical': 0.0013803680981595093, 'mean_word_length': 2.4609872611464967, 'pattern_counts': {'":': 0, '<': 211, '<?xml version=': 2, '>': 211, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5498934', 'n_tokens_mistral': 3144, 'n_tokens_neox': 2998, 'n_words': 1324}