001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.hbtop.screen; 019 020import edu.umd.cs.findbugs.annotations.Nullable; 021import java.io.Closeable; 022import java.io.IOException; 023import java.util.List; 024import java.util.concurrent.TimeUnit; 025import org.apache.hadoop.conf.Configuration; 026import org.apache.hadoop.hbase.client.Admin; 027import org.apache.hadoop.hbase.client.Connection; 028import org.apache.hadoop.hbase.client.ConnectionFactory; 029import org.apache.hadoop.hbase.hbtop.RecordFilter; 030import org.apache.hadoop.hbase.hbtop.field.Field; 031import org.apache.hadoop.hbase.hbtop.mode.Mode; 032import org.apache.hadoop.hbase.hbtop.screen.top.TopScreenView; 033import org.apache.hadoop.hbase.hbtop.terminal.KeyPress; 034import org.apache.hadoop.hbase.hbtop.terminal.Terminal; 035import org.apache.hadoop.hbase.hbtop.terminal.impl.TerminalImpl; 036import org.apache.hadoop.hbase.hbtop.terminal.impl.batch.BatchTerminal; 037import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 038import org.apache.yetus.audience.InterfaceAudience; 039import org.slf4j.Logger; 040import org.slf4j.LoggerFactory; 041 042/** 043 * This dispatches key presses and timers to the current {@link ScreenView}. 044 */ 045@InterfaceAudience.Private 046public class Screen implements Closeable { 047 private static final Logger LOGGER = LoggerFactory.getLogger(Screen.class); 048 private static final long SLEEP_TIMEOUT_MILLISECONDS = 100; 049 050 private final Connection connection; 051 private final Admin admin; 052 private final Terminal terminal; 053 054 private ScreenView currentScreenView; 055 private Long timerTimestamp; 056 057 public Screen(Configuration conf, long initialRefreshDelay, Mode initialMode, 058 @Nullable List<Field> initialFields, @Nullable Field initialSortField, 059 @Nullable Boolean initialAscendingSort, @Nullable List<RecordFilter> initialFilters, 060 long numberOfIterations, boolean batchMode) throws IOException { 061 connection = ConnectionFactory.createConnection(conf); 062 admin = connection.getAdmin(); 063 064 // The first screen is the top screen 065 if (batchMode) { 066 terminal = new BatchTerminal(); 067 } else { 068 terminal = new TerminalImpl("hbtop"); 069 } 070 currentScreenView = new TopScreenView(this, terminal, initialRefreshDelay, admin, initialMode, 071 initialFields, initialSortField, initialAscendingSort, initialFilters, numberOfIterations); 072 } 073 074 @Override 075 public void close() throws IOException { 076 try { 077 admin.close(); 078 } finally { 079 try { 080 connection.close(); 081 } finally { 082 terminal.close(); 083 } 084 } 085 } 086 087 public void run() { 088 currentScreenView.init(); 089 while (true) { 090 try { 091 KeyPress keyPress = terminal.pollKeyPress(); 092 093 ScreenView nextScreenView; 094 if (keyPress != null) { 095 // Dispatch the key press to the current screen 096 nextScreenView = currentScreenView.handleKeyPress(keyPress); 097 } else { 098 if (timerTimestamp != null) { 099 long now = EnvironmentEdgeManager.currentTime(); 100 if (timerTimestamp <= now) { 101 // Dispatch the timer to the current screen 102 timerTimestamp = null; 103 nextScreenView = currentScreenView.handleTimer(); 104 } else { 105 TimeUnit.MILLISECONDS 106 .sleep(Math.min(timerTimestamp - now, SLEEP_TIMEOUT_MILLISECONDS)); 107 continue; 108 } 109 } else { 110 TimeUnit.MILLISECONDS.sleep(SLEEP_TIMEOUT_MILLISECONDS); 111 continue; 112 } 113 } 114 115 // If the next screen is null, then exit 116 if (nextScreenView == null) { 117 return; 118 } 119 120 // If the next screen is not the previous, then go to the next screen 121 if (nextScreenView != currentScreenView) { 122 currentScreenView = nextScreenView; 123 currentScreenView.init(); 124 } 125 } catch (Exception e) { 126 LOGGER.error("Caught an exception", e); 127 } 128 } 129 } 130 131 public void setTimer(long delay) { 132 timerTimestamp = EnvironmentEdgeManager.currentTime() + delay; 133 } 134 135 public void cancelTimer() { 136 timerTimestamp = null; 137 } 138}