use of alma.ACSErrTypeCommon.wrappers.AcsJIllegalStateEventEx in project ACS by ACS-Community.
the class StateChangeListener method getCurrentState.
/**
* Reads the current state hierarchy.
* @return State hierarchy with outmost state first
* @throws AcsJIllegalStateEventEx if the state can't be read ; @TODO: use better fitting ex (don't want to create one now right before the release)
*/
public String[] getCurrentState() throws AcsJIllegalStateEventEx {
CompletionHolder ch = new CompletionHolder();
String[] statesHierarchy = statesProperty.get_sync(ch);
AcsJCompletion statesSyncCompletion = AcsJCompletion.fromCorbaCompletion(ch.value);
if (statesSyncCompletion.isError() || statesSyncCompletion.getType() != ACSErrTypeOK.value || statesSyncCompletion.getCode() != ACSErrOK.value || statesHierarchy == null) {
throw new AcsJIllegalStateEventEx("Failed to retrieve current subsystem state.");
}
return statesHierarchy;
}
use of alma.ACSErrTypeCommon.wrappers.AcsJIllegalStateEventEx in project ACS by ACS-Community.
the class AlmaSubsystemContext method illegalEvent.
//======================================================================
// util methods
//======================================================================
void illegalEvent(String stateName, String eventName) throws AcsJIllegalStateEventEx {
String msg = "illegal event '" + eventName + "' in state '" + stateName + "'.";
if (m_verbose) {
m_logger.warning(msg);
}
// for (Iterator iter = m_stateChangeListeners.iterator(); iter.hasNext();) {
// AcsStateChangeListener listener = (AcsStateChangeListener) iter.next();
// listener.illegalEventNotify(stateName, eventName);
// }
AcsJIllegalStateEventEx ex = new AcsJIllegalStateEventEx();
ex.setEvent(eventName);
ex.setState(stateName);
throw ex;
}
use of alma.ACSErrTypeCommon.wrappers.AcsJIllegalStateEventEx in project ACS by ACS-Community.
the class InMemorySubscriber method pushData.
/**
* InMemoryNcFake should call this method.
* See <code>NCSubscriber#push_structured_event(StructuredEvent</code>.
* @throws AcsJIllegalStateEventEx If this subscriber is disconnected.
*/
void pushData(Object eventData, EventDescription eventDesc) throws AcsJIllegalStateEventEx {
// dare to do in the real NCSubscriber, being afraid of performance risks. Seems fine though.
if (isDisconnected()) {
AcsJIllegalStateEventEx ex = new AcsJIllegalStateEventEx("Subscriber '" + clientName + "' is disconnected.");
ex.setState("disconnected");
// todo ex.set context... instead of above message
throw ex;
}
if (eventData == null) {
// see LOG_NC_EventReceive_FAIL
logger.warning("Received 'null' event.");
} else {
// If the state machine call is too slow then we could also work with "suspendBuffer != null" logic.
if (isSuspended()) {
synchronized (suspendBuffer) {
suspendBuffer.add(new CachedEvent(eventData, eventDesc));
}
} else {
// know that the event type cannot be handled
if (hasGenericReceiver() || receivers.containsKey(eventData.getClass())) {
// TODO: Log something as in LOG_NC_EventReceive_OK
processEventAsync(eventData, eventDesc);
}
}
}
}
use of alma.ACSErrTypeCommon.wrappers.AcsJIllegalStateEventEx in project ACS by ACS-Community.
the class InMemoryNcTest method testConcurrentUse.
/**
* Heavy-duty test to check for concurrency problems
* and to do basic verification of throughput performance (which is limited by having a single receiver).
* <p>
* We want to test also the asynchronous event processing in AcsEventSubscriberImplBase,
* but then must throttle the publishers so that the subscribers don't lose data.
* Still we want the publishers to fire fast enough so that the subscribers get stressed at times.
* This is achieved by letting the publishers fire batches of events at maximum speed,
* but then wait for the entire batch to be received by the registered receiver class.
* These pulses of events are calculated to at most fill up the subscriber queue completely,
* which means that we may get warnings about slow receivers ("More events came in from the NC than the receiver processed"),
* but still no data should be lost ("numEventsDiscarded=0").
*/
@Test
public void testConcurrentUse() throws Exception {
InMemoryNcFake nc = new InMemoryNcFake(services, "myTestChannel");
final int numEventsPerPublisher = 2000;
final int numPublishers = 5;
final int numEventsPublishedTotal = numEventsPerPublisher * numPublishers;
final int numActiveSubscribers = 5;
final int numInactiveSubscribers = 2;
final int numEventsToReceiveTotal = numEventsPublishedTotal * numActiveSubscribers;
final int eventBatchSize = Math.min(numEventsPerPublisher, AcsEventSubscriberImplBase.EVENT_QUEUE_CAPACITY / numPublishers);
assertThat("Current choice of test parameters leads to illegal batch size.", eventBatchSize, greaterThanOrEqualTo(1));
final int numEventsToReceivePerBatch = eventBatchSize * numPublishers * numActiveSubscribers;
logger.info("Will use " + numPublishers + " publishers to each publish " + numEventsPerPublisher + " events (in batches of " + eventBatchSize + " each synchronized with the receivers), and " + numActiveSubscribers + " subscribers for these events. In addition we have " + numInactiveSubscribers + " subscribers that should not receive these events.");
StopWatch sw = new StopWatch(logger);
// set up publishers (unlike above we do it before the subscribers, just to make sure that works as well)
List<InMemoryPublisher<TestEventType1>> publishers = new ArrayList<InMemoryPublisher<TestEventType1>>(numPublishers);
for (int i = 1; i <= numPublishers; i++) {
AcsEventPublisher<TestEventType1> pub = nc.createPublisher("myTestPublisher" + i, TestEventType1.class);
publishers.add((InMemoryPublisher) pub);
}
sw.logLapTime("create " + numPublishers + " publishers");
// set up subscribers
final SyncingEventCollector eventCollector = new SyncingEventCollector(numPublishers, numEventsToReceivePerBatch, numEventsToReceiveTotal);
TestEventReceiver1 sharedReceiver = new TestEventReceiver1(eventCollector);
List<AcsEventSubscriber<?>> subscribers = new ArrayList<AcsEventSubscriber<?>>(numActiveSubscribers);
for (int i = 1; i <= numActiveSubscribers; i++) {
AcsEventSubscriber<TestEventType1> sub = nc.createSubscriber("myTestSubscriber" + i, TestEventType1.class);
subscribers.add(sub);
sub.addSubscription(sharedReceiver);
sub.startReceivingEvents();
}
for (int i = 1; i <= numInactiveSubscribers; i++) {
if (i % 2 == 0) {
AcsEventSubscriber<TestEventType1> sub = nc.createSubscriber("myInactiveTestSubscriber" + i, TestEventType1.class);
subscribers.add(sub);
sub.addSubscription(sharedReceiver);
// do not call sub.startReceivingEvents() for this inactive subscriber
} else {
AcsEventSubscriber<TestEventType2> sub = nc.createSubscriber("myTestSubscriber" + i, TestEventType2.class);
subscribers.add(sub);
sub.startReceivingEvents();
}
}
sw.logLapTime("create " + (numActiveSubscribers + numInactiveSubscribers) + " subscribers");
// Publish and receive "event1" as specified above
final TestEventType1 event1 = new TestEventType1();
final List<Throwable> asyncThrowables = Collections.synchronizedList(new ArrayList<Throwable>());
final CountDownLatch synchOnPublishers = new CountDownLatch(numPublishers);
class PublisherRunnable implements Runnable {
private final InMemoryPublisher<TestEventType1> publisher;
PublisherRunnable(InMemoryPublisher<TestEventType1> publisher) {
this.publisher = publisher;
}
@Override
public void run() {
for (int i = 1; i <= numEventsPerPublisher; i++) {
try {
publisher.publishEvent(event1);
if (i % eventBatchSize == 0) {
awaitEventReception();
}
} catch (Exception ex) {
asyncThrowables.add(ex);
}
}
// test getEventCount()
if (publisher.getEventCount() != numEventsPerPublisher) {
asyncThrowables.add(new Exception("Published only " + publisher.getEventCount() + " events when " + numEventsPerPublisher + " were expected."));
}
try {
publisher.disconnect();
} catch (AcsJIllegalStateEventEx ex) {
asyncThrowables.add(ex);
}
// the last batch may be smaller than eventBatchSize, so that we need to sync on their reception with this extra call
awaitEventReception();
synchOnPublishers.countDown();
}
private void awaitEventReception() {
try {
// StopWatch swWait = new StopWatch(logger);
eventCollector.awaitEventBatchReception();
// logger.fine("Publisher in thread " + Thread.currentThread().getName() + " returned from awaitEventBatchReception() in " + swWait.getLapTimeMillis() + " ms.");
} catch (Exception ex) {
asyncThrowables.add(ex);
}
}
}
// let each publisher fire its events from a separate thread
for (InMemoryPublisher<TestEventType1> publisher : publishers) {
services.getThreadFactory().newThread(new PublisherRunnable(publisher)).start();
}
// wait for publishers to fire all events (which includes already their waiting for event reception)
assertThat(synchOnPublishers.await(1, TimeUnit.MINUTES), is(true));
// verify results
assertThat(asyncThrowables, is(empty()));
assertThat(eventCollector.getNumEventsReceivedTotal(), equalTo((long) numEventsToReceiveTotal));
sw.logLapTime("publish " + numEventsPublishedTotal + " and receive " + numEventsToReceiveTotal + " events");
}
use of alma.ACSErrTypeCommon.wrappers.AcsJIllegalStateEventEx in project ACS by ACS-Community.
the class AcsScxmlEngine method fireSignalWithErrorFeedback.
/**
* Synchronous event handling as in {@link #fireSignal(Enum)},
* but possibly with exceptions for the following cases:
* <ul>
* <li> The <code>signal</code> gets checked if it can be handled by the current state(s);
* an <code>AcsJIllegalStateEventEx</code> exception is thrown if not.
* <li> If an executed action throws a AcsJStateMachineActionEx exception, that exception gets thrown here.
* Depending on the concrete state machine, an additional response to the error may be
* that the SM goes to an error state, due to an internal event triggered by the action.
* <li> <code>ModelException</code>, as thrown by {@link SCXMLExecutor#triggerEvent}, unlikely
* with our static use of the SCXML engine.
* </ul>
* @param signal
* @return True - if all the states are final and there are not events
* pending from the last step. False - otherwise.
* @throws AcsJIllegalStateEventEx
* @throws AcsJStateMachineActionEx
* @throws ModelException
*/
public synchronized boolean fireSignalWithErrorFeedback(S signal) throws AcsJIllegalStateEventEx, AcsJStateMachineActionEx, ModelException {
// check if signal is OK, throw exception if not.
Set<S> applicableSignals = getApplicableSignals();
if (!applicableSignals.contains(signal)) {
AcsJIllegalStateEventEx ex = new AcsJIllegalStateEventEx();
ex.setEvent(signal.name());
ex.setState(getCurrentState());
throw ex;
}
// Register error callback with action dispatcher.
// This is only thread safe because this method is synchronized and we
// execute only one event at a time.
MyActionExceptionHandler handler = new MyActionExceptionHandler();
actionDispatcher.setActionExceptionHandler(handler);
try {
TriggerEvent evnt = new TriggerEvent(signal.name(), TriggerEvent.SIGNAL_EVENT, null);
exec.triggerEvent(evnt);
if (handler.theEx != null) {
throw handler.theEx;
} else {
// or all actions executed without exception.
return exec.getCurrentStatus().isFinal();
}
} finally {
actionDispatcher.setActionExceptionHandler(null);
}
}
Aggregations