What is the correct way to wait for user input using ASP.NET Core? - asp.net-core

What would be the correct approach to implement waiting for user input triggered by server?
Let's assume following scenario:
User sends a request ->
during the execution of this request additional data OR simple confirmation is required ->
the current execution is paused, token is generated with timeout, along with content to send to client ->
on client side a pop-up appears ->
user completes required task, data is sent to server along with the token, that resumes the previous task execution with additional data provided by user.
I already implemented this using a delegate callback in new thread that awaits this token, but I don't think that's the correct approach, is there any other way to do this?
Also, I am aware that it's usually split into two actions, one for the request and other for the confirmation request, but that's impossible to do due to the system being very dynamic and most of serverside actions workflows are defined in data layer.

Task solved (thanks #Tseng) using a stateful object stored on server, whenever data is missing, already present data is stored, token is sent back to client, along with token a requried data keys, UI desscriptors to generate form, etc.
Request is then called again, new data is added to this stored object and the task is attempted again, either finishing successfully or prompting for more data.
Timed disposal is implemented, disposal when job is finished + storage limit per session is in place to prevent malicious overloading.
Thanks again

Related

Retry client request after external condition is met

I want to retry a KTor client request after an external condition is met (such as showing a UI to re-request authorization from the user) when they receive a certain HTTP status code.
HttpRequestRetry is time based and not a great fit for suspending a request while the user executes the external action.
The Auth plugin does not have a concept of needing to redo an authorization due to expiration time has been reached.
Looking into how the Auth and HttpRequestRetry work, they both access an internal function
takeFromWithExecutionContext to make the sub-request and tie them back to the original coroutine scope.
Is there another way to make a custom retry system that does not rely on internal methods?

App client authentication (login) and CQRS

I'm interested in practical scenarios of authentication/login in web application when CQRS pattern is used to build the system.
Say we using HTTP services for commands/queries. And authentication with JWT (or any other authentication token)
We send command LogInUser with credentials (HTTP request).
Server command handler checks credentials, writes events in the store (if using Event Sourcing).
What then? What should we return as the result of the command? Just ok result with authToken? Then client should query the state in the read service? In this case we just make the whole process longer. And this concern actually refers not only to authentication scenarios but also other scenarios when we send a command and expect to get the result of it execution as soon as possible.
I just would like to hear from people who implemented such things. Want to understand possible practical data/requests flows for authentication using CQRS.
Since you are using CQRS, you have decided to separate writing to the application from reading from the application.
To write to the application, you use commands.
To read from the application, you either wait for events, or you query the read model.
This diagram shows the relation between the different options:
(The diagram is taken from the documentation of wolkenkit, a CQRS and event-sourcing framework for JavaScript and Node.js.)
So, when you send your LogInUser command, the command itself does not return anything (of course, when using HTTP there must be a response, but it should just be a 200 OK, so that you can verify that the server received the command and will care about it sooner or later).
Now the server process the login, verifies the sent credentials, and so on, and generates an appropriate UserLoggedIn event. This event gets stored in the event store, and is then sent to the read model.
The read model does two things with this event:
It simply forwards it to the client.
It updates any denormalized tables you may have that are interested in this event, so you can query them later.
So your client has two options:
It can wait for the event after having sent the command. Once the event is being received, the client has the JWT.
It can query the read model, until a given record was updated.
As you need to make sure that only the sender of the command is able to receive the JWT, option 1 is actually the only viable way. You can make sure that an event gets only delivered to the client that sent the appropriate command, but you can't have a table that contains all JWTs where people can only read their JWTs before being authenticated. With the read model, you have a chicken-and-egg problem here.
So, to cut a long story short: The client should wait for the appropriate event, and the event contains the JWT. That's it.

In what scenarios is recommended a reliable session?

In few words, if I am not wrong, a session is used when I want to ensure that the packages are sent in order, and to be able to use sessions is needed a reliable connection.
But my doubt what kind of applications need that? In my case is a simple application in which a client request to a service data from a database, the service get the data from the database and send to the client the results. Also the client can requeset to add, modify or delete data from database. In this case, should I need a reliable connection and sessions or not?
Thanks.
Session presumes that for some period of time you want to retain some data. Such a period of time, as far as session is concerned, refers to client's lifecycle that is when client opens up proxy, both service along with session are created, when client closes proxy service and session terminate their actions. There is exception when closing proxy does not actually perform it right away and this occures when you invoke one-way-operation. Service will keep working as long as operation performs its action despite the fact that it previously received an order to get rid of instance.
Based on provided information I assume the best choice would be PerCall. You do not store any data between calls and every single call can be perceived separately. Additionaly, leverage of ConcurrencyMode set to multiple so as to allow services being created simultaneously.
Personally, I find session useful in MSMQ, whenever I want to specific number of messages be wrapped into single queue-message. If error occures, regardless of whether which message is in charge of it, the whole queue-message is rolled back.

WCF Service- Sending back object to calling App

My WCF service(hosted as Windows Service), has some 'SendEmail' methods, which sends out emails after doing some processing.
Now, I have got another requirement where client wants to preview emails before they are being sent out, so my WCF service needs to return whole email object to calling web app.
If client is happy with emails object, they can simply click 'Send out' which will then again call WCF service to send the emails.
Because at times it can take a bit longer for emails object processingy, I do not want calling application to wait until emails object is ready.
Can anyone please guide what changes I need to make to my WCF service (which currently has all one way operation)?
Also, please guide me whether I need to go for Asynch operation or message queuing or may be a duplex contract?
Thank you!
Based on your description I think you will have to:
Change current operation from sending email to storing email (probably in database).
Add additional operation for retrieving prepared emails for current user
Add additional method to confirm sending one or more emails and removing them from storage.
The process will be:
User will trigger some http request which will result in calling your WCF service for processing (first operation)
WCF service will initiate some processing (asynchronously or firt operation will be one-way so that client doesn't have to wait).
Processing will save email somehow
Depend on duration of processing you can either use AJAX to poll WebApp which will in turn poll WCF service for prepared emails or you will create separate page which will user have to access to see prepared emails. Both methods are using second operation.
User will check prepared email(s) and trigger http request which will result in calling third operation to send those emails.
You have multiple options:
Use Ladislav's approach. Only to add that service returns a token and then client uses the token to poll until a time out or a successful response. Also server keeps these temp emails for a while and after a timeout purges them.
Use duplex communication so that server also gets a way to callback the client and does so when it has finished processing. But don't do this - and here is my view why not.
Use an Asynchronous approach. You can find nice info here.

NServiceBus, NHibernate, and GuidComb()

Disclaimer: This is a follow-on question from my other question about NServiceBus which was answered very thoroughly.
My current question is this: If a website is built to be 'dumb' like the article referred to, above, suggests then how does the following scenario work?
A user registers on a website by filling out a form with relevant details. When the user clicks the 'submit' button on the form the web application takes the form data and creates a message which it sends to the application tier using NServiceBus and Bus.Send(). The application tier goes about the business of creating the new user and publishing the event that the user has been created (Bus.Publish()) so that other processes can do their thing (email the new user, add the user to a search index, etc, etc).
Now, since the web application in this scenario relies entirely on the application tier for the creation of the new user instance, how does it get to know about the user's id? If I didn't use NServiceBus in this scenario but, rather, let the website issue an in-process call to a DAL I'd use NHibernate's GuidComb() strategy to create the identifier for the new user before persisting the new row in the database. If the message handler application which receives the command to create a new user (in the current scenario) uses the same strategy, how is the userId communicated back to the web application?
Do I have to apply a different strategy for managing identifiers in a scenario such as this?
You're free to come up with an ID to use as a correlation identifier by putting it in your message in the web application, allowing it to be carried around whatevery processes are initiated by the message.
That way, you can correlate the request with other events around your system, if only they remember to supply the correlation ID.
But it sounds like you want your user ID to be fed back to you in the same web request - that cannot easily be done with an asynchronous backend, which is what messaging gives you.
Wouldn't it be acceptable to send an email to the user when the user has been created, containing a (secret) link to some kind of gateway, that resumes the user's session?
Wouldn't the UI be able to listen to the bus for the "user created" event? And then you could correlate either by having the event include some kind of event ID linking back to the "user creation requested" event or against some other well known data in the event (like the user name). Though you probably also have to listen to multiple events, such as "user creation failure" event.
This is not unlike normal AJAX processing in a web browser. Technically, you don't block on the out of band call back to the web server. You invoke the call and you asynchronously wait for a callback.