Flushes to HBase any buffered client-side write operation. @return A Deferred, whose callback chain will be invoked when everything that was buffered at the time of the call has been flushed. Note that this doesn't guarantee that ALL outstanding RPCs have completed. This does
()
| 799 | * it does really is it sends any buffered RPCs to HBase. |
| 800 | */ |
| 801 | public Deferred<Object> flush() { |
| 802 | { |
| 803 | // If some RPCs are waiting for -ROOT- to be discovered, we too must wait |
| 804 | // because some of those RPCs could be edits that we must wait on. |
| 805 | final Deferred<Object> d = zkclient.getDeferredRootIfBeingLookedUp(); |
| 806 | if (d != null) { |
| 807 | LOG.debug("Flush needs to wait on {} to come back", |
| 808 | has_root ? (split_meta ? new String(HBASE98_ROOT_REGION) : new String(ROOT)) |
| 809 | : (split_meta ? new String(HBASE96_META) : new String(META))); |
| 810 | final class RetryFlush implements Callback<Object, Object> { |
| 811 | public Object call(final Object arg) { |
| 812 | LOG.debug("Flush retrying after {} came back", |
| 813 | has_root ? (split_meta ? new String(HBASE98_ROOT_REGION) : new String(ROOT)) |
| 814 | : (split_meta ? new String(HBASE96_META) : new String(META))); |
| 815 | return flush(); |
| 816 | } |
| 817 | public String toString() { |
| 818 | return "retry flush"; |
| 819 | } |
| 820 | } |
| 821 | return d.addBoth(new RetryFlush()); |
| 822 | } |
| 823 | } |
| 824 | |
| 825 | num_flushes.increment(); |
| 826 | final boolean need_sync; |
| 827 | { |
| 828 | final LoadingCache<BufferedIncrement, BufferedIncrement.Amount> buf = |
| 829 | increment_buffer; // Single volatile-read. |
| 830 | if (buf != null && !buf.asMap().isEmpty()) { |
| 831 | flushBufferedIncrements(buf); |
| 832 | need_sync = true; |
| 833 | |
| 834 | } else { |
| 835 | final LoadingCache<BufferedMultiColumnIncrement, BufferedMultiColumnIncrement.Amounts> multiColumnBuf = |
| 836 | multi_column_increment_buffer; // Single volatile-read. |
| 837 | if (multiColumnBuf != null && !multiColumnBuf.asMap().isEmpty()) { |
| 838 | flushBufferedMultiColumnIncrements(multiColumnBuf); |
| 839 | need_sync = true; |
| 840 | |
| 841 | } else { |
| 842 | need_sync = false; |
| 843 | } |
| 844 | } |
| 845 | } |
| 846 | final ArrayList<Deferred<Object>> d = |
| 847 | new ArrayList<Deferred<Object>>(client2regions.size() |
| 848 | + got_nsre.size() * 8); |
| 849 | // Bear in mind that we're traversing a ConcurrentHashMap, so we may get |
| 850 | // clients that have been removed from the map since we started iterating. |
| 851 | for (final RegionClient client : client2regions.keySet()) { |
| 852 | d.add(need_sync ? client.sync() : client.flush()); |
| 853 | } |
| 854 | for (final ArrayList<HBaseRpc> nsred : got_nsre.values()) { |
| 855 | synchronized (nsred) { |
| 856 | for (final HBaseRpc rpc : nsred) { |
| 857 | if (rpc instanceof HBaseRpc.IsEdit) { |
| 858 | d.add(rpc.getDeferred()); |