Package org.apache.qpid.tools

Source Code of org.apache.qpid.tools.PerfProducer

/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.qpid.tools;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.jms.BytesMessage;
import javax.jms.DeliveryMode;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;

import org.apache.qpid.thread.Threading;

/**
* PerfProducer sends an x no of messages in warmup mode and wait for a confirmation
* from the consumer that it has successfully consumed them and ready to start the
* test. It will start sending y no of messages and each message will contain a time
* stamp. This will be used at the receiving end to measure the latency.
*
* This is done with the assumption that both consumer and producer are running on
* the same machine or different machines which have time synced using a time server.
*
* This test also calculates the producer rate as follows.
* rate = msg_count/(time_before_sending_msgs - time_after_sending_msgs)
*
* All throughput rates are given as msg/sec so the rates are multiplied by 1000.
*
* Rajith - Producer rate is not an accurate perf metric IMO.
* It is heavily inlfuenced by any in memory buffering.
* System throughput and latencies calculated by the PerfConsumer are more realistic
* numbers.
*
*/
public class PerfProducer extends PerfBase
{
    MessageProducer producer;
    Message msg;
    Object payload;
    List<Object> payloads;
    boolean cacheMsg = false;
    boolean randomMsgSize = false;
    boolean durable = false;
    Random random;
    int msgSizeRange = 1024;

    enum MessageType {
        BYTES, TEXT, MAP, OBJECT;

        public static MessageType getType(String s) throws Exception
        {
            if ("text".equalsIgnoreCase(s))
            {
                return TEXT;
            }
            else if ("bytes".equalsIgnoreCase(s))
            {
                return BYTES;
            }
            /*else if ("map".equalsIgnoreCase(s))
            {
                return MAP;
            }
            else if ("object".equalsIgnoreCase(s))
            {
                return OBJECT;
            }*/
            else
            {
                throw new Exception("Unsupported message type");
            }
        }
    };

    MessageType msgType = MessageType.BYTES;

    public PerfProducer()
    {
        super();
    }

    public void setUp() throws Exception
    {
        super.setUp();
        feedbackDest = session.createTemporaryQueue();

        durable = params.isDurable();
        msgType = MessageType.getType(params.getMessageType());

        System.out.println("Using " + msgType + " messages");

        // if message caching is enabled we pre create the message
        // else we pre create the payload
        if (params.isCacheMessage())
        {
            cacheMsg = true;
            msg = createMessage(createPayload(params.getMsgSize()));
            msg.setJMSDeliveryMode(durable?
                                   DeliveryMode.PERSISTENT :
                                   DeliveryMode.NON_PERSISTENT
                                  );
        }
        else if (params.isRandomMsgSize())
        {
            random = new Random(20080921);
            randomMsgSize = true;
            msgSizeRange = params.getMsgSize();
            payloads = new ArrayList<Object>(msgSizeRange);

            for (int i=0; i < msgSizeRange; i++)
            {
                payloads.add(createPayload(i));
            }
        }
        else
        {
            payload = createPayload(params.getMsgSize());
        }

        producer = session.createProducer(dest);
        producer.setDisableMessageID(params.isDisableMessageID());
        producer.setDisableMessageTimestamp(params.isDisableTimestamp());
    }

    Object createPayload(int size)
    {
        if (msgType == MessageType.TEXT)
        {
           return MessageFactory.createMessagePayload(size);
        }
        else
        {
            return MessageFactory.createMessagePayload(size).getBytes();
        }
    }

    Message createMessage(Object payload) throws Exception
    {
        if (msgType == MessageType.TEXT)
        {
            return session.createTextMessage((String)payload);
        }
        else
        {
            BytesMessage m = session.createBytesMessage();
            m.writeBytes((byte[])payload);
            return m;
        }
    }


    protected Message getNextMessage() throws Exception
    {
        if (cacheMsg)
        {
            return msg;
        }
        else
        {
            Message m;

            if (!randomMsgSize)
            {
                m = createMessage(payload);
            }
            else
            {
                m = createMessage(payloads.get(random.nextInt(msgSizeRange)));
            }
            m.setJMSDeliveryMode(durable?
                    DeliveryMode.PERSISTENT :
                    DeliveryMode.NON_PERSISTENT
                   );
            return m;
        }
    }

    public void warmup()throws Exception
    {
        System.out.println("Warming up......");
        MessageConsumer tmp = session.createConsumer(feedbackDest);

        for (int i=0; i < params.getWarmupCount() -1; i++)
        {
            producer.send(getNextMessage());
        }
        Message msg = session.createTextMessage("End");
        msg.setJMSReplyTo(feedbackDest);
        producer.send(msg);

        if (params.isTransacted())
        {
            session.commit();
        }

        tmp.receive();

        if (params.isTransacted())
        {
            session.commit();
        }

        tmp.close();
    }

    public void startTest() throws Exception
    {
        System.out.println("Starting test......");
        int count = params.getMsgCount();
        boolean transacted = params.isTransacted();
        int tranSize =  params.getTransactionSize();

        long start = System.currentTimeMillis();
        for(int i=0; i < count; i++ )
        {
            Message msg = getNextMessage();
            msg.setJMSTimestamp(System.currentTimeMillis());
            producer.send(msg);
            if ( transacted && ((i+1) % tranSize == 0))
            {
                session.commit();
            }
        }
        long time = System.currentTimeMillis() - start;
        double rate = ((double)count/(double)time)*1000;
        System.out.println(new StringBuilder("Producer rate: ").
                               append(df.format(rate)).
                               append(" msg/sec").
                               toString());
    }

    public void waitForCompletion() throws Exception
    {
        MessageConsumer tmp = session.createConsumer(feedbackDest);
        Message msg = session.createTextMessage("End");
        msg.setJMSReplyTo(feedbackDest);
        producer.send(msg);

        if (params.isTransacted())
        {
            session.commit();
        }

        tmp.receive();

        if (params.isTransacted())
        {
            session.commit();
        }

        tmp.close();
        System.out.println("Consumer has completed the test......");
    }

    public void tearDown() throws Exception
    {
        producer.close();
        session.close();
        con.close();
    }

    public void test()
    {
        try
        {
            setUp();
            warmup();
            startTest();
            waitForCompletion();
            tearDown();
        }
        catch(Exception e)
        {
            handleError(e,"Error when running test");
        }
    }


    public static void main(String[] args)
    {
        final PerfProducer prod = new PerfProducer();
        Runnable r = new Runnable()
        {
            public void run()
            {
                prod.test();
            }
        };

        Thread t;
        try
        {
            t = Threading.getThreadFactory().createThread(r);
        }
        catch(Exception e)
        {
            throw new Error("Error creating producer thread",e);
        }
        t.start();
    }
}
TOP

Related Classes of org.apache.qpid.tools.PerfProducer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.