Bi-directional asynchronous communication in layers

Asked

Viewed 230 times

6

I have system in Asp.Net MVC (.Net 4.5) divided in layers:

inserir a descrição da imagem aqui

That said, let’s get to the problem...

I’m trying to create a screen to send emails asynchronously (3 emails at the same time, for example), but there will be a button to cancel submissions, which forces me to inform the customer in real time, which emails have already been sent.

See the flow below:

inserir a descrição da imagem aqui

inserir a descrição da imagem aqui

At this point, if the user clicks the cancel button, the emails in process must be aborted and the last one does not start.

Respecting the layered architecture, I would like to address all the business rules for sending emails on the proper layer for this. But I haven’t been able to find a solution where I can send a list of objects (emails) from View Layer to the Business Layer, creating there an asynchronous process that send back to the View Layer the result of sending each email (one by one asynchronously), and which at any time allows the interruption of the whole process.

That would be the flow:

All emails are sent to the business layer: inserir a descrição da imagem aqui

The business layer starts an asynchronous process to send the emails, and as it completes sending each email, it responds to the display layer the result:

inserir a descrição da imagem aqui

At any time, the customer can cancel sending, so the view layer sends a cancellation request for all tasks that are still running:

inserir a descrição da imagem aqui

1. It is possible to send data in the opposite direction (from Business Layer for to View Layer) from a single call?

2. I must create some kind of Thread to control the sending of each email?

3. It is possible to interrupt a task that is running in a lower layer?

  • 1

    I do not know if I vote for the question, because it is a little vague, perhaps broad or unclear, but excellent way to present.

  • Thanks @bigown , it’s really looking a little too wide, because it’s not a specific problem as proposed here in stackoverflow. I’m having a hard time synthesizing it to fit in, maybe it was something for the community softwareengineering, but as we have nothing of the kind in Portuguese yet, I had to call for help here, rsrsrs...

  • The problem is not of focus, and we do not know well what you want. Here is Sept.

  • I made an issue trying to improve a little, what do you think now?

  • the best option would be to resume tasks, and first layer that made the request, pass a token cancelation to the others, until the layer that creates the sending threads, so it is possible to cancel the threads from the first layer

3 answers

0

You can solve the problem with 3 calls always originating from the Front End.

  1. Call your controller by passing mailing list and any other information that is required for sending. If the return of your backend is OK/Accepted (STATUS 200/202), you return from the backend a unique identifier for this sending process (PID).

  2. To unsubscribe create a new end point in the backend that the Front end at the click of the button can call and cancel based on the PID.

  3. Once the upload has started and front-end Javascript has PID. You create a Polling procedure (sequential queries) by checking the backend from time to time to check current status (sending %, sent, cancelled) of the items (emails) of your order. In the content of this return put what is necessary to show on the front end if successful or canceled.

Another possible implementation that can be performed in this context is the use of Websockets, Webrtc or Signalr. Basically in these implementations the frontend keeps an HTTP connection open with the backend receiving and sending events to/from the server to update its sending status in real time.

0

Use a queue system, like Rabbitmq, or Kafka, or any of your own.

Business Layer will publish in the queue all the information necessary to send the emails. Each message in the queue is an email that will be sent, so in your example would be 7 published messages. It will also enter in the database an entity for each email with the status pending.

The queue will have N consumers connected to it (N being the amount you want) sending the emails and updating the status of their respective entities as the result of sending (success or error).

If the user clicks the cancel button, clear the queue. How this cleaning will happen depends on the technology you chose. One option, for example, is to activate a consumer who fetches all pending messages and updates their status to canceled.

The screen, in turn, makes a pooling in this database to query the status of messages in real time. If the pooling strategy seems too rudimentary to you, you can use a websocket.

(Tip: This is a great scenario for a Nosql database, like the AWS Dynamodb or the Azure Cosmosdb.)

0

I would do ViewLayer work with javascript (AJAX) calling async your BLL (businessLayer) so it would be quite easy to stop the execution of the process.

The Behavior of $Ajax is already async by nature. So I could call a $Ajax => Start and then a Stop. Inside Ajax. I would be receiving the data and displaying to the client which already sent.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.