001: /*
002: * <copyright>
003: *
004: * Copyright 2001-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.core.mobility.arch;
028:
029: import org.cougaar.util.GenericStateModel;
030:
031: /**
032: * Handle a failed move response from the target node.
033: */
034: public class NackHandler extends AbstractHandler {
035:
036: private GenericStateModel model;
037: private Throwable throwable;
038:
039: public NackHandler(MobilitySupport support,
040: GenericStateModel model, Throwable throwable) {
041: super (support);
042: this .model = model;
043: this .throwable = throwable;
044: }
045:
046: public void run() {
047: nack();
048: }
049:
050: private void nack() {
051:
052: // FIXME race condition between move & agent-add!
053:
054: if (log.isInfoEnabled()) {
055: log.info("Handling failed move of agent " + id + " from "
056: + nodeId + " to node "
057: + moveTicket.getDestinationNode());
058: }
059:
060: // agent is suspended -- let's resume it.
061:
062: try {
063: resumeAgent();
064: } catch (Exception e) {
065: // did we lose an agent?!
066: // should we kill it and reclaim the memory?
067: if (log.isErrorEnabled()) {
068: log.error("Unable to resume agent " + id, e);
069: }
070: return;
071: }
072:
073: try {
074: onFailure(throwable);
075: } catch (Exception e) {
076: // too late now -- the dispatch failed.
077: if (log.isErrorEnabled()) {
078: log.error("Notification for \"onFailure\" of agent "
079: + id + " failed (ignored)", e);
080: }
081: return;
082: }
083:
084: if (log.isInfoEnabled()) {
085: log.info("Completed failed move of agent " + id);
086: }
087:
088: }
089:
090: private void resumeAgent() {
091: if (log.isInfoEnabled()) {
092: log.info("Resume agent " + id);
093: }
094: model.resume();
095: if (log.isInfoEnabled()) {
096: log.info("Resumed agent " + id);
097: }
098: }
099:
100: public String toString() {
101: return "Move (nack) of agent " + id;
102: }
103: }
|