On Tue, Nov 25, 2025 at 8:20 AM Chris Colman <[email protected]>
wrote:

> On 25/11/2025 4:28 pm, Martin Grigorov wrote:
> > If you talk about Ajax requests you could solve that by using
> > AjaxChannel.ACTIVE setting. The JavaScript logic will ignore any Ajax
> > request in the same channel if there is an active request at the moment.
>
> I wish I knew about this earlier! Is this something that can be set via
> a Wicket application config attribute or does it need to be done in raw
> JavaScript somewhere?
>

See AjaxRequestAttributes (
https://github.com/apache/wicket/blob/999d205d3f27310bd657d20e86bd59ab1ed4d7f6/wicket-core/src/main/java/org/apache/wicket/ajax/attributes/AjaxRequestAttributes.java#L117
)
You could override it per Ajax behavior/component (#updateAjaxAttributes())
or globally with AjaxRequestTarget.IListener (see
https://github.com/apache/wicket/blob/999d205d3f27310bd657d20e86bd59ab1ed4d7f6/wicket-core/src/main/java/org/apache/wicket/ajax/AbstractDefaultAjaxBehavior.java#L149
and
https://github.com/apache/wicket/blob/999d205d3f27310bd657d20e86bd59ab1ed4d7f6/wicket-core-tests/src/test/java/org/apache/wicket/ajax/GlobalUpdateAjaxAttributesTest.java#L42
)



>
> To prevent multiple click processing we ended up creating an extension
> to AjaxLink (could do the same with AjaxButton) called DebouncedAjaxLink
> to act like a bit like a electronic debouncing circuit does to prevent
> multiple inadvertent clicks being processed.
>
> Basically, instead of your derived class providing an onClick() impl you
> provide a performAction() impl instead and while multiple clicks can
> result in onClick() being invoked multiple times, performAction() will
> only be called once.
>
> public abstract
> class DebouncedAjaxLink<T> extends AjaxLink<T>
> {
>
> private int semaphore = 0;
>
> ...
>
> /**
>   * Will only be called from onClick() if all other previous calls to
> performAction have
>   * completed.
>   */
> public abstract void performAction(AjaxRequestTarget ajaxRequestTarget);
>
>
> /**
>   * Handle any clicks, preventing multiple calls to performAction()
>   */
> public void onClick(AjaxRequestTarget ajaxRequestTarget)
> {
>      synchronized (this)
>      {
>
>          if (semaphore > 0)
>          {
>              // Preventing firing of action while last request is still
> being processed
>              logger.warn("semaphore > 0");
>              return; // ignore click
>          }
>
>          semaphore++; // will be cleared after performAction invocation
> returns
>      }
>
>      try
>      {
>          performAction(ajaxRequestTarget);
>      }
>      finally
>      {
>          synchronized (this)
>          {
>          semaphore--;
>          }
>      }
> }
>
> }
>
> Yes, it uses synchronized blocks but not really an issue in a web app
> that most companies develop.
>
> Sync blocks are bad in a tight loop that has to do 10 million iterations
> per second but are not really an issue for this UI/Web scenario unless
> your app is running at Google scale - good problem to have ;)
>
>
> > I guess you could reuse it for non-Ajax links by intercepting their click
> > event.
> >
> > On Mon, 24 Nov 2025 at 10:55, Martijn Dashorst <
> [email protected]>
> > wrote:
> >
> >> In our application sometimes a user clicks double when a request takes
> >> long, or they are using windows clicking behavior (double click).
> >>
> >> This is unfortunate as the server is processing the request twice, and
> one
> >> of them is discarded in the bit-void due to no browser listening for the
> >> response...
> >>
> >> I know it is a bad idea to link request threads together, but... with
> the
> >> current pagelock mechanism we already do that in a sort of way.
> >>
> >> What if we were to keep a map of in progress (non-multipart for now)
> >> requests parameters and the threads that are processing them, and when a
> >> duplicate comes in for the same session, we subscribe to a future of the
> >> original response, and respond with that to the browser?
> >>
> >> Martijn
> >>
>

Reply via email to