/* * Copyright (C) 2012 Red Hat, Inc. and/or its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jboss.errai.bus.server; import com.google.inject.Inject; import com.google.inject.Singleton; import org.jboss.errai.bus.client.api.messaging.Message; import org.jboss.errai.bus.client.api.messaging.RequestDispatcher; import org.jboss.errai.common.client.protocols.MessageParts; import org.jboss.errai.bus.server.service.ErraiService; /** * The <tt>AsyncDispatcher</tt> provides asynchronous message delivery into the bus. This means that incoming remote * requests do not block, and processing of the request continues even after the incoming network conversation has * ended. * </p> * This dispatcher implementation can be used with the {@link org.jboss.errai.bus.server.servlet.DefaultBlockingServlet} * as this pertains to incoming--as opposed to outgoing--message handling. Note: some appservers or servlet environments * may restrict thread creation within the container, in which case this implementation cannot be used. * * @author Mike Brock */ @Singleton public class AsyncDispatcher implements RequestDispatcher { private WorkerFactory workerFactory; private ErraiService service; /** * Constructs the <tt>AsyncDispatcher</tt> with the specified service. The injection makes it possible to obtain * a reference to the <tt>ErraiService</tt> * * @param service the service where the bus is located */ @Inject public AsyncDispatcher(final ErraiService service) { this.service = service; this.workerFactory = new WorkerFactory(service); service.addShutdownHook(new Runnable() { @Override public void run() { workerFactory.stopPool(); } }); } /** * Sends the message globally. If the <tt>PriorityProcessing</tt> routing flag is set, then the message is sent * globally on the bus. If not, the message is sent globally through the <tt>workerFactory</tt> * * @param message a message to dispatch globally */ public void dispatchGlobal(final Message message) throws InterruptedException { if (message.hasPart(MessageParts.PriorityProcessing)) { try { service.getBus().sendGlobal(message); } catch (Throwable t) { if (message.getErrorCallback() != null) { if (!message.getErrorCallback().error(message, t)) { return; } } else { t.printStackTrace(); } } } else { workerFactory.deliverGlobal(message); } } /** * @param message a message to dispatch */ public void dispatch(Message message) throws InterruptedException { workerFactory.deliver(message); } }