WildFly 12 Wicket 7.10 - Why does only the first thread have access to Application? - singleton

Each request attempts to create new instances of Singletons, which fail because they use Application.get() which fails with error:
There is no application attached to current thread default
Same code works in WildFly 8.2 and Wicket 6.20. So two problems:
Each request handler thread acts as though it is running in its own JVM not sharing static fields with other threads.
Each request handler thread after the initial one is being created without and application attached to it.
Minimal example:
package com.example.web;
public class SiteConstants
{
public static final String CONTEXT_PATH = WebApp.get().getServletcontext().getContextPath() + "/";
}
Home page uses
SiteConstants.CONTEXT_PATH
First request for the home page works. Second call loads in another thread and fails on
WebApp.get().getServletcontext().getContextPath() + "/";
because WebApp.get() throws
org.apache.wicket.WicketRuntimeException: There is no application attached to current thread default task-1

Related

Minimal API Logging Missing Event ID

I have a Minimal API web application and have enabled logging. Logging is working however the Event ID's don't show up in Azure logs.
I have a call to AddAzureWebAppDiagnostics() at the beginning of the application.
builder.Logging.AddAzureWebAppDiagnostics();
Within the various endpoints I call LogInformation and pass in an event id. It logs the event but the eventID is never shown in the logs. This call
app.Logger.LogInformation(Events.UserGet, "Getting UserInformation: {UserGUID}", UserGUID);
produces the following in the App Logs within Azure.
2023-02-13 00:19:51.662 +00:00 [Information] Admin: Getting UserInformation: c8e7f5ba-445c-42f7-9e61-8869c8f1ace0
Am I missing something? Ideally the event would include the corresponding Event ID. I've included an excerpt of the Event ID's class below.
public class Events
{
//...
public const int UserGet = 1601;
//...
}
Thanks

ASP.NET Core using IOptionsMonitor<T> throwing exception in a different thread

In my web application, I have a custom configuration file which I want to monitor for changes and update the application settings immediately. So I am using IOptionsMonitor<T> to get this done. It works well.
As per the documentation the method that gets called when configuration file changed is wired up like below.
var data = _serviceProvider.GetRequiredService<IOptionsMonitor<MySettings>>();
data.OnChange(OnReaderSettingOptionsChanged);
Within the OnReaderSettingOptionsChanged() method, I do some validations and there is a need to throw an exception on an edge case so that application shouldn't continue.
The problem is when I throw the exception, I expect to see a error on browser (dev mode with details or normal error otherwise). But it's not showing because according to this exception gets fired in another thread.
So, is there another way for me to get this across to browser?

HttpRequest not aborted (cancelled) on browser abort in ASP.NET Core MVC

I wrote the following MVC Controller to test cancellation functionality:
class MyController : Controller
{
[HttpGet("api/CancelTest")]
async Task<IActionResult> Get()
{
await Task.Delay(1000);
CancellationToken token = HttpContext.RequestAborted;
bool cancelled = token.IsCancellationRequested;
logger.LogDebug(cancelled.ToString());
return Ok();
}
}
Say, I want to cancel the request, so the value 'true' is logged in the controller action above. This is possible server-side if the server implements the IHttpRequestLifetimeFeature. Luckily Kestrel does, and this can be accomplished the following way:
var feature = (IHttpRequestLifetimeFeature) HttpContext.Features[typeof(IHttpRequestLifetimeFeature)];
feature.Abort();
The problem however is that I want to cancel the request on the client side. For example, in the browser. In pre-core versions of ASP.NET MVC/WebApi the cancellation token would automatically be cancelled if the browser aborted a request. Example: refresh the page a couple of times in Chrome. In the Network tab of the chrome dev tools you can now see the previous (unfinished) request be cancelled.
The thing is: in ASP.NET Core running on Kestrel, I can only see the following entry in the log:
Microsoft.AspNetCore.Server.Kestrel.Internal.Networking.UvException:
Error -4081 ECANCELED operation canceled
So the abort request from the browser DOES arrive and is handled by the Kestrel webserver. It does however not affect the RequestAborted property of the HttpContext in the controller, because the value 'false' is still logged by the method.
Question:
Is there a way to abort/cancel my controller's method, so that the HttpContext.RequestAborted property will be marked as cancelled?
Perhaps I can make something that would subscribe to Kestrel's operation cancelled trigger and call the IHttpRequestLifetimeFeature.Abort() method?
Update:
I did some further testing and it seems the HttpRequest IS in fact aborted, but there seems to be some kind of delay before the cancellation actually takes place. The delay is not time-factored, and seems to come straight from libuv (the library where the Kestrel webserver is build on top of). I posted more info on https://github.com/aspnet/KestrelHttpServer/issues/1103
More updates:
Issue has been moved to another one, because the previous one contained multiple problems. https://github.com/aspnet/KestrelHttpServer/issues/1139
Turns out that that simply using HttpContext.RequestAborted is indeed the right way, but due to a bug in Kestrel (the order in which FIN/RST packages were handled), the request was not aborted on a browser abort.
The bug should finally be fixed in Kestrel 2.0.
See the updates in my question for more information.

Async ActionResult implementation is blocking

Okay,
Here I have an MVC 4 application and I am trying to create an Asynchronous ActionResult with in that.
Objective : User has a download PDF Icon on the WebPage, and downloading takes much of time. So while server is busy generating the PDF, the user shall be able to perform some actions in webpage.
(clicking "download PDF" link is sending and ajax request to the server, server is fetching some data and is pushing back the PDF)
What is happening is while I call the ajax to download the PDF it starts the process, but blocks every request until and unless it returns back to the browser. That is simple blocking request.
What I have tried so far.
1) Used AsyncController as a base class of controller.
2) Made the ActionResult to an async Task DownloadPDF(), and here I wrapped the whole code/logic to generate PDF into a wrapper. This wrapper is eventually an awaitable thing inside DownloadPDF()
something like this.
public async Task<ActionResult> DownloadPDF()
{
string filepath = await CreatePDF();
//create a file stream and return it as ActionResult
}
private async Task<string> CreatePDF()
{
// creates the PDF and returns the path as a string
return filePath;
}
YES, the Operations are session based.
Am I missing some thing some where?
Objective : User has a download PDF Icon on the WebPage, and downloading takes much of time. So while server is busy generating the PDF, the user shall be able to perform some actions in webpage.
async will not do this. As I describe in my MSDN article, async yields to the ASP.NET runtime, not the client browser. This only makes sense; async can't change the HTTP protocol (as I mention on my blog).
However, though async cannot do this, AJAX can.
What is happening is while I call the ajax to download the PDF it starts the process, but blocks every request until and unless it returns back to the browser. That is simple blocking request.
AFAIK, the request code you posted is completely asynchronous. It is returning the thread to the ASP.NET thread pool while the PDF is being created. However, there are several other aspects to concurrent requests. In particular, one common hangup is that by default the ASP.NET session state cannot be shared between multiple requests.
1) Used AsyncController as a base class of controller.
This is unnecessary. Modern controllers inspect the return type of their actions to determine whether they are asynchronous.
YES, the Operations are session based.
It sounds to me like the ASP.NET session is what is limiting your requests. See Concurrent Requests and Session State. You'll have to either turn it off or make it read-only in order to have concurrent requests within the same session.

Capture GlassFish log file into SQL/JPA data base

I need a little help getting started. I have a new JSF-2 web application that I intend to deploy under GlassFish 3.1 (or higher). Normally the server stores all its log files as text in one of its private directories, which also includes the logging I do with ether System.println( .. ) or something like java.util.logging.Logger.getLogger( ... )
What I want to do is instead of those logging entries going to the text file, capture them and file them into my SQL data base. I can then add table columns for timestamp and key values so it can be easily searched as part of the admin web page in the application, rather than having to go to the admin console for it. It would be possible also to expose some of that data to users.
Can this be done and how?
Follow up question: could this be done in a way that would be portable to Tomcat or another container?
You will need to write custom log handler. Custom log handler is a class that extends java.util.logging.Handler:
package test.stackoverflow;
import java.util.logging.Handler;
..
public class AlanHandler extends Handler {
..
#Override
public void publish(LogRecord record) {
//CODE THAT STORES LOG RECORD INTO THE DATABASE
}
}
Additionally, you will have to slightly change logging.properties file:
handlers=java.util.logging.ConsoleHandler, test.stackoverflow.AlanHandler
Deploy JAR of AlanHandler on Glassfish (as a library), restart the server and that should do it.