2015-08-05 10 views
0

У меня есть следующая ситуация: я пытаюсь реализовать длинный сервлет серфера в java (будет работать на причале). Для этого я использую AsyncContext и TimerTask.«Locker is not reentrant» в асинхронном длинном опросе серфинга java причал

У меня есть класс сеанса, который имеет этот метод:

public boolean setLongPollingContext(final AsyncContext ctx) { 
    if (ctx==null) 
     return false; 
    this.longPollContext = ctx; 

    this.alertHandler = new AlertNotificationHandler() { 
     @Override 
     public void onNewAlert() { 

     } 

     @Override 
     public void onTimeout() { 
      System.out.println("*** timeout ***"); 
      HttpServletResponse response = (HttpServletResponse)ctx.getResponse(); 
      response.setStatus(408); // timeout 
      try { 
       response.getWriter().write("Timeout"); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      ctx.complete(); 
     } 
    }; 

    this.alertHandler.setTimeout(this.longPollingInterval); // 31 seconds 
    return true; 
} 

(SetTimeout только начинается поток таймера, который называет «onTimeout» в 31 секунд)

Я звоню это так:

final AsyncContext asyncCtx = request.startAsync(request, response); 
session.setLongPollingContext(asyncCtx); 

Он работал нормально до 30 секунд (что, по-видимому, является тайм-аутом по умолчанию ssl/http в причале 9.3).

более 30 секунд я получаю вопрос тайма-аута, связанные с которой я неподвижным, установив эту строку в моем умиротворить/start.d/ssl.ini файл:

## Connector idle timeout in milliseconds 
jetty.ssl.idleTimeout=330000 

Я не получаю проблемы тайма-аута больше , но теперь у меня есть что-то еще более странное:

Exception in thread "Timer-0" 
java.lang.IllegalStateException: Locker is not reentrant 
at org.eclipse.jetty.util.thread.Locker.concLock(Locker.java:85) 
at org.eclipse.jetty.util.thread.Locker.lock(Locker.java:61) 
at org.eclipse.jetty.server.HttpChannelState.getStatusString(HttpChannelState.java:166) 
at org.eclipse.jetty.server.HttpChannelState.complete(HttpChannelState.java:481) 
at org.eclipse.jetty.server.AsyncContextState.complete(AsyncContextState.java:92) 
at com.theobroma.paranoidandroid.session.ProxyClientSession$1.onTimeout(ProxyClientSession.java:60) 
at com.theobroma.paranoidandroid.session.AlertNotificationHandler$1.run(AlertNotificationHandler.java:25) 
at java.util.TimerThread.mainLoop(Unknown Source) 
at java.util.TimerThread.run(Unknown Source) 

Google не предоставил мне никаких соответствующих векторов.

Есть ли что-то еще, что мне нужно настроить в причале?

Есть ли способ, чтобы установить эти параметры конфигурации без изменения конфигурационных файлов (из кода, как и с аннотациями или установить некоторые статические переменные?)

Спасибо!

+1

Почему вы используете тайм-аут самостоятельно и не используете встроенные тайм-ауты в AsyncContext? –

+0

Ну, в основном потому, что я хотел быть в состоянии делать вещи в тайм-аут. Я не знаю, возможно ли это с помощью встроенных модулей, но это было очень полезно, потому что, по-видимому, встроенный таймер был тем, который истек, и аннулировал мой выходной поток ответа. Поэтому установка тайм-аута на longPollingInterval + что-то исправило проблему, спасибо! –

+0

Если вы хотите сделать это в ответ, чтобы я мог принять его, и другие люди могут увидеть его более легко :) –

ответ

0

Joakim Erdfelt дал мне несколько полезных подсказок, которые я скомпилирую в ответ, поскольку он исправляет проблему для меня.

Итак, кажется, что проблема в том, что AsyncContext имеет свой собственный тайм-аут, который по умолчанию составляет 30 секунд на моей установке (я предполагаю, что это не имеет ничего общего с 30 секундами причала, это было просто вводящее в заблуждение совпадение)

Как только контекст асинхронизации истекает, потоки запроса и ответа закрываются и не могут быть снова открыты, следовательно, ошибка.

Решение было увеличить время ожидания контекста асинхронном:

ctx.setTimeout(this.longPollingInterval+1000); 

я добавил дополнительное время к тому, чтобы убедиться, что это не тайм-аут до моего тайм-аута потока.

Существует способ назначить слушателю событие таймаута для асинхронного контекста. Я буду изучать это и использовать его вместо своего собственного таймаута. Я довольно новичок в Java, поэтому я не знал об этом :)

 Смежные вопросы

  • Нет связанных вопросов^_^