@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); }