/** * 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 com.alibaba.jstorm.batch.example; import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.log4j.Logger; import backtype.storm.task.TopologyContext; import backtype.storm.topology.BasicOutputCollector; import backtype.storm.topology.IBasicBolt; import backtype.storm.topology.OutputFieldsDeclarer; import backtype.storm.tuple.Fields; import backtype.storm.tuple.Tuple; import backtype.storm.tuple.Values; import com.alibaba.jstorm.batch.BatchId; import com.alibaba.jstorm.batch.IPostCommit; import com.alibaba.jstorm.utils.JStormUtils; public class BatchMetaRebalance implements IBasicBolt, IPostCommit { /** */ private static final long serialVersionUID = 2991323223385556163L; private static final Logger LOG = Logger .getLogger(BatchMetaRebalance.class); public static final String BOLT_NAME = BatchMetaRebalance.class .getSimpleName(); public static final String REBALANCE_STREAM_ID = "rebalance"; private transient AtomicBoolean isNeedRebalance; private transient ScheduledExecutorService scheduExec; @Override public void prepare(Map stormConf, TopologyContext context) { isNeedRebalance = new AtomicBoolean(false); CheckRebalanceTimer timer = new CheckRebalanceTimer(); int rebalanceTimeInterval = JStormUtils.parseInt( stormConf.get("meta.rebalance.frequency.sec"), 3600); long now = System.currentTimeMillis(); long next = (now/(rebalanceTimeInterval * 1000) + 1) * rebalanceTimeInterval * 1000; long diff = (next - now )/1000; // Calendar start = Calendar.getInstance(); // // start.add(Calendar.HOUR_OF_DAY, 1); // // start.set(Calendar.MINUTE, 30); // start.set(Calendar.SECOND, 0); // start.set(Calendar.MILLISECOND, 0); // long startMillis = start.getTimeInMillis(); // // long now = System.currentTimeMillis(); // // long diff = (startMillis - now) / (1000); ScheduledExecutorService scheduExec = null; scheduExec = Executors.newSingleThreadScheduledExecutor(); scheduExec.scheduleAtFixedRate(timer, diff, rebalanceTimeInterval, TimeUnit.SECONDS); LOG.info("Successfully init rebalance timer"); } @Override public void execute(Tuple input, BasicOutputCollector collector) { LOG.warn("Receive unkonw message"); } @Override public void cleanup() { scheduExec.shutdown(); LOG.info("Successfully do cleanup"); } @Override public void postCommit(BatchId id, BasicOutputCollector collector) { if (isNeedRebalance.get() == true) { isNeedRebalance.set(false); collector.emit(REBALANCE_STREAM_ID, new Values(id)); LOG.info("Emit rebalance command"); } } @Override public void declareOutputFields(OutputFieldsDeclarer declarer) { declarer.declareStream(REBALANCE_STREAM_ID, new Fields("BatchId")); } @Override public Map<String, Object> getComponentConfiguration() { return null; } public class CheckRebalanceTimer implements Runnable { public void run() { BatchMetaRebalance.this.isNeedRebalance.set(true); } } }