@Override public void stop(CoprocessorEnvironment env) throws IOException { RegionCoprocessorEnvironment renv = (RegionCoprocessorEnvironment) env; this.cache = null; ((ZKDataHolder) renv.getSharedData().get(ZKKEY)).release(); }
@Override public void start(CoprocessorEnvironment e) { sharedData = ((RegionCoprocessorEnvironment)e).getSharedData(); sharedData.putIfAbsent("test2", new Object()); }
@Override public void start(CoprocessorEnvironment e) { sharedData = ((RegionCoprocessorEnvironment)e).getSharedData(); // using new String here, so that there will be new object on each invocation sharedData.putIfAbsent("test1", new Object()); startCalled = true; }
@Override public void start(CoprocessorEnvironment env) throws IOException { RegionCoprocessorEnvironment renv = (RegionCoprocessorEnvironment) env; try { this.cache = ((ZKDataHolder) renv.getSharedData().computeIfAbsent(ZKKEY, k -> { String ensemble = renv.getConfiguration().get(ZK_ENSEMBLE_KEY); int sessionTimeout = renv.getConfiguration().getInt(ZK_SESSION_TIMEOUT_KEY, ZK_SESSION_TIMEOUT_DEFAULT); return new ZKDataHolder(ensemble, sessionTimeout); })).acquire(); } catch (Exception e) { throw new IOException(e); } }
@Override public ConcurrentMap<String, Object> getSharedData() { return delegate.getSharedData(); }
@Override public void stop(CoprocessorEnvironment e) throws IOException { if (e instanceof RegionCoprocessorEnvironment) { RegionCoprocessorEnvironment env = (RegionCoprocessorEnvironment) e; AtomicInteger id = (AtomicInteger) env.getSharedData().get(KEY_ID); LOG.info("Final ID issued: " + regionName + "-" + id.get()); // co SequentialIdGeneratorObserver-4-Log Log the final number generated by this coprocessor. } else { LOG.warn("Received wrong context."); } }
@Override public void prePut(ObserverContext<RegionCoprocessorEnvironment> e, Put put, WALEdit edit, Durability durability) throws IOException { RegionCoprocessorEnvironment env = e.getEnvironment(); AtomicInteger id = (AtomicInteger) env.getSharedData().get(KEY_ID); put.addColumn(family, qualifier, Bytes.toBytes(regionName + "-" + // co SequentialIdGeneratorObserver-5-SetId Set the shared ID for this instance of put. id.incrementAndGet())); try { Thread.sleep(rnd.nextInt(delay)); // co SequentialIdGeneratorObserver-6-Sleep Sleep for 0 to "delay" milliseconds. } catch (InterruptedException e1) { e1.printStackTrace(); } } // ^^ SequentialIdGeneratorObserver
/** * Get an executor for the given name, based on the passed {@link Configuration}. If a thread pool * already exists with that name, it will be returned. * @param builder * @param env * @return a {@link ThreadPoolExecutor} for the given name. Thread pool that only shuts down when * there are no more explicit references to it. You do not need to shutdown the threadpool * on your own - it is managed for you. When you are done, you merely need to release your * reference. If you do attempt to shutdown the pool, you should be careful to call * {@link ThreadPoolExecutor#shutdown()} XOR {@link ThreadPoolExecutor#shutdownNow()} - extra calls to either can lead to * early shutdown of the pool. */ public static synchronized ThreadPoolExecutor getExecutor(ThreadPoolBuilder builder, RegionCoprocessorEnvironment env) { return getExecutor(builder, env.getSharedData()); }
/** * Get an executor for the given name, based on the passed {@link Configuration}. If a thread pool * already exists with that name, it will be returned. * @param builder * @param env * @return a {@link ThreadPoolExecutor} for the given name. Thread pool that only shuts down when * there are no more explicit references to it. You do not need to shutdown the threadpool * on your own - it is managed for you. When you are done, you merely need to release your * reference. If you do attempt to shutdown the pool, you should be careful to call * {@link ThreadPoolExecutor#shutdown()} XOR {@link ThreadPoolExecutor#shutdownNow()} - extra calls to either can lead to * early shutdown of the pool. */ public static synchronized ThreadPoolExecutor getExecutor(ThreadPoolBuilder builder, RegionCoprocessorEnvironment env) { return getExecutor(builder, env.getSharedData()); }
@Override public void start(CoprocessorEnvironment e) throws IOException { if (e instanceof RegionCoprocessorEnvironment) { RegionCoprocessorEnvironment env = (RegionCoprocessorEnvironment) e; Configuration conf = env.getConfiguration(); // co SequentialIdGeneratorObserver-1-Conf Get environment and configuration instances. this.regionName = env.getRegionInfo().getEncodedName(); String family = conf.get("com.larsgeorge.copro.seqidgen.family", "cf1"); this.family = Bytes.toBytes(family); String qualifier = conf.get("com.larsgeorge.copro.seqidgen.qualifier", // co SequentialIdGeneratorObserver-2-Settings Retrieve the settings passed into the configuration. "GENID"); this.qualifier = Bytes.toBytes(qualifier); int startId = conf.getInt("com.larsgeorge.copro.seqidgen.startId", 1); this.delay = conf.getInt("com.larsgeorge.copro.seqidgen.delay", 100); env.getSharedData().putIfAbsent(KEY_ID, new AtomicInteger(startId)); // co SequentialIdGeneratorObserver-3-Gen Set up generator if this has not been done yet on this region server. } else { LOG.warn("Received wrong context."); } }
@Test public void testCorrectlyCleansUpResources() throws Exception{ ExecutorService exec = Executors.newFixedThreadPool(1); RegionCoprocessorEnvironment e =Mockito.mock(RegionCoprocessorEnvironment.class); Configuration conf =new Configuration(); Mockito.when(e.getConfiguration()).thenReturn(conf); Mockito.when(e.getSharedData()).thenReturn(new ConcurrentHashMap<String,Object>()); FakeTableFactory factory = new FakeTableFactory( Collections.<ImmutableBytesPtr, Table> emptyMap()); TrackingParallelWriterIndexCommitter writer = new TrackingParallelWriterIndexCommitter(VersionInfo.getVersion()); Stoppable mockStop = Mockito.mock(Stoppable.class); // create a simple writer writer.setup(factory, exec, mockStop,e); // stop the writer writer.stop(this.test.getTableNameString() + " finished"); assertTrue("Factory didn't get shutdown after writer#stop!", factory.shutdown); assertTrue("ExectorService isn't terminated after writer#stop!", exec.isShutdown()); Mockito.verifyZeroInteractions(mockStop); }
@Test public void testCorrectlyCleansUpResources() throws Exception{ ExecutorService exec = Executors.newFixedThreadPool(1); FakeTableFactory factory = new FakeTableFactory( Collections.<ImmutableBytesPtr, Table> emptyMap()); TrackingParallelWriterIndexCommitter writer = new TrackingParallelWriterIndexCommitter(VersionInfo.getVersion()); Stoppable mockStop = Mockito.mock(Stoppable.class); RegionCoprocessorEnvironment e =Mockito.mock(RegionCoprocessorEnvironment.class); Configuration conf =new Configuration(); Mockito.when(e.getConfiguration()).thenReturn(conf); Mockito.when(e.getSharedData()).thenReturn(new ConcurrentHashMap<String,Object>()); // create a simple writer writer.setup(factory, exec, mockStop, e); // stop the writer writer.stop(this.test.getTableNameString() + " finished"); assertTrue("Factory didn't get shutdown after writer#stop!", factory.shutdown); assertTrue("ExectorService isn't terminated after writer#stop!", exec.isShutdown()); Mockito.verifyZeroInteractions(mockStop); }
Configuration conf =new Configuration(); Mockito.when(e.getConfiguration()).thenReturn(conf); Mockito.when(e.getSharedData()).thenReturn(new ConcurrentHashMap<String,Object>()); Region mockRegion = Mockito.mock(Region.class); Mockito.when(e.getRegion()).thenReturn(mockRegion);
Configuration conf =new Configuration(); Mockito.when(e.getConfiguration()).thenReturn(conf); Mockito.when(e.getSharedData()).thenReturn(new ConcurrentHashMap<String,Object>()); Region mockRegion = Mockito.mock(Region.class); Mockito.when(e.getRegion()).thenReturn(mockRegion);
Configuration conf =new Configuration(); Mockito.when(e.getConfiguration()).thenReturn(conf); Mockito.when(e.getSharedData()).thenReturn(new ConcurrentHashMap<String,Object>()); Region mockRegion = Mockito.mock(Region.class); Mockito.when(e.getRegion()).thenReturn(mockRegion);
Configuration conf =new Configuration(); Mockito.when(e.getConfiguration()).thenReturn(conf); Mockito.when(e.getSharedData()).thenReturn(new ConcurrentHashMap<String,Object>()); Region mockRegion = Mockito.mock(Region.class); Mockito.when(e.getRegion()).thenReturn(mockRegion);
@Override public void stop(CoprocessorEnvironment env) throws IOException { RegionCoprocessorEnvironment renv = (RegionCoprocessorEnvironment) env; this.cache = null; ((ZKDataHolder) renv.getSharedData().get(ZKKEY)).release(); }
@Override public void start(CoprocessorEnvironment e) { sharedData = ((RegionCoprocessorEnvironment)e).getSharedData(); // using new String here, so that there will be new object on each invocation sharedData.putIfAbsent("test1", new Object()); startCalled = true; }
@Override public void start(CoprocessorEnvironment e) { sharedData = ((RegionCoprocessorEnvironment)e).getSharedData(); sharedData.putIfAbsent("test2", new Object()); }
@Override public void start(CoprocessorEnvironment e) throws IOException { RegionCoprocessorEnvironment re = (RegionCoprocessorEnvironment) e; if (!re.getSharedData().containsKey(zkkey)) { // there is a short race here // in the worst case we create a watcher that will be notified once re.getSharedData().putIfAbsent( zkkey, new ZKWatcher(re.getRegionServerServices().getZooKeeper() .getRecoverableZooKeeper().getZooKeeper())); } }