@Override public synchronized void failed(Exception e) { if(prepared) { final ModelController.OperationTransaction transaction = activeTx; if(transaction != null) { transaction.rollback(); txCompletedLatch.countDown(); } } else if (responseChannel != null) { rollbackOnPrepare = true; // Failed in a step before prepare, send error response final String message = e.getMessage() != null ? e.getMessage() : "failure before rollback " + e.getClass().getName(); final ModelNode response = new ModelNode(); response.get(OUTCOME).set(FAILED); response.get(FAILURE_DESCRIPTION).set(message); try { sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_FAILED, response); } catch (IOException ignored) { ProtocolLogger.ROOT_LOGGER.debugf(ignored, "failed to process message"); } } }
@Override public synchronized void failed(Exception e) { if(prepared) { final ModelController.OperationTransaction transaction = activeTx; activeTx = null; if(transaction != null) { try { transaction.rollback(); } finally { txCompletedLatch.countDown(); } } } else if (responseChannel != null) { rollbackOnPrepare = true; // Failed in a step before prepare, send error response final String message = e.getMessage() != null ? e.getMessage() : "failure before rollback " + e.getClass().getName(); final ModelNode response = new ModelNode(); response.get(OUTCOME).set(FAILED); response.get(FAILURE_DESCRIPTION).set(message); ControllerLogger.MGMT_OP_LOGGER.tracef("sending pre-prepare failed response for %d --- interrupted: %s", getOperationId(), (Object) Thread.currentThread().isInterrupted()); try { sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_FAILED, response); responseChannel = null; } catch (IOException ignored) { ControllerLogger.MGMT_OP_LOGGER.failedSendingFailedResponse(ignored, response, getOperationId()); } } }
@Override public synchronized void failed(Exception e) { if(prepared) { final ModelController.OperationTransaction transaction = activeTx; activeTx = null; if(transaction != null) { try { transaction.rollback(); } finally { txCompletedLatch.countDown(); } } } else if (responseChannel != null) { rollbackOnPrepare = true; // Failed in a step before prepare, send error response final String message = e.getMessage() != null ? e.getMessage() : "failure before rollback " + e.getClass().getName(); final ModelNode response = new ModelNode(); response.get(OUTCOME).set(FAILED); response.get(FAILURE_DESCRIPTION).set(message); ControllerLogger.MGMT_OP_LOGGER.tracef("sending pre-prepare failed response for %d --- interrupted: %s", getOperationId(), (Object) Thread.currentThread().isInterrupted()); try { sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_FAILED, response); responseChannel = null; } catch (IOException ignored) { ControllerLogger.MGMT_OP_LOGGER.failedSendingFailedResponse(ignored, response, getOperationId()); } } }
synchronized void completed(final ModelNode response) { assert prepared; assert responseChannel != null; try { // 4) operation-completed (done) sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_COMPLETED, response); } catch (IOException e) { ProtocolLogger.ROOT_LOGGER.debugf(e, "failed to process message"); } finally { getResultHandler().done(null); } }
synchronized void completed(final ModelNode response) { assert prepared; assert responseChannel != null; try { // 4) operation-completed (done) sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_COMPLETED, response); } catch (IOException e) { ProtocolLogger.ROOT_LOGGER.debugf(e, "failed to process message"); } finally { getResultHandler().done(null); } }
synchronized void prepare(final ModelController.OperationTransaction tx, final ModelNode result) { if(rollbackOnPrepare) { try { tx.rollback(); } finally { txCompletedLatch.countDown(); } // TODO send response ? } else { assert !prepared; assert activeTx == null; assert responseChannel != null; try { // 2) send the operation-prepared notification (just clear response info) sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_PREPARED, result); activeTx = tx; prepared = true; } catch (IOException e) { getResultHandler().failed(e); } finally { responseChannel = null; } } }
synchronized void prepare(final ModelController.OperationTransaction tx, final ModelNode result) { if(rollbackOnPrepare) { try { tx.rollback(); } finally { txCompletedLatch.countDown(); } // TODO send response ? } else { assert !prepared; assert activeTx == null; assert responseChannel != null; try { // 2) send the operation-prepared notification (just clear response info) sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_PREPARED, result); activeTx = tx; prepared = true; } catch (IOException e) { getResultHandler().failed(e); } finally { responseChannel = null; } } }
/** Signal from ProxyOperationTransactionControl that the operation is prepared */ synchronized void prepare(final ModelController.OperationTransaction tx, final ModelNode result) { assert !prepared; prepared = true; if(rollbackOnPrepare) { try { tx.rollback(); ControllerLogger.MGMT_OP_LOGGER.tracef("rolled back on prepare for %d --- interrupted: %s", getOperationId(), (Object) Thread.currentThread().isInterrupted()); } finally { txCompletedLatch.countDown(); } // no response to remote side here; the response will go out when this thread executing // the now rolled-back op returns in ExecuteRequestHandler.doExecute } else { assert activeTx == null; assert responseChannel != null; activeTx = tx; ControllerLogger.MGMT_OP_LOGGER.tracef("sending prepared response for %d --- interrupted: %s", getOperationId(), (Object) Thread.currentThread().isInterrupted()); try { sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_PREPARED, result); responseChannel = null; // we've now sent a response to the original request, so we can't use this one further } catch (IOException e) { getResultHandler().failed(e); // this will eventually call back into failed(e) above and roll back the tx } } }
/** Signal from ProxyOperationTransactionControl that the operation is prepared */ synchronized void prepare(final ModelController.OperationTransaction tx, final ModelNode result) { assert !prepared; prepared = true; if(rollbackOnPrepare) { try { tx.rollback(); ControllerLogger.MGMT_OP_LOGGER.tracef("rolled back on prepare for %d --- interrupted: %s", getOperationId(), (Object) Thread.currentThread().isInterrupted()); } finally { txCompletedLatch.countDown(); } // no response to remote side here; the response will go out when this thread executing // the now rolled-back op returns in ExecuteRequestHandler.doExecute } else { assert activeTx == null; assert responseChannel != null; activeTx = tx; ControllerLogger.MGMT_OP_LOGGER.tracef("sending prepared response for %d --- interrupted: %s", getOperationId(), (Object) Thread.currentThread().isInterrupted()); try { sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_PREPARED, result); responseChannel = null; // we've now sent a response to the original request, so we can't use this one further } catch (IOException e) { getResultHandler().failed(e); // this will eventually call back into failed(e) above and roll back the tx } } }
synchronized void failed(final ModelNode response) { if(prepared) { // in case commit or rollback throws an exception, to conform with the API we still send a operation-completed message completed(response); } else { assert responseChannel != null; try { // 2) send the operation-failed message (done) sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_FAILED, response); } catch (IOException e) { ProtocolLogger.ROOT_LOGGER.debugf(e, "failed to process message"); } finally { getResultHandler().done(null); } } }
synchronized void failed(final ModelNode response) { if(prepared) { // in case commit or rollback throws an exception, to conform with the API we still send an operation-completed message completed(response); } else { assert responseChannel != null; try { // 2) send the operation-failed message (done) sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_FAILED, response); } catch (IOException e) { ProtocolLogger.ROOT_LOGGER.debugf(e, "failed to process message"); } finally { getResultHandler().done(null); } } }
/** * Handles sending a failure response to the remote client. If operation has already been prepared * this method simply delegates to {@link #completed(OperationResponse)}. * @param response the failure response ModelNode to send */ synchronized void failed(final ModelNode response) { if(prepared) { // in case commit or rollback throws an exception, to conform with the API we still send an operation-completed message completed(OperationResponse.Factory.createSimple(response)); } else { // Failure before prepare. So send a response to the original request assert responseChannel != null; ControllerLogger.MGMT_OP_LOGGER.tracef("sending pre-prepare failed response for %d --- interrupted: %s", getOperationId(), (Object) Thread.currentThread().isInterrupted()); try { sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_FAILED, response); responseChannel = null; // we've now sent a response to the original request, so we can't use this one further } catch (IOException e) { ControllerLogger.MGMT_OP_LOGGER.failedSendingFailedResponse(e, response, getOperationId()); } finally { getResultHandler().done(null); } } }
/** * Handles sending a failure response to the remote client. If operation has already been prepared * this method simply delegates to {@link #completed(OperationResponse)}. * @param response the failure response ModelNode to send */ synchronized void failed(final ModelNode response) { if(prepared) { // in case commit or rollback throws an exception, to conform with the API we still send an operation-completed message completed(OperationResponse.Factory.createSimple(response)); } else { // Failure before prepare. So send a response to the original request assert responseChannel != null; ControllerLogger.MGMT_OP_LOGGER.tracef("sending pre-prepare failed response for %d --- interrupted: %s", getOperationId(), (Object) Thread.currentThread().isInterrupted()); try { sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_FAILED, response); responseChannel = null; // we've now sent a response to the original request, so we can't use this one further } catch (IOException e) { ControllerLogger.MGMT_OP_LOGGER.failedSendingFailedResponse(e, response, getOperationId()); } finally { getResultHandler().done(null); } } }
/** * Sends the final response to the remote client after the prepare phase has been executed. * This should be called whether the outcome was successful or not. */ synchronized void completed(final OperationResponse response) { assert prepared; if (responseChannel != null) { // Normal case, where a COMPLETE_TX_REQUEST came in after the prepare() call and // established a new responseChannel so the client can correlate the response ControllerLogger.MGMT_OP_LOGGER.tracef("sending completed response %s for %d --- interrupted: %s", response.getResponseNode(), getOperationId(), Thread.currentThread().isInterrupted()); streamSupport.registerStreams(operation.getOperationId(), response.getInputStreams()); try { sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_COMPLETED, response.getResponseNode()); responseChannel = null; // we've now sent a response to the COMPLETE_TX_REQUEST, so we can't use this one further } catch (IOException e) { ControllerLogger.MGMT_OP_LOGGER.failedSendingCompletedResponse(e, response.getResponseNode(), getOperationId()); } finally { getResultHandler().done(null); } } else { // We were cancelled or somehow failed after sending our prepare() message but before we got a COMPLETE_TX_REQUEST. // The client will not be able to deal with any response until it sends a COMPLETE_TX_REQUEST // (which is why we null out responseChannel in prepare()). So, just cache this response // so we can send it in completeTx when the COMPLETE_TX_REQUEST comes in. assert postPrepareRaceResponse == null; // else we got called twice locally! ControllerLogger.MGMT_OP_LOGGER.tracef("received a post-prepare response for %d but no " + "COMPLETE_TX_REQUEST has been received; caching the response", getOperationId()); postPrepareRaceResponse = response; } }
/** * Sends the final response to the remote client after the prepare phase has been executed. * This should be called whether the outcome was successful or not. */ synchronized void completed(final OperationResponse response) { assert prepared; if (responseChannel != null) { // Normal case, where a COMPLETE_TX_REQUEST came in after the prepare() call and // established a new responseChannel so the client can correlate the response ControllerLogger.MGMT_OP_LOGGER.tracef("sending completed response %s for %d --- interrupted: %s", response.getResponseNode(), getOperationId(), Thread.currentThread().isInterrupted()); streamSupport.registerStreams(operation.getOperationId(), response.getInputStreams()); try { sendResponse(responseChannel, ModelControllerProtocol.PARAM_OPERATION_COMPLETED, response.getResponseNode()); responseChannel = null; // we've now sent a response to the COMPLETE_TX_REQUEST, so we can't use this one further } catch (IOException e) { ControllerLogger.MGMT_OP_LOGGER.failedSendingCompletedResponse(e, response.getResponseNode(), getOperationId()); } finally { getResultHandler().done(null); } } else { // We were cancelled or somehow failed after sending our prepare() message but before we got a COMPLETE_TX_REQUEST. // The client will not be able to deal with any response until it sends a COMPLETE_TX_REQUEST // (which is why we null out responseChannel in prepare()). So, just cache this response // so we can send it in completeTx when the COMPLETE_TX_REQUEST comes in. assert postPrepareRaceResponse == null; // else we got called twice locally! ControllerLogger.MGMT_OP_LOGGER.tracef("received a post-prepare response for %d but no " + "COMPLETE_TX_REQUEST has been received; caching the response", getOperationId()); postPrepareRaceResponse = response; } }