Re: WebSocket concurrent modification

2020-05-28 Thread fanfy
Updated the sample application  websocket-test.tar
  

--
Sent from: http://apache-wicket.1842946.n4.nabble.com/Users-forum-f1842947.html

-
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org



Re: WebSocket concurrent modification

2020-05-28 Thread fanfy
Hello,I finally found the problem ... It seems that I didn't understood very
well how to use WebSocketMessageBroadcaster from wicket-spring-boot. The
proper way to broadcast websocket messages from an ajax call is to use
org.apache.wicket.protocol.ws.api.WebSocketPushBroadcaster with an
additional configuration of the Executor that must broadcast the messages
using a separate threadFor example, if using springframework (with wicket
application as a bean) you must configure the executor:
java.util.concurrent.Executor executor =
Executors.newSingleThreadExecutor();
WebSocketSettings.Holder.get(webApplication).setWebSocketPushMessageExecutor(new
Executor() {@Override   
public void run(Runnable command) { 
executor.execute(command);  }   });
To broadcast messages from business code you can use spring events
(published from your business code) To broadcast from ajax handlers inject
this bean and call broadcastToAll(event) directly. 
/** *  * @author Elvis Ciocoiu * */@Componentpublic class
TaskEventWebSocketBroadcaster { private WebSocketPushBroadcaster
broadcaster;@Autowired private Application application; 
@PostConstruct
public void init() {WebSocketSettings webSocketSettings =
WebSocketSettings.Holder.get(application);  
IWebSocketConnectionRegistry
webSocketConnectionRegistry = webSocketSettings.getConnectionRegistry();
broadcaster = new WebSocketPushBroadcaster(webSocketConnectionRegistry);
}   
@EventListener  public void onTaskEvent(TaskEvent taskEvent) {  
broadcastToAll(taskEvent);  }   public void 
broadcastToAll(TaskEvent
taskEvent) {broadcaster.broadcastAll(application, new
TaskEventWebSocketPushMessage(taskEvent));  }   /**  *  
 * @author Elvis
Ciocoiu  *   */ public static class TaskEventWebSocketPushMessage 
implements
IWebSocketPushMessage { private static final long serialVersionUID = 
1L;
private TaskEvent taskEvent;public
TaskEventWebSocketPushMessage(TaskEvent taskEvent) {
this.taskEvent =
taskEvent;  }   public TaskEvent 
getTaskEvent() {   return taskEvent;   }   
}}
I think these distinct scenarios (broadcast from ajaxhandler and from
business thread) should be documented a little more in user guide. Sorry to
waste your time.Thank you

--
Sent from: http://apache-wicket.1842946.n4.nabble.com/Users-forum-f1842947.html

-
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org



WebSocket concurrent modification

2020-05-20 Thread fanfy
Hello,

Maybe you can help me with a problem related to wicket 8.8.0 with websocket.
Sometimes (usually when there are many ajax request in a short time
interval) I encounter ConcurrentModificationException. The page store saving
is synchronous. I created a sample project (attached  websocket-test.tar
 
)

mvn package
java -jar target/websocket-test-0.0.1-SNAPSHOT.jar
http://localhost:8080/)

If clicking multiple times on 'New message' AjaxLink soon the exception is
thrown. Internally I have a timer that creates messages on 50 milliseconds
frequency (may be changed in src/main/resources/application.properties -
fanfy.messsage-generator-frequency=50)  

Below is a sample stacktrace.

Thank you.

2020-05-20 10:43:55.241 ERROR 246999 --- [nio-8080-exec-1]
o.apache.wicket.DefaultExceptionMapper   : Unexpected error occurred

java.util.ConcurrentModificationException: null
at
org.apache.commons.collections4.map.AbstractLinkedMap$LinkIterator.nextEntry(AbstractLinkedMap.java:574)
~[commons-collections4-4.4.jar!/:4.4]
at
org.apache.commons.collections4.map.AbstractLinkedMap$ValuesIterator.next(AbstractLinkedMap.java:506)
~[commons-collections4-4.4.jar!/:4.4]
at
org.apache.wicket.MarkupContainer$1MarkupChildIterator.refreshInternalIteratorIfNeeded(MarkupContainer.java:624)
~[wicket-core-8.8.0.jar!/:8.8.0]
at
org.apache.wicket.MarkupContainer$1MarkupChildIterator.hasNext(MarkupContainer.java:573)
~[wicket-core-8.8.0.jar!/:8.8.0]
at org.apache.wicket.util.visit.Visits.visitChildren(Visits.java:134)
~[wicket-util-8.8.0.jar!/:8.8.0]
at org.apache.wicket.util.visit.Visits.visitChildren(Visits.java:162)
~[wicket-util-8.8.0.jar!/:8.8.0]
at org.apache.wicket.util.visit.Visits.visitChildren(Visits.java:162)
~[wicket-util-8.8.0.jar!/:8.8.0]
at org.apache.wicket.util.visit.Visits.visitChildren(Visits.java:162)
~[wicket-util-8.8.0.jar!/:8.8.0]
at org.apache.wicket.util.visit.Visits.visitChildren(Visits.java:123)
~[wicket-util-8.8.0.jar!/:8.8.0]
at org.apache.wicket.util.visit.Visits.visitChildren(Visits.java:192)
~[wicket-util-8.8.0.jar!/:8.8.0]
at
org.apache.wicket.MarkupContainer.visitChildren(MarkupContainer.java:976)
~[wicket-core-8.8.0.jar!/:8.8.0]
at
org.apache.wicket.ComponentEventSender.breadth(ComponentEventSender.java:160)
~[wicket-core-8.8.0.jar!/:8.8.0]
at
org.apache.wicket.ComponentEventSender.send(ComponentEventSender.java:68)
~[wicket-core-8.8.0.jar!/:8.8.0]
at org.apache.wicket.Component.send(Component.java:4413)
~[wicket-core-8.8.0.jar!/:8.8.0]
at
org.apache.wicket.ajax.AjaxRequestHandler.respond(AjaxRequestHandler.java:349)
~[wicket-core-8.8.0.jar!/:8.8.0]
at
org.apache.wicket.request.cycle.RequestCycle$HandlerExecutor.respond(RequestCycle.java:914)
~[wicket-core-8.8.0.jar!/:8.8.0]
at
org.apache.wicket.request.RequestHandlerExecutor.execute(RequestHandlerExecutor.java:65)
~[wicket-request-8.8.0.jar!/:8.8.0]
at
org.apache.wicket.request.cycle.RequestCycle.execute(RequestCycle.java:282)
[wicket-core-8.8.0.jar!/:8.8.0]
at
org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:253)
[wicket-core-8.8.0.jar!/:8.8.0]
at
org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:221)
[wicket-core-8.8.0.jar!/:8.8.0]
at
org.apache.wicket.protocol.ws.AbstractUpgradeFilter.processRequestCycle(AbstractUpgradeFilter.java:70)
[wicket-native-websocket-core-8.8.0.jar!/:8.8.0]
at
org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFilter.java:206)
[wicket-core-8.8.0.jar!/:8.8.0]
at
org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:299)
[wicket-core-8.8.0.jar!/:8.8.0]
at
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
[tomcat-embed-core-9.0.35.jar!/:9.0.35]
at
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
[tomcat-embed-core-9.0.35.jar!/:9.0.35]
at
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
[tomcat-embed-core-9.0.35.jar!/:9.0.35]
at
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
[tomcat-embed-core-9.0.35.jar!/:9.0.35]
at
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
[tomcat-embed-core-9.0.35.jar!/:9.0.35]
at
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
[tomcat-embed-core-9.0.35.jar!/:9.0.35]
at
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
[tomcat-embed-core-9.0.35.jar!/:9.0.35]
at
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
[tomcat-embed-core-9.0.35.jar!/:9.0.35]
at