Is there any way to run PreRequestFilters that are async? I can see that there's been a number of async request filters added, but no async version of PreRequestFilters.
It would be nice to have an async version of PreRequestFilters so that we can run async tasks before any Request Filter Attributes. The only way I can see of doing that at the moment is to use GlobalRequestFiltersAsync and make sure all Request Filter Attributes have a Priority >= 0.
There isn't an async version of PreRequestFilters but you could use a custom RequestFilter Async Attribute with a -Priortity, e.g:
public class MyAsyncAttribute : RequestFilterAsyncAttribute
{
public MyAsyncAttribute()
{
// Priority -101, before any built-in request filter attributes
Priority = (int)RequestFilterPriority.Authenticate - 1;
}
public override Task ExecuteAsync(IRequest req, IResponse res, object requestDto)
{
//...
}
}
Related
I'm bit new to NodeJs & NestJs. I always wondered what's the difference between using async as the method return type inside a controller vs executing async operation inside a regular method ? How does NodeJs handles the request in both these cases if there is huge traffic on this API (eg. 40K req/min). Will it be blocking in the 2nd example and non blocking in the 1st or would it work in a similar way?
For Eg:
#Controller('cats')
export class CatsController {
constructor(private catsService: CatsService) {}
#Post()
async sample() {
return "1234";
}
}
vs
#Controller('cats')
export class CatsController {
constructor(private catsService: CatsService) {}
#Post()
function sample() {
return await methodX();
}
async function methodX(){
return "1234"
}
Please ignore what the content in sample() & methodX() does its only for example.
First, marking a method as async enables you to use the await keyword inside of it.
For example in the second sample you provided, you need to mark the method sample as async to await methodX:
#Post()
async function sample() {
// Now `await` can be used inside `sample`
return await methodX();
}
So to answer your questions
what's the difference between using async as the method return type inside a controller vs executing async operation inside a regular method ?
There is none. In both cases, the method of the controller will need to marked as async. Performing what the route is supposed to perform in the body of the method or extracting it in another async method is just a matter of code organisation.
Will it be blocking in the 2nd example and non blocking in the 1st or would it work in a similar way?
Both examples would work in a similar way.
Second, marking a mehthod as async doesn't actually make it async if there is no real async operation performed in its body like a request to another service or a setTimeout. It means that the following samples
// Sample 1
#Post()
async sample() {
return "1234";
}
// Sample 2
#Post()
function async sample() {
return await methodX();
}
async function methodX(){
return "1234"
}
Are both equivalent to the synchronous method
#Post()
syncSample() {
return "1234";
}
Finally, as stated by #Micael Levi, return await is syntactically correct but should be avoided. Considering this sample:
#Post()
function async sample() {
return await methodX();
}
async function methodX(){
throw new Error('something failed')
}
Because the method sample return await methodX, sample won't appear in the stack trace which makes debugging more difficult.
We would prefer this sample:
#Post()
function async sample() {
const result = await methodX();
return result;
}
async function methodX(){
throw new Error('something failed')
}
So no matter what I've read, even once I do it right, I can't seem to get the the hang of async and await. For example I have this in my startup.
startup.js
await CommandBus.GetInstance();
await Consumers.GetInstance();
Debugging jumps to the end of the get instance for CommandBus (starting up a channel for rabbitmq) and start Consumers.GetInstance() which fails since channel is null.
CommandBus.js
export default class CommandBus {
private static instance: CommandBus;
private channel: any;
private conn: Connection;
private constructor() {
this.init();
}
private async init() {
//Create connection to rabbitmq
console.log("Starting connection to rabbit.");
this.conn = await connect({
protocol: "amqp",
hostname: settings.RabbitIP,
port: settings.RabbitPort,
username: settings.RabbitUser,
password: settings.RabbitPwd,
vhost: "/"
});
console.log("connecting channel.");
this.channel = await this.conn.createChannel();
}
static async GetInstance(): Promise<CommandBus> {
if (!CommandBus.instance) {
CommandBus.instance = new CommandBus();
}
return CommandBus.instance;
}
public async AddConsumer(queue: Queues) {
await this.channel.assertQueue(queue);
this.channel.consume(queue, msg => {
this.Handle(msg, queue);
});
}
}
Consumers.js
export default class Consumers {
private cb: CommandBus;
private static instance: Consumers;
private constructor() {
this.init();
}
private async init() {
this.cb = await CommandBus.GetInstance();
await cb.AddConsumer(Queues.AuthResponseLogin);
}
static async GetInstance(): Promise<Consumers> {
if (!Consumers.instance) {
Consumers.instance = new Consumers();
}
return Consumers.instance;
}
}
Sorry I realize this is in Typescript, but I imagine that doesn't matter. The issue occurs specifically when calling cb.AddConsumer which can be found CommandBus.js. It tries to assert a queue against a channel that doesn't exist yet. What I don't understand, is looking at it. I feel like I've covered all the await areas, so that it should wait on channel creation. The CommandBus is always fetched as a singleton. I don't if this poses issues, but again it is one of those areas that I cover with awaits as well. Any help is great thanks everyone.
You can't really use asynchronous operations in a constructor. The problem is that the constructor needs to return your instance so it can't also return a promise that will tell the caller when it's done.
So, in your Consumers class, await new Consumers(); is not doing anything useful. new Consumers() returns a new instance of a Consumers object so when you await that it doesn't actually wait for anything. Remember that await does something useful with you await a promise. It doesn't have any special powers to await your constructor being done.
The usual way around this is to create a factory function (which can be a static in your design) that returns a promise that resolves to the new object.
Since you're also trying to make a singleton, you would cache the promise the first time you create it and always return the promise to the caller so the caller would always use .then() to get the finished instance. The first time they call it, they'd get a promise that was still pending, but later they'd get a promise that was already fulfilled. In either case, they just use .then() to get the instance.
I don't know TypeScript well enough to suggest to you the actual code for doing this, but hopefully you get the idea from the description. Turn GetInstance() into a factory function that returns a promise (that you cache) and have that promise resolve to your instance.
Something like this:
static async GetInstance(): Promise<Consumers> {
if (!Consumers.promise) {
let obj = new Consumers();
Consumers.promise = obj.init().then(() => obj);
}
return Consumers.promise;
}
Then, the caller would do:
Consumers.getInstance().then(consumer => {
// code here to use the singleton consumer object
}).catch(err => {
console.log("failed to get consumer object");
});
You will have to do the same thing in any class that has async operations involved in initializing the object (like CommandBus) too and each .init() call needs to call the base class super.init().then(...) so base class can do its thing to get properly initialized too and the promise your .init() is linked to the base class too. Or, if you're creating other objects that themselves have factory functions, then your .init() needs to call those factory functions and link their promises together so the .init() promise that is returned is linked to the other factory function promises too (so the promise your .init() returns will not resolve until all dependent objects are all done).
I have an mvc 5 controller that makes use of some async data access code. I've written a simple test using nUnit. The test doesn't complete, it just spins until i cancel it. afaik i've set up the test correctly; it's awaiting the controller action is marked as async and returns a task. Am i missing something? Interestingly, the test works when i mock out the dependencies using moq, but if i go for an integration test with the actual dependencies in place, it just spins forever.
the a simplified test:
[Test]
public async Task Get_WhenProductHasData_ReturnsView()
{
// Arrange
...
// Act
PartialViewResult actualResult = await _controller.Widget(_productId1) as PartialViewResult;
// Assert
Assert.That(actualResult, Is.Not.Null);
...
}
And here's the simplified controller
public async Task<ActionResult> Widget(string productId)
{
ProductStats stats = await _statsService.GetProductStatsAsync(productId);
return PartialView(stats);
}
Try this instead:
[Test]
public async Task Get_WhenProductHasData_ReturnsView()
{
// Arrange
...
// Act
var result = await _controller.Widget(_productId1);
// Assert
Assert.That(result as PartialViewResult, Is.Not.Null);
}
Note that the "Act" line is simply awaiting and the result is then cast as a PartialViewResult on the Assert.That line, if it was null or not a PartialViewResult type it would return null. Either way you get what you're looking for.
I have a simple middleware:
public class MiddlewareInterceptor
{
RequestDelegate _next;
public MiddlewareInterceptor(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext ctx)
{
ctx.Response.WriteAsync("<h2>From SomeMiddleWare</h2>");
return _next(ctx);
}
}
And in my Startup.cs Configure method, I hook it like so:
app.UseMiddleware<MiddlewareInterceptor>();
The above builds and the app seems to run fine, but my breakpoint in the interceptor Invoke method never hits. And likewise, there is never any output. I tried that with Debug.WriteLine also.
Now, I also tried this method:
public class MiddlewareInterceptor : OwinMiddleware
{
public MiddlewareInterceptor(OwinMiddleware next) : base(next){}
public override async Task Invoke(IOwinContext context)
{
Debug.WriteLine(context.Request.Uri.ToString());
await Next.Invoke(context);
}
}
And in my Startup.cs Configure method, I hook it like so:
app.Use(next => new MiddlewareInterceptor(next).Invoke);
Unfortunately, the base OwinMiddleware constructor is looking for the next OwinMiddleware as a parameter, unlike ye olde RequestDelegate. So my app.Use instantiation of my MiddlewareInterceptor fails because next is of type RequestDelegate.
Lastly, I have tried an inline function directly in the Configure method which also never hits the breakpoint:
app.Use(async (ctx, next) =>
{
System.Diagnostics.Debug.WriteLine("Hello");
await next();
});
So as it stands, it seems like I cant make a basic middleware interceptor using OWIN. What am I missing?
What is the order of the aforementioned middleware in the pipeline? Make sure this executes before anything that will terminate the request part of the pipeline; eg. UseMvc();
Specifically when doing MonoDroid uses of threads all the documentation I can find recommends calling RunOnUiThread() to call the callback. There is a similar function that can be used on MonoTouch however both of them require a GUI (Activity or whatever its counter part is on IOS). What I would like is to be able to start a thread, pass in a callback and call that callback on the thread that started the thread. For example
ThreadPool.QueueUserWorkItem(state =>
{
//Do Stuff
execute_callback_magically_on_main_thread(() => callback(response));
});
Any ideas? To be clear I would prefer this to not need a handle to the Activity etc.
What if you do something like this? (assuming they have the same signature) I haven't messed with RunOnUiThread, so I don't know it's signature.
public delegate void InvokeOnUIMethod(Action action);
public void CallingMethod()
{
//iOS
MyMethod(InvokeOnMainThread, () => { /* Your callback functionality */ });
//Android
MyMethod(RunOnUiThread, () => { /* Your callback functionality */ });
}
public void MyMethod(InvokeOnUIMethod execute_callback_magically_on_main_thread, Action callback)
{
System.Threading.ThreadPool.QueueUserWorkItem(state =>
{
//Do Stuff
execute_callback_magically_on_main_thread(() => callback(response));
});
}
I hope this helps.
Using the Alpha builds (Hopefully soon to be available as stable) you can use the new Async await idiom.
here is an overview on MSDN:
http://msdn.microsoft.com/en-gb/library/vstudio/hh191443.aspx
and here is a great video series on Channel9:
http://channel9.msdn.com/Series/Three-Essential-Tips-for-Async/Tip-1-Async-void-is-for-top-level-event-handlers-only
I found a solution that works and does not appear to be dependent on either platform.
Task<string> t = new Task<string>(() =>
{
//Do Stuff
return "my results";
});
t.ContinueWith(task =>{
if(callback != null)
callback(task.Result);
}, TaskScheduler.FromCurrentSynchronizationContext());
t.Start();
The important part is the TaskScheduler.FromCurrentSynchronizationContext() which tells the "ContinueWith" to execute on the original thread.