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.client; 019 020import java.util.Optional; 021import org.apache.yetus.audience.InterfaceAudience; 022 023/** 024 * This is the low level API for asynchronous scan. 025 * <p> 026 * All results that match the given scan object will be passed to this class by calling 027 * {@link #onNext(Result[], ScanController)}. {@link #onComplete()} means the scan is finished, and 028 * {@link #onError(Throwable)} means we hit an unrecoverable error and the scan is terminated. 029 * {@link #onHeartbeat(ScanController)} means the RS is still working but we can not get a valid 030 * result to call {@link #onNext(Result[], ScanController)}. This is usually because the matched 031 * results are too sparse, for example, a filter which almost filters out everything is specified. 032 * <p> 033 * Notice that, all the methods here will be called directly in the thread which we send request to 034 * HBase service. So if you want the asynchronous scanner fetch data from HBase in background while 035 * you process the returned data, you need to move the processing work to another thread to make the 036 * {@link #onNext(Result[], ScanController)} call return immediately. And please do NOT do any time 037 * consuming tasks in these methods unless you know what you are doing. 038 * @since 2.0.0 039 */ 040@InterfaceAudience.Public 041public interface AdvancedScanResultConsumer extends ScanResultConsumerBase { 042 043 /** 044 * Used to resume a scan. 045 */ 046 @InterfaceAudience.Public 047 interface ScanResumer { 048 049 /** 050 * Resume the scan. You are free to call it multiple time but only the first call will take 051 * effect. 052 */ 053 void resume(); 054 } 055 056 /** 057 * Used to suspend or stop a scan, or get a scan cursor if available. 058 * <p> 059 * Notice that, you should only call the {@link #suspend()} or {@link #terminate()} inside onNext 060 * or onHeartbeat method. A IllegalStateException will be thrown if you call them at other places. 061 * <p> 062 * You can only call one of the {@link #suspend()} and {@link #terminate()} methods(of course you 063 * are free to not call them both), and the methods are not reentrant. An IllegalStateException 064 * will be thrown if you have already called one of the methods. 065 */ 066 @InterfaceAudience.Public 067 interface ScanController { 068 069 /** 070 * Suspend the scan. 071 * <p> 072 * This means we will stop fetching data in background, i.e., will not call onNext any more 073 * before you resume the scan. 074 * @return A resumer used to resume the scan later. 075 */ 076 ScanResumer suspend(); 077 078 /** 079 * Terminate the scan. 080 * <p> 081 * This is useful when you have got enough results and want to stop the scan in onNext method, 082 * or you want to stop the scan in onHeartbeat method because it has spent too many time. 083 */ 084 void terminate(); 085 086 /** 087 * Get the scan cursor if available. 088 * @return The scan cursor. 089 */ 090 Optional<Cursor> cursor(); 091 } 092 093 /** 094 * Indicate that we have receive some data. 095 * @param results the data fetched from HBase service. 096 * @param controller used to suspend or terminate the scan. Notice that the {@code controller} 097 * instance is only valid within scope of onNext method. You can only call its 098 * method in onNext, do NOT store it and call it later outside onNext. 099 */ 100 void onNext(Result[] results, ScanController controller); 101 102 /** 103 * Indicate that there is a heartbeat message but we have not cumulated enough cells to call 104 * {@link #onNext(Result[], ScanController)}. 105 * <p> 106 * Note that this method will always be called when RS returns something to us but we do not have 107 * enough cells to call {@link #onNext(Result[], ScanController)}. Sometimes it may not be a 108 * 'heartbeat' message for RS, for example, we have a large row with many cells and size limit is 109 * exceeded before sending all the cells for this row. For RS it does send some data to us and the 110 * time limit has not been reached, but we can not return the data to client so here we call this 111 * method to tell client we have already received something. 112 * <p> 113 * This method give you a chance to terminate a slow scan operation. 114 * @param controller used to suspend or terminate the scan. Notice that the {@code controller} 115 * instance is only valid within the scope of onHeartbeat method. You can only 116 * call its method in onHeartbeat, do NOT store it and call it later outside 117 * onHeartbeat. 118 */ 119 default void onHeartbeat(ScanController controller) { 120 } 121}