Frank:

Thanks for your quick response.

Do you see any drawback from my code change?

In my application, the snmp agent thread co-exists with other threads. By yielding to other threads when there is no message on the agent port, other threads get more CPU time. I noticed that the overall CPU usage of my application cuts into less than half comparing with the application without this change.

I cut|paste my change here.

Have a nice day.

Vivi

=======================================================================

     DatagramPacket packet = new DatagramPacket(buf, buf.length,
udpAddress.getInetAddress(),
                                                udpAddress.getPort());
     while (!stop) {
       try {
         try {
           socket.receive(packet);
         }
         catch (InterruptedIOException iiox) {
             if (iiox.bytesTransferred <= 0) {
                 try
                 {
                     Thread.sleep(getSocketTimeout() / 10);
                 }
                 catch (InterruptedException e)
                 {
                     // Now move on.
                     continue;
                 }
                 continue;
             }
         }
...


[email protected] wrote:
Send SNMP4J mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        http://lists.agentpp.org/mailman/listinfo/snmp4j
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of SNMP4J digest..."


Today's Topics:

   1. DefaultUdpTransportMapping class and  ListenThread (Vivi Zhang)
   2. Re: DefaultUdpTransportMapping class and  ListenThread
      (Frank Fock)


----------------------------------------------------------------------

Message: 1
Date: Mon, 02 Feb 2009 13:52:11 -0600
From: Vivi Zhang <[email protected]>
Subject: [SNMP4J] DefaultUdpTransportMapping class and  ListenThread
To: [email protected].
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

Hi,

I am looking at ways to tuning my application with embedded SNMP agent with SNMP4J and SNMP4J-Agent.

I have two questions about the implementation of  inner class ListernThread.
Q1) Line 315 * try {
      socket.receive(packet);
   }
   catch (InterruptedIOException iiox) {
         if (iiox.bytesTransferred <= 0) {
         continue;
   }*
If we see SocketTimeoutException since there is no packet to read, can we put the thread to a small break before it goes for another socket.receive() call? The suggestion is intended to ease some pressure on the CPU and network resource. Do you see any potential drawback from this change? Q2) Line 307 *DatagramPacket packet = new DatagramPacket(buf, buf.length,
                                             udpAddress.getInetAddress(),
                                             udpAddress.getPort());**
*A DatagramPacket object is created repeatedly within the while loop. What is the drawback if we move the stmt outiside while loop. The logic behind this suggestion is avoiding object creating repeatedly withing the loop.

Thanks.

Vivi

P.S.

I am using SNMP4J 1.9.3c.

Following is a section of code I cut from DefaultUdpTransportMapping.java.
============================================================================

while (!stop) {
*  DatagramPacket packet = new DatagramPacket(buf, buf.length,
                                             udpAddress.getInetAddress(),
                                             udpAddress.getPort());*
  try {
    try {
      socket.receive(packet);
    }
    catch (InterruptedIOException iiox) {
      if (iiox.bytesTransferred <= 0) {
     *   continue;*
      }
    }
    if (logger.isDebugEnabled()) {
      logger.debug("Received message from "+packet.getAddress()+"/"+
                   packet.getPort()+
                   " with length "+packet.getLength()+": "+
                   new OctetString(packet.getData(), 0,
                                   packet.getLength()).toHexString());
    }
    ByteBuffer bis;
    // If messages are processed asynchronously (i.e. multi-threaded)
    // then we have to copy the buffer's content here!
    if (isAsyncMsgProcessingSupported()) {
      byte[] bytes = new byte[packet.getLength()];
      System.arraycopy(packet.getData(), 0, bytes, 0, bytes.length);
      bis = ByteBuffer.wrap(bytes);
    }
    else {
      bis = ByteBuffer.wrap(packet.getData());
    }
    fireProcessMessage(new UdpAddress(packet.getAddress(),
                                      packet.getPort()), bis);
  }
  catch (SocketTimeoutException stex) {
    // ignore
  }
  catch (PortUnreachableException purex) {
    synchronized (DefaultUdpTransportMapping.this) {
      listener = null;
    }
    logger.error(purex);
    if (logger.isDebugEnabled()) {
      purex.printStackTrace();
    }
    if (SNMP4JSettings.isFowardRuntimeExceptions()) {
      throw new RuntimeException(purex);
    }
    break;
  }
  catch (SocketException soex) {
    logger.error("Socket for transport mapping "+toString()+
                 " error: "+soex.getMessage(), soex);
    stop = true;
  }
  catch (IOException iox) {
    logger.warn(iox);
    if (logger.isDebugEnabled()) {
      iox.printStackTrace();
    }
    if (SNMP4JSettings.isFowardRuntimeExceptions()) {
      throw new RuntimeException(iox);
    }
  }
}
synchronized (DefaultUdpTransportMapping.this) {
  listener = null;
  stop = true;
  if (socket != null) {
    socket.close();
  }
}


------------------------------

Message: 2
Date: Tue, 03 Feb 2009 01:31:59 +0100
From: Frank Fock <[email protected]>
Subject: Re: [SNMP4J] DefaultUdpTransportMapping class and
        ListenThread
To: Vivi Zhang <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

Hi,

Since Socket.receive blocks until a packet is received,
I do not see any advantage of the suggested code.

Best regards,
Frank

Vivi Zhang wrote:
Hi,

I am looking at ways to tuning my application with embedded SNMP agent with SNMP4J and SNMP4J-Agent.

I have two questions about the implementation of inner class ListernThread.
Q1) Line 315 *   try {
     socket.receive(packet);
  }
  catch (InterruptedIOException iiox) {
        if (iiox.bytesTransferred <= 0) {
        continue;
  }*
If we see SocketTimeoutException since there is no packet to read, can we put the thread to a small break before it goes for another socket.receive() call? The suggestion is intended to ease some pressure on the CPU and network resource. Do you see any potential drawback from this change?

Q2) Line 307 *DatagramPacket packet = new DatagramPacket(buf, buf.length,
                                            udpAddress.getInetAddress(),
                                            udpAddress.getPort());**
*A DatagramPacket object is created repeatedly within the while loop. What is the drawback if we move the stmt outiside while loop. The logic behind this suggestion is avoiding object creating repeatedly withing the loop.

Thanks.

Vivi

P.S.

I am using SNMP4J 1.9.3c.

Following is a section of code I cut from DefaultUdpTransportMapping.java.
============================================================================

while (!stop) {
*  DatagramPacket packet = new DatagramPacket(buf, buf.length,
                                            udpAddress.getInetAddress(),
                                            udpAddress.getPort());*
 try {
   try {
     socket.receive(packet);
   }
   catch (InterruptedIOException iiox) {
     if (iiox.bytesTransferred <= 0) {
    *   continue;*
     }
   }
   if (logger.isDebugEnabled()) {
     logger.debug("Received message from "+packet.getAddress()+"/"+
                  packet.getPort()+
                  " with length "+packet.getLength()+": "+
                  new OctetString(packet.getData(), 0,
                                  packet.getLength()).toHexString());
   }
   ByteBuffer bis;
   // If messages are processed asynchronously (i.e. multi-threaded)
   // then we have to copy the buffer's content here!
   if (isAsyncMsgProcessingSupported()) {
     byte[] bytes = new byte[packet.getLength()];
     System.arraycopy(packet.getData(), 0, bytes, 0, bytes.length);
     bis = ByteBuffer.wrap(bytes);
   }
   else {
     bis = ByteBuffer.wrap(packet.getData());
   }
   fireProcessMessage(new UdpAddress(packet.getAddress(),
                                     packet.getPort()), bis);
 }
 catch (SocketTimeoutException stex) {
   // ignore
 }
 catch (PortUnreachableException purex) {
   synchronized (DefaultUdpTransportMapping.this) {
     listener = null;
   }
   logger.error(purex);
   if (logger.isDebugEnabled()) {
     purex.printStackTrace();
   }
   if (SNMP4JSettings.isFowardRuntimeExceptions()) {
     throw new RuntimeException(purex);
   }
   break;
 }
 catch (SocketException soex) {
   logger.error("Socket for transport mapping "+toString()+
                " error: "+soex.getMessage(), soex);
   stop = true;
 }
 catch (IOException iox) {
   logger.warn(iox);
   if (logger.isDebugEnabled()) {
     iox.printStackTrace();
   }
   if (SNMP4JSettings.isFowardRuntimeExceptions()) {
     throw new RuntimeException(iox);
   }
 }
}
synchronized (DefaultUdpTransportMapping.this) {
 listener = null;
 stop = true;
 if (socket != null) {
   socket.close();
 }
}
_______________________________________________
SNMP4J mailing list
[email protected]
http://lists.agentpp.org/mailman/listinfo/snmp4j


_______________________________________________
SNMP4J mailing list
[email protected]
http://lists.agentpp.org/mailman/listinfo/snmp4j

Reply via email to