@Override public void run(ClientResponseImpl parameter) { if (debug.get()) LOG.debug( String.format( "Got ClientResponse callback for txn #%d! Sending back to %s", parameter.getTransactionId(), HStoreThreadManager.formatSiteName(this.destSiteId))); FastSerializer fs = new FastSerializer(); try { parameter.writeExternal(fs); } catch (IOException ex) { throw new RuntimeException(ex); } ByteString bs = ByteString.copyFrom(fs.getBuffer()); TransactionRedirectResponse response = TransactionRedirectResponse.newBuilder() .setSenderSite(this.sourceSiteId) .setOutput(bs) .build(); this.orig_callback.run(response); if (debug.get()) LOG.debug( String.format( "Sent back ClientResponse for txn #%d to %s [bytes=%d]", parameter.getTransactionId(), HStoreThreadManager.formatSiteName(this.destSiteId))); // IMPORTANT: Since we're the only one that knows that we're finished (and actually even // cares), we need to be polite and clean-up after ourselves... try { this.finish(); hstore_site.getObjectPools().CALLBACKS_TXN_REDIRECT_RESPONSE.returnObject(this); } catch (Exception ex) { throw new RuntimeException("Funky failure", ex); } }
/** * Send a copy of a single message request to the partitions given as input If a partition is * managed by the local HStoreSite, then we will invoke the sendLocal() method. If it is on a * remote HStoreSite, then we will invoke sendRemote(). * * @param ts * @param request * @param callback * @param partitions */ public void sendMessages( LocalTransaction ts, T request, RpcCallback<U> callback, PartitionSet partitions) { // If this flag is true, then we'll invoke the local method // We want to do this *after* we send out all the messages to the remote sites // so that we don't have to wait as long for the responses to come back over the network boolean send_local = false; boolean site_sent[] = new boolean[this.num_sites]; if (debug.val) LOG.debug( String.format( "Sending %s to %d partitions for %s", request.getClass().getSimpleName(), partitions.size(), ts)); for (int partition : partitions.values()) { int dest_site_id = hstore_site.getCatalogContext().getSiteIdForPartitionId(partition); // Skip this HStoreSite if we're already sent it a message if (site_sent[dest_site_id]) continue; if (trace.val) LOG.trace( String.format( "Sending %s message to %s for %s", request.getClass().getSimpleName(), HStoreThreadManager.formatSiteName(dest_site_id), ts)); // Local Partition if (this.local_site_id == dest_site_id) { send_local = true; } // Remote Partition else { HStoreService channel = coordinator.getChannel(dest_site_id); assert (channel != null) : "Invalid partition id '" + partition + "'"; ProtoRpcController controller = this.getProtoRpcController(ts, dest_site_id); assert (controller != null) : "Invalid " + request.getClass().getSimpleName() + " ProtoRpcController for site #" + dest_site_id; this.sendRemote(channel, controller, request, callback); } site_sent[dest_site_id] = true; } // FOR // Optimization: We'll invoke sendLocal() after we have sent out // all of the messages to remote sites if (send_local) this.sendLocal(ts.getTransactionId(), request, partitions, callback); }
@Override public synchronized void run() { final boolean d = debug.get(); final boolean t = trace.get(); if (this.first) { Thread self = Thread.currentThread(); self.setName( HStoreThreadManager.getThreadName(hstore_site, HStoreConstants.THREAD_NAME_HELPER)); hstore_site.getThreadManager().registerProcessingThread(); this.first = false; } if (t) LOG.trace("New invocation of the ExecutionSiteHelper. Let's clean-up some txns!"); this.hstore_site.updateLogging(); for (PartitionExecutor es : this.executors) { // if (t) LOG.trace(String.format("Partition %d has %d finished transactions", // es.partitionId, es.finished_txn_states.size())); // long to_remove = System.currentTimeMillis() - this.txn_expire; int cleaned = 0; // while (es.finished_txn_states.isEmpty() == false && (this.txn_per_round < 0 || // cleaned < this.txn_per_round)) { // AbstractTransaction ts = es.finished_txn_states.peek(); // if (ts.getEE_FinishedTimestamp() < to_remove) { //// if (traceLOG.info(String.format("Want to clean txn #%d [done=%s, // type=%s]", ts.getTransactionId(), ts.getHStoreSiteDone(), ts.getClass().getSimpleName())); // if (ts.isHStoreSite_Finished() == false) break; // // if (t) LOG.trace("Cleaning txn #" + ts.getTransactionId()); // // // es.cleanupTransaction(ts); // es.finished_txn_states.remove(); // cleaned++; // this.total_cleaned++; // } else break; // } // WHILE if (d && cleaned > 0) LOG.debug( String.format( "Cleaned %d TransactionStates at partition %d [total=%d]", cleaned, es.getPartitionId(), this.total_cleaned)); // Only call tick here! // es.tick(); } // FOR // Recompute MarkovGraphs if we have them MarkovGraph m = null; while ((m = this.markovs_to_recompute.poll()) != null) { if (d) LOG.debug( String.format( "Recomputing MarkovGraph for %s [recomputed=%d, hashCode=%d]", m.getProcedure().getName(), m.getRecomputeCount(), m.hashCode())); m.calculateProbabilities(); if (d && m.isValid() == false) { LOG.error("Invalid MarkovGraph after recomputing! Crashing..."); Exception error = new Exception( String.format( "Invalid %s MarkovGraph for after recomputing", m.getProcedure().getName())); this.hstore_site.getCoordinator().shutdownCluster(error); } } // WHILE }