Performs a graceful shutdown of this instance. #flush Flushes all buffered edits. Completes all outstanding requests. Terminates all connections. Releases all other resources. Not calling this method before losing the last re
()
| 1039 | * failure. TODO(tsuna): Document possible / common failure scenarios. |
| 1040 | */ |
| 1041 | public Deferred<Object> shutdown() { |
| 1042 | // This is part of step 3. We need to execute this in its own thread |
| 1043 | // because Netty gets stuck in an infinite loop if you try to shut it |
| 1044 | // down from within a thread of its own thread pool. They don't want |
| 1045 | // to fix this so as a workaround we always shut Netty's thread pool |
| 1046 | // down from another thread. |
| 1047 | final class ShutdownThread extends Thread { |
| 1048 | ShutdownThread() { |
| 1049 | super("HBaseClient@" + HBaseClient.super.hashCode() + " shutdown"); |
| 1050 | } |
| 1051 | public void run() { |
| 1052 | // This terminates the Executor. |
| 1053 | channel_factory.releaseExternalResources(); |
| 1054 | } |
| 1055 | }; |
| 1056 | |
| 1057 | // 3. Release all other resources. |
| 1058 | final class ReleaseResourcesCB implements Callback<Object, Object> { |
| 1059 | public Object call(final Object arg) { |
| 1060 | LOG.debug("Releasing all remaining resources"); |
| 1061 | timer.stop(); |
| 1062 | rpc_timeout_timer.stop(); |
| 1063 | new ShutdownThread().start(); |
| 1064 | return arg; |
| 1065 | } |
| 1066 | public String toString() { |
| 1067 | return "release resources callback"; |
| 1068 | } |
| 1069 | } |
| 1070 | |
| 1071 | // 2. Terminate all connections. |
| 1072 | final class DisconnectCB implements Callback<Object, Object> { |
| 1073 | public Object call(final Object arg) { |
| 1074 | return disconnectEverything().addCallback(new ReleaseResourcesCB()); |
| 1075 | } |
| 1076 | public String toString() { |
| 1077 | return "disconnect callback"; |
| 1078 | } |
| 1079 | } |
| 1080 | |
| 1081 | // If some RPCs are waiting for -ROOT- to be discovered, we too must wait |
| 1082 | // because some of those RPCs could be edits that we must not lose. |
| 1083 | final Deferred<Object> d = zkclient.getDeferredRootIfBeingLookedUp(); |
| 1084 | if (d != null) { |
| 1085 | LOG.debug("Shutdown needs to wait on {} to come back", |
| 1086 | has_root ? (split_meta ? new String(HBASE98_ROOT_REGION) : new String(ROOT)) |
| 1087 | : (split_meta ? new String(HBASE96_META) : new String(META))); |
| 1088 | final class RetryShutdown implements Callback<Object, Object> { |
| 1089 | public Object call(final Object arg) { |
| 1090 | LOG.debug("Shutdown retrying after {} came back", |
| 1091 | has_root ? (split_meta ? new String(HBASE98_ROOT_REGION) : new String(ROOT)) |
| 1092 | : (split_meta ? new String(HBASE96_META) : new String(META))); |
| 1093 | return shutdown(); |
| 1094 | } |
| 1095 | public String toString() { |
| 1096 | return "retry shutdown"; |
| 1097 | } |
| 1098 | } |