Package io.s4.emitter

Source Code of io.s4.emitter.CommLayerEmitter$PassThroughSerializer

/*
* Copyright (c) 2010 Yahoo! Inc. All rights reserved.
*
* Licensed 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. See accompanying LICENSE file.
*/
package io.s4.emitter;

import static io.s4.util.MetricsName.S4_CORE_METRICS;
import static io.s4.util.MetricsName.S4_EVENT_METRICS;
import static io.s4.util.MetricsName.low_level_emitter_msg_out_ct;
import static io.s4.util.MetricsName.low_level_emitter_out_err_ct;
import static io.s4.util.MetricsName.low_level_emitter_qsz;
import io.s4.collector.EventWrapper;
import io.s4.comm.core.SenderProcess;
import io.s4.comm.core.Serializer;
import io.s4.listener.CommLayerListener;
import io.s4.logger.Monitor;
import io.s4.message.Request;
import io.s4.serialize.SerializerDeserializer;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

import org.apache.log4j.Logger;

public class CommLayerEmitter implements EventEmitter, Runnable {
    private static Logger logger = Logger.getLogger(CommLayerEmitter.class);

    // config for emitter is coupled with listener, if there is a non-null
    // listener. This prevents 2 tasks from being checked out of the cluster
    // config for the same node: one for the listener and another for the
    // emitter.
    private CommLayerListener listener;

    private SenderProcess sender;
    private int nodeCount;
    private BlockingQueue<MessageHolder> messageQueue = new LinkedBlockingDeque<MessageHolder>();
    private String senderId;
    private String clusterManagerAddress;
    private String appName;
    private String listenerAppName = null;
    private Monitor monitor;
    private SerializerDeserializer serDeser;

    public void setSerDeser(SerializerDeserializer serDeser) {
        this.serDeser = serDeser;
    }

    public void setMonitor(Monitor monitor) {
        this.monitor = monitor;
    }

    public void setSenderId(String senderId) {
        this.senderId = senderId;
    }

    public void setClusterManagerAddress(String clusterManagerAddress) {
        this.clusterManagerAddress = clusterManagerAddress;
    }

    public void setAppName(String appName) {
        this.appName = appName;
    }

    public void setListenerAppName(String listenerAppName) {
        this.listenerAppName = listenerAppName;
    }

    public void setListener(CommLayerListener listener) {
        this.listener = listener;
    }

    public void init() {

        Thread t = new Thread(this, "CommLayerEmitter");
        t.start();
    }

    public void queueMessage(MessageHolder messageHolder) {
        messageQueue.add(messageHolder);
        try {
            if (monitor != null) {
                monitor.set(low_level_emitter_qsz.toString(),
                            messageQueue.size(),
                            S4_CORE_METRICS.toString());
            }
        } catch (Exception e) {
            logger.error("Exception in monitor metrics on thread "
                    + Thread.currentThread().getId(), e);
        }
    }

    @Override
    public void emit(int partitionId, EventWrapper eventWrapper) {

        // Special handling required for Requests
        if (eventWrapper.getEvent() instanceof Request) {
            decorateRequest((Request) eventWrapper.getEvent());
        }

        try {
            byte[] rawMessage = serDeser.serialize(eventWrapper);
            MessageHolder mh = new MessageHolder(partitionId, rawMessage);
            queueMessage(mh);
        } catch (RuntimeException rte) {
            if (monitor != null) {
                monitor.increment(low_level_emitter_out_err_ct.toString(),
                                  1,
                                  S4_EVENT_METRICS.toString(),
                                  "et",
                                  eventWrapper.getStreamName());
            }
            Logger.getLogger("s4").error("Error serializing or emitting event "
                                                 + eventWrapper.getEvent(),
                                         rte);
            throw rte;
        }
    }

    // Add partition id of sender
    private void decorateRequest(Request r) {
        Request.RInfo rinfo = r.getRInfo();

        if (rinfo != null && listener != null)
            rinfo.setPartition(listener.getId());
    }

    @Override
    public int getNodeCount() {
        if (listener == null) {
            return 1;
        }
        return nodeCount;
    }

    @Override
    public void run() {
        if (listener == null) {
            if (listenerAppName == null) {
                listenerAppName = appName;
            }
            sender = new SenderProcess(clusterManagerAddress,
                                       appName,
                                       listenerAppName);
            Map<String, String> map = new HashMap<String, String>();
            map.put("SenderId", "" + senderId);
            sender.setSerializer(new PassThroughSerializer());
            sender.acquireTaskAndCreateSender(map);
        } else {
            Object listenerConfig = null;
            try {
                listenerConfig = listener.getListenerConfig();
                if (listenerConfig == null) {
                    logger.info("CommLayerEmitter going to wait for listener to acquire task");
                    synchronized (listener) {
                        listenerConfig = listener.getListenerConfig();
                        if (listenerConfig == null) {
                            listener.wait();
                            listenerConfig = listener.getListenerConfig();
                        }
                    }
                }
            } catch (Exception e) {
                logger.info("Exception in CommLayerEmitter.run()", e);
            }
            logger.info("Creating sender process with " + listenerConfig);

            String destinationAppName = (listenerAppName != null
                    ? listenerAppName : listener.getAppName());

            sender = new SenderProcess(listener.getClusterManagerAddress(),
                                       listener.getAppName(),
                                       destinationAppName);

            sender.setSerializer(new PassThroughSerializer());
            sender.createSenderFromConfig(listenerConfig);
            nodeCount = sender.getNumOfPartitions();
        }
        boolean isSent = false;
        while (!Thread.interrupted()) {
            isSent = false;
            try {
                MessageHolder mh = messageQueue.take();
                byte[] rawMessage = mh.getRawMessage();
                if (listener == null) {
                    isSent = sender.send(rawMessage);
                } else {
                    isSent = sender.sendToPartition(mh.getPartitionId(),
                                                    rawMessage);
                }

                if (isSent) {
                    if (monitor != null) {
                        monitor.increment(low_level_emitter_msg_out_ct.toString(),
                                          1,
                                          S4_CORE_METRICS.toString());
                    }
                } else {
                    if (monitor != null) {
                        monitor.increment(low_level_emitter_out_err_ct.toString(),
                                          1,
                                          S4_CORE_METRICS.toString());
                    }
                    logger.warn("commlayer emit failed ...");
                }
            } catch (InterruptedException ie) {
                if (monitor != null) {
                    monitor.increment(low_level_emitter_out_err_ct.toString(),
                                      1,
                                      S4_CORE_METRICS.toString());
                }
                Thread.currentThread().interrupt();
            } catch (Exception e) {
                Logger.getLogger("s4").error("Error emitting message", e);
            }
        }
    }

    public class PassThroughSerializer implements Serializer {
        public byte[] serialize(Object input) {
            if (input instanceof byte[]) {
                return (byte[]) input;
            } else {
                return null;
            }
        }
    }

    class MessageHolder {
        private int partitionId;
        private byte[] rawMessage;

        MessageHolder(int partitionId, byte[] rawMessage) {
            this.partitionId = partitionId;
            this.rawMessage = rawMessage;
        }

        int getPartitionId() {
            return partitionId;
        }

        byte[] getRawMessage() {
            return rawMessage;
        }
    }
}
TOP

Related Classes of io.s4.emitter.CommLayerEmitter$PassThroughSerializer

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.