Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   * Copyright 2010 JBoss Inc
   * 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
  * 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.drools.guvnor.server;
 import java.util.*;
This is the backchannel to send "push" messages to the browser. Here be dragons. Would like to convert this to using actors one day. TODO: convert to executor architecture. Only one instance needed.
 public class Backchannel {
     private final List<CountDownLatchwaiting = Collections.synchronizedList(new ArrayList<CountDownLatch>());
     private final Map<StringList<PushResponse>> mailbox = Collections.synchronizedMap(new HashMap<StringList<PushResponse>>());
     private final Timer timer = new Timer(true);
     private Credentials credentials;
     private HttpSessionStatus sessionStatus;
     public void postConstruct() {
         //using a timer to make sure awaiting subs are flushed every now and then, otherwise web threads could be consumed.
         .schedule(new TimerTask() {
                     public void run() {

Called on the original thread.

never null, an empty list if there's nothing to tell
     public List<PushResponsesubscribe() {
         if (.isActive()) {
             try {
                 return await(.getUsername());
             } catch (InterruptedException e) {
                 return new ArrayList<PushResponse>();
         } else {
             return new ArrayList<PushResponse>();
     public List<PushResponseawait(String userNamethrows InterruptedException {
         List<PushResponsemessages = fetchMessageForUser(userName);
         if (messages != null && messages.size() > 0) {
             return messages;
         } else {
             CountDownLatch latch = new CountDownLatch(1);
             // Now PAUSE here for a while.... and release after 3hours if nothing done
             latch.await(3 * 60 * 60,
             // In the meantime... response has been set, and then it will be unlatched, and message sent back...
             return fetchMessageForUser(userName);

Fetch the list of messages waiting, if there are some, replace it with an empty list.
     private List<PushResponsefetchMessageForUser(String userName) {
        return .put(userName,
                new ArrayList<PushResponse>());

Push out a message to the specific client
    public synchronized void push(String userName,
                                  PushResponse message) {
        //need to queue this up in the users mailbox, and then wake it all up
        List<PushResponseresp = .get(userName);
        if (resp == null) {
            resp = new ArrayList<PushResponse>();
        } else {

Push out a message to all currently connected clients
    public synchronized void publish(PushResponse message) {
        for (Map.Entry<StringList<PushResponse>> e : .entrySet()) {
            if (e.getValue() == null) {
                e.setValue(new ArrayList<PushResponse>());
    private void unlatchAllWaiting() {
        synchronized () {
            Iterator<CountDownLatchit = .iterator();
            while (it.hasNext()) {
                CountDownLatch l =;
New to GrepCode? Check out our FAQ X