View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.hbtop.screen;
19  
20  import edu.umd.cs.findbugs.annotations.Nullable;
21  import java.io.Closeable;
22  import java.io.IOException;
23  import java.util.List;
24  import java.util.concurrent.TimeUnit;
25  
26  import org.apache.commons.logging.Log;
27  import org.apache.commons.logging.LogFactory;
28  import org.apache.hadoop.conf.Configuration;
29  import org.apache.hadoop.hbase.classification.InterfaceAudience;
30  import org.apache.hadoop.hbase.client.Admin;
31  import org.apache.hadoop.hbase.client.Connection;
32  import org.apache.hadoop.hbase.client.ConnectionFactory;
33  import org.apache.hadoop.hbase.hbtop.RecordFilter;
34  import org.apache.hadoop.hbase.hbtop.field.Field;
35  import org.apache.hadoop.hbase.hbtop.mode.Mode;
36  import org.apache.hadoop.hbase.hbtop.screen.top.TopScreenView;
37  import org.apache.hadoop.hbase.hbtop.terminal.KeyPress;
38  import org.apache.hadoop.hbase.hbtop.terminal.Terminal;
39  import org.apache.hadoop.hbase.hbtop.terminal.impl.TerminalImpl;
40  import org.apache.hadoop.hbase.hbtop.terminal.impl.batch.BatchTerminal;
41  
42  /**
43   * This dispatches key presses and timers to the current {@link ScreenView}.
44   */
45  @InterfaceAudience.Private
46  public class Screen implements Closeable {
47  
48    private static final Log LOG = LogFactory.getLog(Screen.class);
49  
50    private static final long SLEEP_TIMEOUT_MILLISECONDS = 100;
51  
52    private final Connection connection;
53    private final Admin admin;
54    private final Terminal terminal;
55  
56    private ScreenView currentScreenView;
57    private Long timerTimestamp;
58  
59    public Screen(Configuration conf, long initialRefreshDelay, Mode initialMode,
60      @Nullable List<Field> initialFields, @Nullable Field initialSortField,
61      @Nullable Boolean initialAscendingSort, @Nullable List<RecordFilter> initialFilters,
62      long numberOfIterations, boolean batchMode)
63      throws IOException {
64      connection = ConnectionFactory.createConnection(conf);
65      admin = connection.getAdmin();
66  
67      // The first screen is the top screen
68      if (batchMode) {
69        terminal = new BatchTerminal();
70      } else {
71        terminal = new TerminalImpl("hbtop");
72      }
73      currentScreenView = new TopScreenView(this, terminal, initialRefreshDelay, admin,
74        initialMode, initialFields, initialSortField, initialAscendingSort, initialFilters,
75        numberOfIterations);
76    }
77  
78    @Override
79    public void close() throws IOException {
80      try {
81        admin.close();
82      } finally {
83        try {
84          connection.close();
85        } finally {
86          terminal.close();
87        }
88      }
89    }
90  
91    public void run() {
92      currentScreenView.init();
93      while (true) {
94        try {
95          KeyPress keyPress = terminal.pollKeyPress();
96  
97          ScreenView nextScreenView;
98          if (keyPress != null) {
99            // Dispatch the key press to the current screen
100           nextScreenView = currentScreenView.handleKeyPress(keyPress);
101         } else {
102           if (timerTimestamp != null) {
103             long now = System.currentTimeMillis();
104             if (timerTimestamp <= now) {
105               // Dispatch the timer to the current screen
106               timerTimestamp = null;
107               nextScreenView = currentScreenView.handleTimer();
108             } else {
109               TimeUnit.MILLISECONDS
110                 .sleep(Math.min(timerTimestamp - now, SLEEP_TIMEOUT_MILLISECONDS));
111               continue;
112             }
113           } else {
114             TimeUnit.MILLISECONDS.sleep(SLEEP_TIMEOUT_MILLISECONDS);
115             continue;
116           }
117         }
118 
119         // If the next screen is null, then exit
120         if (nextScreenView == null) {
121           return;
122         }
123 
124         // If the next screen is not the previous, then go to the next screen
125         if (nextScreenView != currentScreenView) {
126           currentScreenView = nextScreenView;
127           currentScreenView.init();
128         }
129       } catch (Exception e) {
130         LOG.error("Caught an exception", e);
131       }
132     }
133   }
134 
135   public void setTimer(long delay) {
136     timerTimestamp = System.currentTimeMillis() + delay;
137   }
138 
139   public void cancelTimer() {
140     timerTimestamp = null;
141   }
142 }