Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 86FF3200D0E for ; Tue, 26 Sep 2017 17:19:38 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 853DA1609B4; Tue, 26 Sep 2017 15:19:38 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 7E49E1609EB for ; Tue, 26 Sep 2017 17:19:36 +0200 (CEST) Received: (qmail 4799 invoked by uid 500); 26 Sep 2017 15:14:16 -0000 Mailing-List: contact commits-help@hbase.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@hbase.apache.org Delivered-To: mailing list commits@hbase.apache.org Received: (qmail 4646 invoked by uid 99); 26 Sep 2017 15:14:15 -0000 Received: from Unknown (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 26 Sep 2017 15:14:15 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 1839BDFA25; Tue, 26 Sep 2017 15:13:58 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: git-site-role@apache.org To: commits@hbase.apache.org Date: Tue, 26 Sep 2017 15:14:15 -0000 Message-Id: <79c6bfe623fa4fc4acd728feb63cd657@git.apache.org> In-Reply-To: <714958fce79c4c59ba58c0a117c68af5@git.apache.org> References: <714958fce79c4c59ba58c0a117c68af5@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [18/51] [partial] hbase-site git commit: Published site at . archived-at: Tue, 26 Sep 2017 15:19:38 -0000 http://git-wip-us.apache.org/repos/asf/hbase-site/blob/8e4e1542/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RegionServerCoprocessorHost.EnvironmentPriorityComparator.html ---------------------------------------------------------------------- diff --git a/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RegionServerCoprocessorHost.EnvironmentPriorityComparator.html b/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RegionServerCoprocessorHost.EnvironmentPriorityComparator.html index ec36d2e..1572f5f 100644 --- a/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RegionServerCoprocessorHost.EnvironmentPriorityComparator.html +++ b/devapidocs/src-html/org/apache/hadoop/hbase/regionserver/RegionServerCoprocessorHost.EnvironmentPriorityComparator.html @@ -34,330 +34,328 @@ 026import org.apache.commons.logging.Log; 027import org.apache.commons.logging.LogFactory; 028import org.apache.hadoop.conf.Configuration; -029import org.apache.hadoop.hbase.CellScanner; -030import org.apache.hadoop.hbase.Coprocessor; -031import org.apache.hadoop.hbase.CoprocessorEnvironment; -032import org.apache.hadoop.hbase.HBaseInterfaceAudience; -033import org.apache.yetus.audience.InterfaceAudience; -034import org.apache.yetus.audience.InterfaceStability; -035import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; -036import org.apache.hadoop.hbase.coprocessor.MetricsCoprocessor; -037import org.apache.hadoop.hbase.coprocessor.ObserverContext; -038import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment; -039import org.apache.hadoop.hbase.coprocessor.RegionServerObserver; -040import org.apache.hadoop.hbase.coprocessor.SingletonCoprocessorService; -041import org.apache.hadoop.hbase.ipc.RpcServer; -042import org.apache.hadoop.hbase.metrics.MetricRegistry; -043import org.apache.hadoop.hbase.replication.ReplicationEndpoint; -044import org.apache.hadoop.hbase.security.User; -045import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.WALEntry; -046 -047@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC) -048@InterfaceStability.Evolving -049public class RegionServerCoprocessorHost extends -050 CoprocessorHost<RegionServerCoprocessorHost.RegionServerEnvironment> { +029import org.apache.hadoop.hbase.Coprocessor; +030import org.apache.hadoop.hbase.CoprocessorEnvironment; +031import org.apache.hadoop.hbase.HBaseInterfaceAudience; +032import org.apache.yetus.audience.InterfaceAudience; +033import org.apache.yetus.audience.InterfaceStability; +034import org.apache.hadoop.hbase.coprocessor.CoprocessorHost; +035import org.apache.hadoop.hbase.coprocessor.MetricsCoprocessor; +036import org.apache.hadoop.hbase.coprocessor.ObserverContext; +037import org.apache.hadoop.hbase.coprocessor.RegionServerCoprocessorEnvironment; +038import org.apache.hadoop.hbase.coprocessor.RegionServerObserver; +039import org.apache.hadoop.hbase.coprocessor.SingletonCoprocessorService; +040import org.apache.hadoop.hbase.ipc.RpcServer; +041import org.apache.hadoop.hbase.metrics.MetricRegistry; +042import org.apache.hadoop.hbase.replication.ReplicationEndpoint; +043import org.apache.hadoop.hbase.security.User; +044 +045@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC) +046@InterfaceStability.Evolving +047public class RegionServerCoprocessorHost extends +048 CoprocessorHost<RegionServerCoprocessorHost.RegionServerEnvironment> { +049 +050 private static final Log LOG = LogFactory.getLog(RegionServerCoprocessorHost.class); 051 -052 private static final Log LOG = LogFactory.getLog(RegionServerCoprocessorHost.class); +052 private RegionServerServices rsServices; 053 -054 private RegionServerServices rsServices; -055 -056 public RegionServerCoprocessorHost(RegionServerServices rsServices, -057 Configuration conf) { -058 super(rsServices); -059 this.rsServices = rsServices; -060 this.conf = conf; -061 // Log the state of coprocessor loading here; should appear only once or -062 // twice in the daemon log, depending on HBase version, because there is -063 // only one RegionServerCoprocessorHost instance in the RS process -064 boolean coprocessorsEnabled = conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY, -065 DEFAULT_COPROCESSORS_ENABLED); -066 boolean tableCoprocessorsEnabled = conf.getBoolean(USER_COPROCESSORS_ENABLED_CONF_KEY, -067 DEFAULT_USER_COPROCESSORS_ENABLED); -068 LOG.info("System coprocessor loading is " + (coprocessorsEnabled ? "enabled" : "disabled")); -069 LOG.info("Table coprocessor loading is " + -070 ((coprocessorsEnabled && tableCoprocessorsEnabled) ? "enabled" : "disabled")); -071 loadSystemCoprocessors(conf, REGIONSERVER_COPROCESSOR_CONF_KEY); -072 } -073 -074 @Override -075 public RegionServerEnvironment createEnvironment(Class<?> implClass, -076 Coprocessor instance, int priority, int sequence, Configuration conf) { -077 return new RegionServerEnvironment(implClass, instance, priority, -078 sequence, conf, this.rsServices); -079 } -080 -081 public void preStop(String message, User user) throws IOException { -082 // While stopping the region server all coprocessors method should be executed first then the -083 // coprocessor should be cleaned up. -084 execShutdown(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { -085 @Override -086 public void call(RegionServerObserver oserver, -087 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { -088 oserver.preStopRegionServer(ctx); -089 } -090 @Override -091 public void postEnvCall(RegionServerEnvironment env) { -092 // invoke coprocessor stop method -093 shutdown(env); -094 } -095 }); -096 } -097 -098 public void preRollWALWriterRequest() throws IOException { -099 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { -100 @Override -101 public void call(RegionServerObserver oserver, -102 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { -103 oserver.preRollWALWriterRequest(ctx); -104 } -105 }); -106 } -107 -108 public void postRollWALWriterRequest() throws IOException { -109 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { -110 @Override -111 public void call(RegionServerObserver oserver, -112 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { -113 oserver.postRollWALWriterRequest(ctx); -114 } -115 }); -116 } -117 -118 public void preReplicateLogEntries(final List<WALEntry> entries, final CellScanner cells) -119 throws IOException { -120 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { -121 @Override -122 public void call(RegionServerObserver oserver, -123 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { -124 oserver.preReplicateLogEntries(ctx, entries, cells); -125 } -126 }); -127 } -128 -129 public void postReplicateLogEntries(final List<WALEntry> entries, final CellScanner cells) -130 throws IOException { -131 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { -132 @Override -133 public void call(RegionServerObserver oserver, -134 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { -135 oserver.postReplicateLogEntries(ctx, entries, cells); -136 } -137 }); -138 } -139 -140 public ReplicationEndpoint postCreateReplicationEndPoint(final ReplicationEndpoint endpoint) -141 throws IOException { -142 return execOperationWithResult(endpoint, coprocessors.isEmpty() ? null -143 : new CoprocessOperationWithResult<ReplicationEndpoint>() { -144 @Override -145 public void call(RegionServerObserver oserver, -146 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { -147 setResult(oserver.postCreateReplicationEndPoint(ctx, getResult())); -148 } -149 }); -150 } -151 -152 public void preClearCompactionQueues() throws IOException { -153 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { -154 @Override -155 public void call(RegionServerObserver oserver, -156 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { -157 oserver.preClearCompactionQueues(ctx); -158 } -159 }); -160 } -161 -162 public void postClearCompactionQueues() throws IOException { -163 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { -164 @Override -165 public void call(RegionServerObserver oserver, -166 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { -167 oserver.postClearCompactionQueues(ctx); -168 } -169 }); -170 } -171 -172 private <T> T execOperationWithResult(final T defaultValue, -173 final CoprocessOperationWithResult<T> ctx) throws IOException { -174 if (ctx == null) -175 return defaultValue; -176 ctx.setResult(defaultValue); -177 execOperation(ctx); -178 return ctx.getResult(); -179 } -180 -181 private static abstract class CoprocessorOperation -182 extends ObserverContext<RegionServerCoprocessorEnvironment> { -183 public CoprocessorOperation() { -184 this(RpcServer.getRequestUser()); -185 } -186 -187 public CoprocessorOperation(User user) { -188 super(user); -189 } -190 -191 public abstract void call(RegionServerObserver oserver, -192 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException; -193 -194 public void postEnvCall(RegionServerEnvironment env) { -195 } -196 } -197 -198 private static abstract class CoprocessOperationWithResult<T> extends CoprocessorOperation { -199 private T result = null; -200 -201 public void setResult(final T result) { -202 this.result = result; -203 } -204 -205 public T getResult() { -206 return this.result; -207 } -208 } -209 -210 private boolean execOperation(final CoprocessorOperation ctx) throws IOException { -211 if (ctx == null) return false; -212 boolean bypass = false; -213 List<RegionServerEnvironment> envs = coprocessors.get(); -214 for (int i = 0; i < envs.size(); i++) { -215 RegionServerEnvironment env = envs.get(i); -216 if (env.getInstance() instanceof RegionServerObserver) { -217 ctx.prepare(env); -218 Thread currentThread = Thread.currentThread(); -219 ClassLoader cl = currentThread.getContextClassLoader(); -220 try { -221 currentThread.setContextClassLoader(env.getClassLoader()); -222 ctx.call((RegionServerObserver)env.getInstance(), ctx); -223 } catch (Throwable e) { -224 handleCoprocessorThrowable(env, e); -225 } finally { -226 currentThread.setContextClassLoader(cl); -227 } -228 bypass |= ctx.shouldBypass(); -229 if (ctx.shouldComplete()) { -230 break; -231 } -232 } -233 ctx.postEnvCall(env); -234 } -235 return bypass; -236 } -237 -238 /** -239 * RegionServer coprocessor classes can be configured in any order, based on that priority is set -240 * and chained in a sorted order. For preStop(), coprocessor methods are invoked in call() and -241 * environment is shutdown in postEnvCall(). <br> -242 * Need to execute all coprocessor methods first then postEnvCall(), otherwise some coprocessors -243 * may remain shutdown if any exception occurs during next coprocessor execution which prevent -244 * RegionServer stop. (Refer: -245 * <a href="https://issues.apache.org/jira/browse/HBASE-16663">HBASE-16663</a> -246 * @param ctx CoprocessorOperation -247 * @return true if bypaas coprocessor execution, false if not. -248 * @throws IOException -249 */ -250 private boolean execShutdown(final CoprocessorOperation ctx) throws IOException { -251 if (ctx == null) return false; -252 boolean bypass = false; -253 List<RegionServerEnvironment> envs = coprocessors.get(); -254 int envsSize = envs.size(); -255 // Iterate the coprocessors and execute CoprocessorOperation's call() -256 for (int i = 0; i < envsSize; i++) { -257 RegionServerEnvironment env = envs.get(i); -258 if (env.getInstance() instanceof RegionServerObserver) { -259 ctx.prepare(env); -260 Thread currentThread = Thread.currentThread(); -261 ClassLoader cl = currentThread.getContextClassLoader(); -262 try { -263 currentThread.setContextClassLoader(env.getClassLoader()); -264 ctx.call((RegionServerObserver) env.getInstance(), ctx); -265 } catch (Throwable e) { -266 handleCoprocessorThrowable(env, e); -267 } finally { -268 currentThread.setContextClassLoader(cl); -269 } -270 bypass |= ctx.shouldBypass(); -271 if (ctx.shouldComplete()) { -272 break; -273 } -274 } -275 } -276 -277 // Iterate the coprocessors and execute CoprocessorOperation's postEnvCall() -278 for (int i = 0; i < envsSize; i++) { -279 RegionServerEnvironment env = envs.get(i); -280 ctx.postEnvCall(env); -281 } -282 return bypass; -283 } -284 -285 /** -286 * Coprocessor environment extension providing access to region server -287 * related services. -288 */ -289 static class RegionServerEnvironment extends CoprocessorHost.Environment -290 implements RegionServerCoprocessorEnvironment { -291 private final RegionServerServices regionServerServices; -292 private final MetricRegistry metricRegistry; -293 -294 @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="BC_UNCONFIRMED_CAST", -295 justification="Intentional; FB has trouble detecting isAssignableFrom") -296 public RegionServerEnvironment(final Class<?> implClass, -297 final Coprocessor impl, final int priority, final int seq, -298 final Configuration conf, final RegionServerServices services) { -299 super(impl, priority, seq, conf); -300 this.regionServerServices = services; -301 for (Object itf : ClassUtils.getAllInterfaces(implClass)) { -302 Class<?> c = (Class<?>) itf; -303 if (SingletonCoprocessorService.class.isAssignableFrom(c)) {// FindBugs: BC_UNCONFIRMED_CAST -304 this.regionServerServices.registerService( -305 ((SingletonCoprocessorService) impl).getService()); -306 break; -307 } -308 } -309 this.metricRegistry = -310 MetricsCoprocessor.createRegistryForRSCoprocessor(implClass.getName()); -311 } -312 -313 @Override -314 public RegionServerServices getRegionServerServices() { -315 return regionServerServices; -316 } -317 -318 @Override -319 public MetricRegistry getMetricRegistryForRegionServer() { -320 return metricRegistry; -321 } -322 -323 @Override -324 protected void shutdown() { -325 super.shutdown(); -326 MetricsCoprocessor.removeRegistry(metricRegistry); -327 } -328 } -329 -330 /** -331 * Environment priority comparator. Coprocessors are chained in sorted -332 * order. -333 */ -334 static class EnvironmentPriorityComparator implements -335 Comparator<CoprocessorEnvironment> { -336 @Override -337 public int compare(final CoprocessorEnvironment env1, -338 final CoprocessorEnvironment env2) { -339 if (env1.getPriority() < env2.getPriority()) { -340 return -1; -341 } else if (env1.getPriority() > env2.getPriority()) { -342 return 1; -343 } -344 if (env1.getLoadSequence() < env2.getLoadSequence()) { -345 return -1; -346 } else if (env1.getLoadSequence() > env2.getLoadSequence()) { -347 return 1; -348 } -349 return 0; -350 } -351 } -352} +054 public RegionServerCoprocessorHost(RegionServerServices rsServices, +055 Configuration conf) { +056 super(rsServices); +057 this.rsServices = rsServices; +058 this.conf = conf; +059 // Log the state of coprocessor loading here; should appear only once or +060 // twice in the daemon log, depending on HBase version, because there is +061 // only one RegionServerCoprocessorHost instance in the RS process +062 boolean coprocessorsEnabled = conf.getBoolean(COPROCESSORS_ENABLED_CONF_KEY, +063 DEFAULT_COPROCESSORS_ENABLED); +064 boolean tableCoprocessorsEnabled = conf.getBoolean(USER_COPROCESSORS_ENABLED_CONF_KEY, +065 DEFAULT_USER_COPROCESSORS_ENABLED); +066 LOG.info("System coprocessor loading is " + (coprocessorsEnabled ? "enabled" : "disabled")); +067 LOG.info("Table coprocessor loading is " + +068 ((coprocessorsEnabled && tableCoprocessorsEnabled) ? "enabled" : "disabled")); +069 loadSystemCoprocessors(conf, REGIONSERVER_COPROCESSOR_CONF_KEY); +070 } +071 +072 @Override +073 public RegionServerEnvironment createEnvironment(Class<?> implClass, +074 Coprocessor instance, int priority, int sequence, Configuration conf) { +075 return new RegionServerEnvironment(implClass, instance, priority, +076 sequence, conf, this.rsServices); +077 } +078 +079 public void preStop(String message, User user) throws IOException { +080 // While stopping the region server all coprocessors method should be executed first then the +081 // coprocessor should be cleaned up. +082 execShutdown(coprocessors.isEmpty() ? null : new CoprocessorOperation(user) { +083 @Override +084 public void call(RegionServerObserver oserver, +085 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { +086 oserver.preStopRegionServer(ctx); +087 } +088 @Override +089 public void postEnvCall(RegionServerEnvironment env) { +090 // invoke coprocessor stop method +091 shutdown(env); +092 } +093 }); +094 } +095 +096 public void preRollWALWriterRequest() throws IOException { +097 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { +098 @Override +099 public void call(RegionServerObserver oserver, +100 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { +101 oserver.preRollWALWriterRequest(ctx); +102 } +103 }); +104 } +105 +106 public void postRollWALWriterRequest() throws IOException { +107 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { +108 @Override +109 public void call(RegionServerObserver oserver, +110 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { +111 oserver.postRollWALWriterRequest(ctx); +112 } +113 }); +114 } +115 +116 public void preReplicateLogEntries() +117 throws IOException { +118 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { +119 @Override +120 public void call(RegionServerObserver oserver, +121 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { +122 oserver.preReplicateLogEntries(ctx); +123 } +124 }); +125 } +126 +127 public void postReplicateLogEntries() +128 throws IOException { +129 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { +130 @Override +131 public void call(RegionServerObserver oserver, +132 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { +133 oserver.postReplicateLogEntries(ctx); +134 } +135 }); +136 } +137 +138 public ReplicationEndpoint postCreateReplicationEndPoint(final ReplicationEndpoint endpoint) +139 throws IOException { +140 return execOperationWithResult(endpoint, coprocessors.isEmpty() ? null +141 : new CoprocessOperationWithResult<ReplicationEndpoint>() { +142 @Override +143 public void call(RegionServerObserver oserver, +144 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { +145 setResult(oserver.postCreateReplicationEndPoint(ctx, getResult())); +146 } +147 }); +148 } +149 +150 public void preClearCompactionQueues() throws IOException { +151 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { +152 @Override +153 public void call(RegionServerObserver oserver, +154 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { +155 oserver.preClearCompactionQueues(ctx); +156 } +157 }); +158 } +159 +160 public void postClearCompactionQueues() throws IOException { +161 execOperation(coprocessors.isEmpty() ? null : new CoprocessorOperation() { +162 @Override +163 public void call(RegionServerObserver oserver, +164 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException { +165 oserver.postClearCompactionQueues(ctx); +166 } +167 }); +168 } +169 +170 private <T> T execOperationWithResult(final T defaultValue, +171 final CoprocessOperationWithResult<T> ctx) throws IOException { +172 if (ctx == null) +173 return defaultValue; +174 ctx.setResult(defaultValue); +175 execOperation(ctx); +176 return ctx.getResult(); +177 } +178 +179 private static abstract class CoprocessorOperation +180 extends ObserverContext<RegionServerCoprocessorEnvironment> { +181 public CoprocessorOperation() { +182 this(RpcServer.getRequestUser()); +183 } +184 +185 public CoprocessorOperation(User user) { +186 super(user); +187 } +188 +189 public abstract void call(RegionServerObserver oserver, +190 ObserverContext<RegionServerCoprocessorEnvironment> ctx) throws IOException; +191 +192 public void postEnvCall(RegionServerEnvironment env) { +193 } +194 } +195 +196 private static abstract class CoprocessOperationWithResult<T> extends CoprocessorOperation { +197 private T result = null; +198 +199 public void setResult(final T result) { +200 this.result = result; +201 } +202 +203 public T getResult() { +204 return this.result; +205 } +206 } +207 +208 private boolean execOperation(final CoprocessorOperation ctx) throws IOException { +209 if (ctx == null) return false; +210 boolean bypass = false; +211 List<RegionServerEnvironment> envs = coprocessors.get(); +212 for (int i = 0; i < envs.size(); i++) { +213 RegionServerEnvironment env = envs.get(i); +214 if (env.getInstance() instanceof RegionServerObserver) { +215 ctx.prepare(env); +216 Thread currentThread = Thread.currentThread(); +217 ClassLoader cl = currentThread.getContextClassLoader(); +218 try { +219 currentThread.setContextClassLoader(env.getClassLoader()); +220 ctx.call((RegionServerObserver)env.getInstance(), ctx); +221 } catch (Throwable e) { +222 handleCoprocessorThrowable(env, e); +223 } finally { +224 currentThread.setContextClassLoader(cl); +225 } +226 bypass |= ctx.shouldBypass(); +227 if (ctx.shouldComplete()) { +228 break; +229 } +230 } +231 ctx.postEnvCall(env); +232 } +233 return bypass; +234 } +235 +236 /** +237 * RegionServer coprocessor classes can be configured in any order, based on that priority is set +238 * and chained in a sorted order. For preStop(), coprocessor methods are invoked in call() and +239 * environment is shutdown in postEnvCall(). <br> +240 * Need to execute all coprocessor methods first then postEnvCall(), otherwise some coprocessors +241 * may remain shutdown if any exception occurs during next coprocessor execution which prevent +242 * RegionServer stop. (Refer: +243 * <a href="https://issues.apache.org/jira/browse/HBASE-16663">HBASE-16663</a> +244 * @param ctx CoprocessorOperation +245 * @return true if bypaas coprocessor execution, false if not. +246 * @throws IOException +247 */ +248 private boolean execShutdown(final CoprocessorOperation ctx) throws IOException { +249 if (ctx == null) return false; +250 boolean bypass = false; +251 List<RegionServerEnvironment> envs = coprocessors.get(); +252 int envsSize = envs.size(); +253 // Iterate the coprocessors and execute CoprocessorOperation's call() +254 for (int i = 0; i < envsSize; i++) { +255 RegionServerEnvironment env = envs.get(i); +256 if (env.getInstance() instanceof RegionServerObserver) { +257 ctx.prepare(env); +258 Thread currentThread = Thread.currentThread(); +259 ClassLoader cl = currentThread.getContextClassLoader(); +260 try { +261 currentThread.setContextClassLoader(env.getClassLoader()); +262 ctx.call((RegionServerObserver) env.getInstance(), ctx); +263 } catch (Throwable e) { +264 handleCoprocessorThrowable(env, e); +265 } finally { +266 currentThread.setContextClassLoader(cl); +267 } +268 bypass |= ctx.shouldBypass(); +269 if (ctx.shouldComplete()) { +270 break; +271 } +272 } +273 } +274 +275 // Iterate the coprocessors and execute CoprocessorOperation's postEnvCall() +276 for (int i = 0; i < envsSize; i++) { +277 RegionServerEnvironment env = envs.get(i); +278 ctx.postEnvCall(env); +279 } +280 return bypass; +281 } +282 +283 /** +284 * Coprocessor environment extension providing access to region server +285 * related services. +286 */ +287 static class RegionServerEnvironment extends CoprocessorHost.Environment +288 implements RegionServerCoprocessorEnvironment { +289 private final RegionServerServices regionServerServices; +290 private final MetricRegistry metricRegistry; +291 +292 @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="BC_UNCONFIRMED_CAST", +293 justification="Intentional; FB has trouble detecting isAssignableFrom") +294 public RegionServerEnvironment(final Class<?> implClass, +295 final Coprocessor impl, final int priority, final int seq, +296 final Configuration conf, final RegionServerServices services) { +297 super(impl, priority, seq, conf); +298 this.regionServerServices = services; +299 for (Object itf : ClassUtils.getAllInterfaces(implClass)) { +300 Class<?> c = (Class<?>) itf; +301 if (SingletonCoprocessorService.class.isAssignableFrom(c)) {// FindBugs: BC_UNCONFIRMED_CAST +302 this.regionServerServices.registerService( +303 ((SingletonCoprocessorService) impl).getService()); +304 break; +305 } +306 } +307 this.metricRegistry = +308 MetricsCoprocessor.createRegistryForRSCoprocessor(implClass.getName()); +309 } +310 +311 @Override +312 public RegionServerServices getRegionServerServices() { +313 return regionServerServices; +314 } +315 +316 @Override +317 public MetricRegistry getMetricRegistryForRegionServer() { +318 return metricRegistry; +319 } +320 +321 @Override +322 protected void shutdown() { +323 super.shutdown(); +324 MetricsCoprocessor.removeRegistry(metricRegistry); +325 } +326 } +327 +328 /** +329 * Environment priority comparator. Coprocessors are chained in sorted +330 * order. +331 */ +332 static class EnvironmentPriorityComparator implements +333 Comparator<CoprocessorEnvironment> { +334 @Override +335 public int compare(final CoprocessorEnvironment env1, +336 final CoprocessorEnvironment env2) { +337 if (env1.getPriority() < env2.getPriority()) { +338 return -1; +339 } else if (env1.getPriority() > env2.getPriority()) { +340 return 1; +341 } +342 if (env1.getLoadSequence() < env2.getLoadSequence()) { +343 return -1; +344 } else if (env1.getLoadSequence() > env2.getLoadSequence()) { +345 return 1; +346 } +347 return 0; +348 } +349 } +350}