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.yetus.audience.InterfaceAudience; 038import org.slf4j.Logger; 039import org.slf4j.LoggerFactory; 040 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) 061 throws IOException { 062 connection = ConnectionFactory.createConnection(conf); 063 admin = connection.getAdmin(); 064 065 // The first screen is the top screen 066 if (batchMode) { 067 terminal = new BatchTerminal(); 068 } else { 069 terminal = new TerminalImpl("hbtop"); 070 } 071 currentScreenView = new TopScreenView(this, terminal, initialRefreshDelay, admin, 072 initialMode, initialFields, initialSortField, initialAscendingSort, initialFilters, 073 numberOfIterations); 074 } 075 076 @Override 077 public void close() throws IOException { 078 try { 079 admin.close(); 080 } finally { 081 try { 082 connection.close(); 083 } finally { 084 terminal.close(); 085 } 086 } 087 } 088 089 public void run() { 090 currentScreenView.init(); 091 while (true) { 092 try { 093 KeyPress keyPress = terminal.pollKeyPress(); 094 095 ScreenView nextScreenView; 096 if (keyPress != null) { 097 // Dispatch the key press to the current screen 098 nextScreenView = currentScreenView.handleKeyPress(keyPress); 099 } else { 100 if (timerTimestamp != null) { 101 long now = System.currentTimeMillis(); 102 if (timerTimestamp <= now) { 103 // Dispatch the timer to the current screen 104 timerTimestamp = null; 105 nextScreenView = currentScreenView.handleTimer(); 106 } else { 107 TimeUnit.MILLISECONDS 108 .sleep(Math.min(timerTimestamp - now, SLEEP_TIMEOUT_MILLISECONDS)); 109 continue; 110 } 111 } else { 112 TimeUnit.MILLISECONDS.sleep(SLEEP_TIMEOUT_MILLISECONDS); 113 continue; 114 } 115 } 116 117 // If the next screen is null, then exit 118 if (nextScreenView == null) { 119 return; 120 } 121 122 // If the next screen is not the previous, then go to the next screen 123 if (nextScreenView != currentScreenView) { 124 currentScreenView = nextScreenView; 125 currentScreenView.init(); 126 } 127 } catch (Exception e) { 128 LOGGER.error("Caught an exception", e); 129 } 130 } 131 } 132 133 public void setTimer(long delay) { 134 timerTimestamp = System.currentTimeMillis() + delay; 135 } 136 137 public void cancelTimer() { 138 timerTimestamp = null; 139 } 140}