org.apache.kylin.common.restclient.Broadcaster.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.kylin.common.restclient.Broadcaster.java

Source

/*
 * 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.kylin.common.restclient;

import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import org.apache.kylin.common.KylinConfig;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Broadcast kylin event out
 * 
 * @author jianliu
 * 
 */
public class Broadcaster {

    private static final Logger logger = LoggerFactory.getLogger(Broadcaster.class);

    private BlockingDeque<BroadcastEvent> broadcastEvents = new LinkedBlockingDeque<>();

    private AtomicLong counter = new AtomicLong();

    static class BroadcasterHolder {
        static final Broadcaster INSTANCE = new Broadcaster();
    }

    private Broadcaster() {
        Executors.newSingleThreadExecutor().execute(new Runnable() {
            @Override
            public void run() {
                final String[] nodes = KylinConfig.getInstanceFromEnv().getRestServers();
                if (nodes == null || nodes.length < 1) {//TODO if the node count is greater than 1, it means it is a cluster
                    logger.warn("There is no available rest server; check the 'kylin.rest.servers' config");
                    return;
                }
                final List<RestClient> restClients = Lists.newArrayList();
                for (String node : nodes) {
                    restClients.add(new RestClient(node));
                }
                final ExecutorService wipingCachePool = Executors.newFixedThreadPool(restClients.size());
                while (true) {
                    try {
                        final BroadcastEvent broadcastEvent = broadcastEvents.takeFirst();
                        logger.info("new broadcast event:" + broadcastEvent);
                        for (final RestClient restClient : restClients) {
                            wipingCachePool.execute(new Runnable() {
                                @Override
                                public void run() {
                                    try {
                                        restClient.wipeCache(broadcastEvent.getType(), broadcastEvent.getAction(),
                                                broadcastEvent.getName());
                                    } catch (IOException e) {
                                        logger.warn("Thread failed during wipe cache at " + broadcastEvent);
                                    }
                                }
                            });
                        }
                    } catch (Exception e) {
                        logger.error("error running wiping", e);
                    }
                }
            }
        });
    }

    public static Broadcaster getInstance() {
        return BroadcasterHolder.INSTANCE;
    }

    /**
     * Broadcast the cubedesc event out
     * 
     * @param action
     *            event action
     */
    public void queue(String type, String action, String key) {
        try {
            counter.incrementAndGet();
            broadcastEvents.putFirst(new BroadcastEvent(type, action, key));
        } catch (Exception e) {
            counter.decrementAndGet();
            logger.error("error putting BroadcastEvent", e);
        }
    }

    public long getCounterAndClear() {
        return counter.getAndSet(0);
    }

    public static enum EVENT {
        CREATE("create"), UPDATE("update"), DROP("drop");
        private String text;

        private EVENT(String text) {
            this.text = text;
        }

        public String getType() {
            return text;
        }

        public static EVENT getEvent(String event) {
            for (EVENT one : values()) {
                if (one.getType().equalsIgnoreCase(event)) {
                    return one;
                }
            }

            return null;
        }
    }

    public static enum TYPE {
        ALL("all"), CUBE("cube"), CUBE_DESC("cube_desc"), PROJECT("project"), INVERTED_INDEX(
                "inverted_index"), INVERTED_INDEX_DESC("ii_desc"), TABLE("table"), DATA_MODEL("data_model");
        private String text;

        private TYPE(String text) {
            this.text = text;
        }

        public String getType() {
            return text;
        }

        /**
         * @param type
         * @return
         */
        public static TYPE getType(String type) {
            for (TYPE one : values()) {
                if (one.getType().equalsIgnoreCase(type)) {
                    return one;
                }
            }

            return null;
        }
    }

    public static class BroadcastEvent {
        private String type;
        private String action;
        private String name;

        public BroadcastEvent(String type, String action, String name) {
            super();
            this.type = type;
            this.action = action;
            this.name = name;
        }

        public String getType() {
            return type;
        }

        public String getAction() {
            return action;
        }

        public String getName() {
            return name;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((action == null) ? 0 : action.hashCode());
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            result = prime * result + ((type == null) ? 0 : type.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (this == obj) {
                return true;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            BroadcastEvent other = (BroadcastEvent) obj;
            if (!StringUtils.equals(action, other.action)) {
                return false;
            }
            if (!StringUtils.equals(name, other.name)) {
                return false;
            }
            if (!StringUtils.equals(type, other.type)) {
                return false;
            }
            return true;
        }

        @Override
        public String toString() {
            return Objects.toStringHelper(this).add("type", type).add("name", name).add("action", action)
                    .toString();
        }

    }
}